James Stroud wrote: > sam wrote: > >> this does what i want, though i don't like the inner while loop having >> to be there [snip] > 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 >
Of course I see room for improvement in my own code. Personally, I like to remove "values" from logic because it results, naturally, in more versatile functions. So I would redo my get_pct() method to take the list as a parameter: def get_pct(pct_list): while True: 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() Now, its a much more versatile piece of code, e.g.: pct_list = ['cash', 'bond', 'blue', 'tech', 'dev'] pct_dict = get_pct(pct_list) And now all of your code boils down to these latter 2 statments. You might want to think about what you would do to pass the total criterion is as a parameter rather than hard coding it. Hint: def get_pct(pct_list, criterion, slack): [you fill in here] if (total < (criterion - slack)) or {total > (criterion + slack)): [you fill in more here] Now, no values are hard-coded but are passed in as parameters. Perhaps "msg" in get_one_pct_value() could be treated the same way to produce yet more flexibility and hence re-usability. 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