# [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
```