error handling in user input: is this natural or just laborious

James Stroud jstroud at mbi.ucla.edu
Fri Oct 6 17:32:08 EDT 2006


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

-- 
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