feba a écrit :
.strip() returns a copy of the string without leading and ending
whitespaces (inlcuding newlines, tabs etc).

Ahh. I had removed it because it didn't seem to do anything, but I've
readded it.

And I understand your dictionary stuff correctly now, I think, and I
worked it in. Currently, I have:


import random

def safeint(prompt="y"):
    while True:
        x = input(prompt)
        try:
            x = int(x)
        except ValueError:
            print("BAD INPUT!")
        else:
            break
    return x

def safestr(prompt="y"):
    while True:
        x = input(prompt)
        try:
            x = str(x)

Doesn't input already return a string ?

        except ValueError:
            print("BAD INPUT!")
        else:
            break
    return x

You could as well replace the 'break' statement by 'return x' - since
returning will obviously break the loop


Now don't you notice kind of a pattern in these two functions ? obviously, the only thing that change is the conversion/validation part. The good news is that Python functions are objects too, so you can pass them as params to another function. The generic version of your above code could be:


def safeinput(prompt, convert):
     while True:
         x = input(prompt)
         try:
             x = convert(x)
         except ValueError, e:
             print("Bad input : %s" % e)
         else:
             return x


then you can use it for int:

i = safeinput("Please enter an integer", int)

or use more complex conversion/validation:

def yesno(s):
   s = s.strip().lower()
   if not s in ("y", "n"):
       raise ValueError("please answer with 'y' or 'n'")
   # we return a boolean
   return s == 'y'

answer = safeinput("really do this ?", yesno)


Last point : if your conversion/validation function needs more arguments than the value to convert - ie : converting to an int and vaidating this int is in a specified range, which require mini and maxi arguments for the range - you can use partial evaluation[1]:

from functools import partial

def int_in_range(x, mini, maxi):
   x = int(x)
   if not mini <= x <= maxi:
       raise ValueError("%s is not in range (%s, %s)" % (x, mini, maxi))
   return x

i = safeinput(
        "Please enter an int between 1 and 99",
        partial(int_in_range, mini=1, maxi=99)
        )


[1] given the function f(x, y): return x + y, the partial evaluation partial(f, x=2) is a function fx(y) that when called returns the result of f(2, y).


(snip)

rewrite it once again using objects instead of dicts ?

I'd need to find out how those work,

Mostly as glorified dicts with associated functions. Your game and players dicts are obvious candidates. Whenever you see a dict with a more or less defined "structure" and a set of functions working on this dict, you have in fact a class waiting to be born.


and I have a list of python stuff
to read piling up anyway... That said, I think for something like
that, something that's not a major flaw, I'd prefer to make something
else, and maybe work on this again later on. There is only so much
guessing numbers one person can take.

Indeed. That was just a suggestion, and it would have been pretty interesting IMHO as a basis for a "from Q&D procedural scripting to OO application programing" tutorial.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to