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/ -- http://mail.python.org/mailman/listinfo/python-list