2

How do you make sure that the user only entered a float that has two decimal places. The number cannot be 4 or 4.999 it has to be 4.00 or 4.99 otherwise an error should appear.

while looping:
    try:
        number = float(input("Number: "))

        string_number = (str(number)).split(".")
        check_length = len(string_number)
        if check_length != 2:
            print ("ERROR!")
            looping = True
        else:
            looping = False

     except ValueError:
         looping = True
novice coder
  • 33
  • 2
  • 6

4 Answers4

1

You are currently only checking that there is currently just one decimal point.

number.split(".") will return a list. If number is 4.323, it will return ['4', '323'].

What you really want to check in your if clause is that the length of the second element is 2.

if len(string_number[1]) != 2:
Hamatti
  • 1,210
  • 10
  • 11
1

Check the second part of the number.

while True:
    try:
        number = input('Number:')
        integral, fractional = number.split('.')
        number = float(number)
        if len(fractional) == 2:
            break
    except ValueError:
        pass
    print('ERROR!')
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Did not see this before I wrote essentially the same thing. Just add `float(number)` otherwise there won't be a value error (unless there is no `.`) – dawg May 05 '14 at 03:10
  • @dawg, Thank you for the comment. I updated the code to include `float(number)`. BTW, multiple assignment also raises `ValueError` if there's not exactly 2 parts (for example `1`, `1.2.3`, ..) – falsetru May 05 '14 at 03:29
  • You need to move `float()` up above the test of the fractional part test. Then, by definition, there will not be multiple periods. Then the lack of a period in the second test would also cause a `ValueError` Then it is logically complete. – dawg May 05 '14 at 03:45
0
looping = True
while looping:
    number = input("Number: ")
    string_number = number.split(".")
    if len(string_number) != 2:
        print ("ERROR: Needs exactly one decimal point!")
        looping = True
    elif len(string_number[1]) != 2:
        print ("ERROR: Two numbers are required after decimal point!")
        looping = True
    else:
        try:
            number = float(number)
            looping = False
        except ValueError:
            print("ERROR: Number is not valid!")
            looping = True

Making some minor changes eliminates the need for the variable looping. Since our goal is to get a valid number, we can just test for that:

number = None
while not number:
    s = input("Number: ")
    string_number = s.split(".")
    if len(string_number) != 2:
        print ("ERROR: Needs exactly one decimal point!")
        continue
    elif len(string_number[1]) != 2:
        print ("ERROR: Two numbers are required after decimal point!")
        continue
    try:
        number = float(s)
    except ValueError:
        print("ERROR: Number is not valid!")
John1024
  • 109,961
  • 14
  • 137
  • 171
  • Why put the try except after? – novice coder May 05 '14 at 02:39
  • @novicecoder Suppose the user entered `1.50`. If you convert it to float and then convert it to string, the result would be `1.5` which would wrongly fail the 2-decimal requirement. By doing the conversion later, we assure that the input we analyze is the same as the input that the user provided. – John1024 May 05 '14 at 02:41
  • but what if the user enters 4 then it would give an error since there would be no index 1 – novice coder May 05 '14 at 02:47
  • @novicecoder That should be caught on the test for the existence of a decimal point ( `len(string_number) != 2` ) which is run before the test for exactly two decimals ( `len(string_number[1]) != 2` ). – John1024 May 05 '14 at 02:49
  • thanks that makes sense BUT again if I enter 4 it does not ask the user for an input again it simply exits the loop and prints out that there was an error – novice coder May 05 '14 at 03:01
0

I would write this way:

while True:
    try: 
        str_num=input("Number: ")
        num=float(str_num)           # ValueError if cannot be converted
        i, f=str_num.split('.')      # also ValueError if not two parts
        if len(f)==2:
            break                    # we are done!!!
    except ValueError:
        pass

    print('ERROR! ')                 # either cannot be converted or not 2 decimal places

print(num) 
dawg
  • 98,345
  • 23
  • 131
  • 206