[Tutor] Limit raw_input to hundredth decimal point
Ryan Kirk
ryankirk at me.com
Sat Jul 2 08:51:14 CEST 2011
Thanks all! This helps a lot.
On Jul 1, 2011, at 6:13 AM, Steven D'Aprano wrote:
> Ryan Kirk wrote:
>> Is there a way to limit raw_input to the hundredth decimal point?
>
> No. raw_input is a tool that does one thing: it collects input from the user. It doesn't understand numbers, check for decimal places, check the input for spelling errors, or anything else. It's a hammer, not a combination hammer-screwdriver-wrench-drill-saw-axe :)
>
> One solution is to build a new tool that checks for decimal places:
>
>
> def check(text):
> try:
> x = float(text)
> except ValueError:
> print "please enter a number"
> return None
> y = x*100
> if y - int(y) != 0:
> print "please enter only two decimal places"
> return None
> return x
>
>
> def get_number(prompt):
> answer = None
> while answer is None:
> text = raw_input(prompt)
> answer = check(text)
> return answer
>
>
> At first, this seems to work well:
>
> >>> get_number("Please enter a number with two decimal places: ")
> Please enter a number with two decimal places: 77.25
> 77.25
> >>>
>
> but there's a fundamental problem. The user is entering numbers in decimal (base 10), but Python does calculations in binary (base 2), and something that has two decimal places may not be exact in binary:
>
> >>> get_number("Please enter a number with two decimal places: ")
> Please enter a number with two decimal places: 77.21
> please enter only two decimal places
>
> Huh? 77.21 does have two decimal places. But the closest float to 77.21 is in fact 77.209999999999994. No computer on Earth can store 77.21 *exactly* as a binary float, no matter how hard you try!
>
> So, what to do...? You can:
>
> (1) Give up on forcing the user to only enter two decimal places, and instead use the round() function to round to two places:
>
> >>> round(77.2123456, 2)
> 77.209999999999994
>
> This is still not two decimal places, but it is the closest possible float to 7.21, so you can't do any better.
>
> (2) Or give up on using float, and use the decimal module instead. (However decimals are slower and less convenient than floats.)
>
> >>> from decimal import Decimal
> >>> x = Decimal("77.21")
> >>> x
> Decimal("77.21")
>
>
> If you are working with currency, then you should use decimal, and not floats.
>
>
>
> Good luck!
>
>
>
> --
> Steven
>
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
More information about the Tutor
mailing list