Python Forum
while loops and breaks
Thread Rating:
  • 1 Vote(s) - 2 Average
  • 1
  • 2
  • 3
  • 4
  • 5
while loops and breaks
#1
secret_num = round(3.3312, 2)

while True:
    user_guess = float(input("Guess the secret number: "))
    if user_guess > secret_num:
        print "Too High!"
    elif user_guess < 3.3:
        print "Too low!"
    else:
        print "Great Guess"
    break   

print "you guessed the right number"
This is the result I get not sure where the break goes in order not to get the "you guessed the right number" when its wrong.

Guess the secret number: 3.2
Too low!
you guessed the right number
Reply
#2
The final print statement is not under any condition. It will always be printed because it is outside the while loop code block.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#3
secret_num = round(3.3312, 2)

while True:
    user_guess = float(input("Guess the secret number: "))
    if user_guess > secret_num:
        print "Too High!" 
       
    elif user_guess < 3.3:
        print "Too low!"
        
    else:
        print "Correct"
    break
    print "you guessed the right number"
This is the test results: not sure what i'm doing wrong
Test Too Low Failure
Expected result:

Too low!
Correct!

Your result:

Too low!

Difference:

Too low!
Correct!
Reply
#4
The break statement is executed unconditionally, no mater if the user input is lower, bigger or equal to the right answer... and the "you guessed the ..." is never reached (code just after a break or return is dead code)
Also, in one of the branches of your if you compare with secret_num but in the other you compare with 3.3, hard-coded.
Reply
#5
You need to indent the break statement so it is at the same indent level as print in the final else. The final print statement should not be indented at all.

This means, when the else condition is met, correct will be printed, the loop will be exited, and you guessed the right number will be printed.
I am trying to help you, really, even if it doesn't always seem that way
Reply
#6
secret_num = round(3.3312, 2)

while True:
    user_guess = float(input("Guess the secret number: "))
    if user_guess > secret_num:
        print "Too High!" 
       
    elif user_guess < secret_num:
        print "Too low!"
        
    else:
        print "Correct"
        break
print "you guessed the right number"
It's won't recognize 3.3 as the secret_num
Reply
#7
And you are surprised?

>>> float('3.3')
3.3
>>> round(3.3312,2)
3.33
>>> float('3.3') < round(3.3312,2)
True
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
As alwillia identified that there could be a potential 'floating point' comparison problem by use of round(), there are several alternatives:
a. User defined tolerance (not demonstrated)
b. Rounding to one more digit than required
c. Use of math.isclose() (included with Python as of Python 3.5)
d. Use of 'decimal' package (included with Python)

# Reference: https://python-forum.io/Thread-while-loops-and-breaks
# Reference: https://stackoverflow.com/questions/5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python
# Reference: https://docs.python.org/3/library/math.html
# Reference: https://docs.python.org/3/library/decimal.html

import math
import decimal

def print_results(user_guess, secret_num):
    if user_guess == secret_num:
        print("User guess of {} is equal to the secret number of {}.".format(user_guess, secret_num))
    elif user_guess < secret_num:
        print("User guess of {} is less than the secret number of {}.".format(user_guess, secret_num))
    else:
        print("User guess of {} is greater than the secret number of {}.".format(user_guess, secret_num))
    return

def print_results_using_isclose(user_guess, secret_num):
    if math.isclose(user_guess, secret_num):
        print("User guess of {} is equal (i.e. close enough) to the secret number of {}.".format(user_guess, secret_num))
    elif user_guess < secret_num:
        print("User guess of {} is less than the secret number of {}.".format(user_guess, secret_num))
    else:
        print("User guess of {} is greater than the secret number of {}.".format(user_guess, secret_num))
    return

print("")
print("Example of floating point limitation:  3.3 != 1.1 + 2.2")
secret_num = 1.1 + 2.2
user_guess = 3.3
print_results(user_guess, secret_num)

print("")
print("Example of using 'round' as floating point limitation workaround: 3.3 == round(1.1 + 2.2, 2)")
secret_num = round(1.1 + 2.2, 2)
user_guess = 3.3
print_results(user_guess, secret_num)

print("")
print("Example of using 'math.isclose()' as floating point limitation workaround: math.isclose(3.3, 1.1 + 2.2)")
print("NOTE: 'math.isclose()' was added in Python 3.5.")
secret_num = 1.1 + 2.2
user_guess = 3.3
print_results_using_isclose(user_guess, secret_num)


print("")
print("Example of using 'decimal package' as floating point limitation workaround: Decimal('3.3') == Decimal('1.1') + Decimal('2.2')")
print("NOTE: Use of strings preserves number of digits.")
secret_num = decimal.Decimal('1.1') + decimal.Decimal('2.222')
user_guess = decimal.Decimal('3.3')
print_results(user_guess, secret_num)
Output:
Example of floating point limitation: 3.3 != 1.1 + 2.2 User guess of 3.3 is less than the secret number of 3.3000000000000003. Example of using 'round' as floating point limitation workaround: 3.3 == round(1.1 + 2.2, 2) User guess of 3.3 is equal to the secret number of 3.3. Example of using 'math.isclose()' as floating point limitation workaround: math.isclose(3.3, 1.1 + 2.2) NOTE: 'math.isclose()' was added in Python 3.5. User guess of 3.3 is equal (i.e. close enough) to the secret number of 3.3000000000000003. Example of using 'decimal package' as floating point limitation workaround: Decimal('3.3') == Decimal('1.1') + Decimal('2.2') NOTE: Use of strings preserves number of digits. User guess of 3.3 is equal to the secret number of 3.3.
Lewis
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply
#9
Comparing floating points numbers for equality is -almost- always a bad idea and a source of funny little bugs...
There are many examples like the classical:
>>> a = 1.0 / 3
>>> a
0.3333333333333333
>>> 1 - a == 2*a  # 1 - a = 1 - 1/3 = 2/3 = 2*a
False
This kind of error is still present if we use the decimal module (more oriented to "accounting maths") but is solved if we use the fractions module:
>>> from fractions import Fraction
>>> c = Fraction(1, 3)
>>> 1 - c == 2*c
True
The best option is to define a range where the response is "good enough". there are several ways to do it, depending of what you want.
If the condition is for typical mathematical problem the best is to define a distance:
is_ok = abs(user_guess - secret_num) <= accuracy
This is essentially the same as math.isclose(user_guess, secret_num, rel_tol=accuracy)

In this case if the target solution is 3.3312 with for example an accuracy of 0.005 that will mean that all the values between 3.3312 - 0.005 = 3.3262 and 3.3312 + 0.005 = 3.3362 will be considered as valid.
If we want a more "human like" check where any 3.33xxx... is valid but 3.329999 or 3.34 must be discarded the criteria must be:
def round_down(n, digits):
    f = 10**digits
    return int(n * f) / f
is_ok = 0.0 <= user_guess - round_down(secret_num, 2) < 0.01
In this case where it is also necessary to say if the guess is too small or too big something like:
# For "Human like"
lower = round_down(secret_number, 2)
upper = lower + 0.01
# For math like
# lower = secret_number - 0.005
# upper = secret_number + 0.005
if user_guess < lower:
    print("Too low")
elif user_guess < upper:
    print(f"You are close enough to the answer {user_guess} ~= {secret_number}")
else:
    print("Too high")
Reply
#10
(May-26-2018, 08:29 PM)gruntfutuk Wrote: You need to indent the break statement so it is at the same indent level as print in the final else. The final print statement should not be indented at all.

This means, when the else condition is met, correct will be printed, the loop will be exited, and you guessed the right number will be printed.

secret_num = round(3.3312, 2)
 
while True:
    user_guess = float(input("Guess the secret number: "))
    if user_guess > secret_num:
        print ("Too High!")
    elif user_guess < 3.3:
        print ("Too low!")
    else:
        print ("Great Guess")
        print ("You guessed the right number")
        break   
 
Did you mean like this?
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020