error handling in user input: is this natural or just laborious
James Stroud
jstroud at mbi.ucla.edu
Fri Oct 6 23:41:11 EDT 2006
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/
More information about the Python-list
mailing list