Katt wrote:
Message: 3
Date: Thu, 15 Oct 2009 16:50:57 +0100
From: Rich Lovely <[email protected]>
To: Wayne Werner <[email protected]>
Cc: "[email protected]" <[email protected]>
Subject: Re: [Tutor] Most pythonic input validation
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=windows-1252
2009/10/15 Wayne Werner <[email protected]>:
Hi,
I'm writing a text based menu and want to validate the user input. I'm
giving the options as integers, and I want to make sure the user
enters a
proper value.
Here's what I've got so far:?http://pastebin.com/m1fdd5863
I'm most interested in this segment:
?? ?while True:
?? ? ? ?choice = raw_input(prompt)
?? ? ? ?if valid_choice(choice, 0, len(options)-1):
?? ? ? ? ? ?break
?? ?return choice
Is that the most pythonic way of validating? Is there a better way?
As an aside, in the valid_choice function I know I could do:
if not choice in range(min, max)
but I figured a comparison would probably be the better choice,
correct?
Thanks,
Wayne
--
To be considered stupid and to be told so is more painful than being
called
gluttonous, mendacious, violent, lascivious, lazy, cowardly: every
weakness,
every vice, has found its defenders, its rhetoric, its ennoblement and
exaltation, but stupidity hasn?t. - Primo Levi
_______________________________________________
Tutor maillist ?- [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
The most pythonic way would be to use a try except block:
while True:
choice = raw_input(prompt)
try:
options[int(choice)]
except (KeyError, IndexError, TypeError):
print "Invalid input, try again."
continue
return choice
Also, did you want to convert choice to an int at some point? You
appear to be comparing it to a number in valid_choice(), but it will
be passed out of the method as a str.
Hence I've added a conversion to int, and I'm catching KeyError (for
dicts), IndexError (for lists), and TypeError, for when int(choice)
fails.
This is a principle called "It's Easier to Ask Forgiveness than
Permission" (EAFP), which is one of the pythonic principles.
Hope that helps.
--
Rich "Roadie Rich" Lovely
As I am a new programmer I am specifically trying to pay attention to
when you guys discuss making thing more python like.
I am a bit confused though on a couple things in this code. Probably
since I have not dealt with it as of yet.
The first is the while statement. I have made a successful menu
selection but my while statement is:
while prompt != 0:
0 of course meaning exit. Does "while True:" mean the same?
Second is the input statement. Could you not just put choice =
int(raw_input(prompt)) instead of using two different statements? Or
is it that my example will return as string?
The third is the "try" statement. How is this different from the
"for" loop or "if" loop?
The fourth is except (KeyError, IndexError, TypeError): why do you
check for three different types of errors?
Thanks in advance,
Katt
_______________________________________________
Tutor maillist - [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
1) `while True` will result in an infinite loop unless you test for your
prompt condition inside the loop and if it's true then use a break
statement to exit the loop, eg.
while True:
if prompt == 0:
break
2) If you were to put the `choice = int(raw_input(prompt))` into one
line, remember to put it in a try/except block as you could be casting
an alphanumeric into an integer. The reasoning behind putting it on two
lines is to increase readability and so that you have a variable
`choice` which contains the actual input in case you wanted to use it
for something if it causes an exception, eg.
choice = raw_input(prompt)
try:
options[int(choice)]
except (KeyError, IndexError, TypeError):
print '%s is not a valid choice' % choice
3) If you start a `try` block it is because you want to handle any
errors occurring from the statements / expressions in the block itself.
It is not a loop, it just runs through once completely or until it
receives the first exception and in that case then moves onto the
`except` section
4) The three exceptions lists are for various errors that might have
occurred.
The KeyError is if `options` is a dictionary and the key (contained in
choice) is not in your dictionary, although for a dictionary I would
rather write `if int(choice) in options:`.
The IndexError is if `options` is a list and your choice was supposed to
be the index that you want to seek to, eg.
options = ['Exit', 'Start New Game', 'High Scores']
choice = raw_input(prompt) # lets say you use the number 3 here
try
options[int(choice)]
except IndexError:
print 'Selection out of range, please use a number between 0 and %s'
% (len(options)-1)
Counting starts from zero so there are 0, 1, 2 as valid choices in this
example.
The TypeError, should be a ValueError, is for catching conversion
errors. If you supply a choice of 'a' and try and convert that to an
integer it will throw a ValueError letting you know that what you are
trying to convert is not an integer. TypeError will catch a NoneType
conversion which you won't be able to type in on the console.
Hope that helps.
--
Kind Regards,
Christian Witts
_______________________________________________
Tutor maillist - [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor