sam wrote: > this does what i want, though i don't like the inner while loop having > to be there > > > def get_pct(): > while True: > pct_list=[['cash', 0], ['bond', 0], ['blue', 0], ['tech', 0], > ['dev', > 0]] > total=0 > for i in range(len(pct_list)): > while True: > pct_list[i][1]=raw_input('Please enter the > percentage value for %s: > ' %pct_list[i][0]) > if pct_list[i][1].isdigit() == False: > print "You've messed up, do it again..." > else: > total+=int(pct_list[i][1]) > break > if total == 100: > return pct_list > break > else: > print "You've messed up, do it again..." > > > gosh, a lot of work to get some input. i must be missing something, > though this is a lot better than what i had before... >
I think youwill like your code better if you take nested loops and put them in functions In this following block, I have made changes to your revised code to show better technique on the small scale (removing tabs so it would format correctly without wrapping and breaking lines): def get_pct(): while True: # for things like your pct_list, begin with dictionaries in mind # the pairs you had were unnecessary clutter pct_list = ['cash', 'bond', 'blue', 'tech', 'dev'] # clean up code by moving long message strings outside of loops # this will help you see the logic of your code later msg = 'Please enter the percentage value for %s: ' # Hmm--running totals, big PITA total=0 # here is the dictionary we will be constructing pct_dict = {} # loop over lists and not over list indices # usually watch when you want to write "range(len(some_list))" for a_pct in pct_list: # 3rd level nested loop: think function while True: # see the python style guide for where to put spaces # around such things as equals signs pct_dict[a_pct] = raw_input(msg % a_pct) # doesn't seem to hit at the heart of what you want, but # I'll keep it for pedagogy (I would try to coerce to float # and catch # also, use not instead of "== False" # e.g: if not pct_list[a_pct].isdigit() # better yet, put the positive case in the "if" statement try: # maybe even better would be to total later so you # don't have to keep track of a running total # also, coercing to int here anyway, so just make it # the test with try:except total += int(pct_list[a_pct]) break except ValueError, e: print "You've messed up, do it again..." # the pct_list may add to 100 as floats, but int rounding # might kill the total and make the test fail # perhaps add as floats and test for a small range around # 100 that allows for float arithmetic error if total == 100: return pct_list else: print "You've messed up, do it again..." That's as few changes I could make to it. Let's see it without the comments: def get_pct(): while True: pct_list = ['cash', 'bond', 'blue', 'tech', 'dev'] msg = 'Please enter the percentage value for %s: ' total=0 pct_dict = {} for a_pct in pct_list: while True: pct_dict[a_pct] = raw_input(msg % a_pct) try: total += int(pct_list[a_pct]) break except ValueError, e: print "You've messed up, do it again..." if total == 100: return pct_dict else: print "You've messed up, do it again..." A little cleaner. Now, lets tighten it up a bit more, and put nested loops into functions. Im getting rid of keeping track of the running total, that will clean a lot. I'm also going to be a little more mathematically saavy. def get_pct(): while True: pct_list = ['cash', 'bond', 'blue', 'tech', 'dev'] pct_dict = get_pct_dict(pct_list) total = sum(pct_dict.values()) if (total < 99.999) or (total > 100.001): print "You've messed up, do it again" else: return pct_dict() def get_pct_dict(pct_list): pct_dict = {} for a_pct in pct_list: pct_dict[a_pct] = get_one_pct_value(a_pct) return pct_dict() def get_one_pct_value(a_pct): msg = 'Please enter the percentage value for %s: ' while True: try: return float(msg % a_pct) except ValueError: print "You messed up, try again." Now, all testing is done at the point where it is needed. There are no running totals that could cause accounting errors, your final data structure is an easy to use dict, unecessary tests have been eliminated, loops have been de-nested visually and logically, and, most importantly, the indentation level is kept manageable. I think you will be able to see how this latter code evolved from yours. I used to program just like you and it has taken me a few years to develop these little rules for tightening my code. James -- 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