error handling in user input: is this natural or just laborious
James Stroud
jstroud at mbi.ucla.edu
Fri Oct 6 18:00:53 EDT 2006
James Stroud wrote:
> sam wrote:
>
>> hi all,
>>
>> i'm starting to put together a program to simulate the performance of
>> an investment portfolio in a monte carlo manner doing x thousand
>> iterations and extracting data from the results.
>>
>> i'm still in the early stages, and am trying to code something simple
>> and interactive to get the percentages of the portfolio in the five
>> different investment categories. i thought i'd get in with the error
>> handling early so if someone types in something wrong (like a word), or
>> the numbers don't add up to 100%, the error would be caught immediately
>> and the user sent back to the start of the loop. granting that there
>> may be better ways of doing this, if i decide that i do want to do it
>> like this (i.e. a single error requires all data to be re-entered, not
>> unreasonable for only five items), is this a good way of doing it or a
>> confusing way of doing it from the perspective of readability and
>> maintenance:
>>
>> while True:
>>
>> cash, bond, blue, tech, dev = 0,0,0,0,0
>> check=False
>>
>> try:
>> cash=input('Please enter a cash percentage for the portfolio: ')
>> except NameError:
>> print 'That is not a number. Please start again and remember
>> to enter
>> integers.'
>> else:
>> try:
>> bond=input('Please enter a bond portfolio for the
>> portfolio: ')
>>
>> except NameError:
>> print 'That is not a number. Please start again and
>> remember to
>> enter integers.'
>> else:
>> try:
>> blue=input('Please enter a blue-chip percentage for
>> the portfolio:
>> ')
>> except NameError:
>> print 'That is not a number. Please start again and
>> remember to
>> enter integers.'
>> else:
>> try:
>> tech=input('Please enter a tech stocks percentage
>> for the
>> portfolio: ')
>> except NameError:
>> print 'That is not a number. Please start again
>> and remember to
>> enter integers.'
>> else:
>> try:
>> dev=input('Please enter a developing countries
>> index for the
>> portfolio: ')
>> check=True
>> except NameError:
>> print 'That is not a number. Please start
>> again and remember to
>> enter integers.'
>>
>> if cash+bond+blue+tech+dev==100:
>> break
>> if cash+bond+blue+tech+dev!=100 and check!= False:
>> print 'Those numbers do not sum to 100. Please start again.'
>>
>>
>>
>> i know it's a bit verbose, but it was the nested try clauses i was
>> really wondering about. is the code immediate legible to experienced
>> python users? or does it look like gibberish at first?
>>
>> just hoped for some fresh eyes on it.
>>
>> thanks,
>>
>> sam
>>
>> PS making check=True just saves the code from printing 'those numbers
>> don't sum to 100' if they haven't all been entered, which looks kind of
>> silly.
>>
>
> It looks pretty rough. I think tabs are a very bad idea. Patently. Tabs
> should be reserved for tables, for which tabs were named. If they were
> meant to be used for indenting, they would have been named "indenters".
>
> Try blocks in my opinion are a good idea but they need to be done
> correctly. You should also consider thinking more in terms of procedural
> programming than linear.
>
> Also, the best way would be by gui. See this book for the best resource
> (IMHO) for python gui programming:
>
> http://www.manning.com/grayson/
>
> I think the following is much better technique and is more fun than
> laborious to code:
>
>
> def get_pcts(prompts):
> prompts = ['gross product', 'repleat divisional', 'sales quota']
> pcts = [get_pct(prompt) for prompt in prompts]
> sum_pcts = sum(pcts)
> if (sum_pcts > 100.0001) or (sum_pcts < 99.999):
> raise ValueError, "Values didn't add to 100."
> return pcts
>
> def get_pct(pct_type):
> pct = raw_input('Input percent of %s:' % pct_type)
> return float(pct)
>
> def get_values():
> prompts = ['gross product', 'net outsource', 'sales quota']
> while True:
> try:
> pcts = get_pcts(prompts)
> return dict(zip(prompts, pcts))
> except ValueError, e:
> print e
> print 'Try again dude.'
>
> """
> Here's a test
> >>> print get_values()
> Input percent of gross product:21
> Input percent of repleat divisional:22
> Input percent of sales quota:57
> {'sales quota': 57.0, 'gross product': 21.0, 'net outsource': 22.0}
> """
>
> James
>
Oops, I forgot to remove a line in the final code:
def get_pcts(prompts):
pcts = [get_pct(prompt) for prompt in prompts]
sum_pcts = sum(pcts)
if (sum_pcts > 100.0001) or (sum_pcts < 99.999):
raise ValueError, "Values didn't add to 100."
return pcts
def get_pct(pct_type):
pct = raw_input('Input percent of %s:' % pct_type)
return float(pct)
def get_values():
prompts = ['gross product', 'net outsource', 'sales quota']
while True:
try:
pcts = get_pcts(prompts)
return dict(zip(prompts, pcts))
except ValueError, e:
print e
print 'Try again dude.'
"""
Testing:
>>> print get_values()
Input percent of gross product:22
Input percent of net outsource:21
Input percent of sales quota:57
{'sales quota': 57.0, 'gross product': 22.0, 'net outsource': 21.0}
>>> print get_values()
Input percent of gross product:15.1
Input percent of net outsource:88.2
Input percent of sales quota:19.8
Values didn't add to 100.
Try again dude.
Input percent of gross product:bob
invalid literal for float(): bob
Try again dude.
"""
--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095
http://www.jamesstroud.com/
More information about the Python-list
mailing list