[Tutor] Dividing a float derived from a string

Steven D'Aprano steve at pearwood.info
Fri Nov 21 06:08:00 CET 2014


My response is interleaved with yours, below.

On Thu, Nov 20, 2014 at 09:20:27PM +0000, Stephanie Morrow wrote:
> Hi there,
> 
> I have been posed with the following challenge:
> 
> "Create a script that will ask for a number. Check if their input is a
> legitimate number. If it is, multiply it by 12 and print out the result."

The challenge doesn't say what you should do if the input is not a 
number. In your code below, you print False, which is reasonable, but 
just to be different I'm going to print something else.


> I was able to do this with the following code:
> 
> input = raw_input("Insert a number: ")
> if input.isdigit():
>     print int(input) * 12
> else:
>     print False

This technique is sometimes called "Look Before You Leap" -- first you 
look to see whether the input looks like a number, and if it does, you 
convert the string.

But there's another technique, sometimes called "Easier to Ask 
Forgiveness than Permission" -- first you try converting the string, and 
if it fails, you say sorry.

Here is an attempt using EAFP:

input = raw_input("Enter a number: ")
try:
    x = float(input)
    print 12*x
except ValueError:
    print "That doesn't look like a number to me."


> *However*, a colleague of mine pointed out that a decimal will return as
> False.  As such, we have tried numerous methods to allow it to divide by a
> decimal, all of which have failed.  Do you have any suggestions?

What makes a valid decimal?

- At most one leading + or - sign.

- At most one decimal point.

- At most one 'e' or 'E' exponent.

- If there is an exponent, it must not have a decimal point 
  itself, and at most one + or - sign immediately after the E.

- There can be spaces in front of the string, or at the
  end of the string, but not in the middle.

- There has to be at least one digit.

- If there is an exponent, there must be at least one
  digit before AND after the exponent.

Have I missed any rules?


E.g. these are valid:

123
123.
+123.4
.5
.5e-7
-1234.567e89

but these are not:

1.2e3.4
123 456
56-78
-.
.e
.e3
123.456.789
1,234,567
1.1f6
abc


That makes it quite hard to check whether a string looks like a valid 
number first. It would be easy to miss some cases which should be 
allowed, or allow some cases which should not be.

Or... we can allow Python to check for us. After all, when you call the 
float() function, Python has to check anyway. So why bother checking 
first? That's doing twice as much work: first you check, then Python 
checks.

Hence the Easier to Ask Forgiveness than Permission approach above.


-- 
Steven


More information about the Tutor mailing list