6

I have some code which asks the user to guess the answer to a calculation, and then either tells them they are correct or tries to identify where they went wrong. I have used a while loop in this but sometimes it gets stuck, is there a way to add a counter to the guesses taken, and to break the while loop after 5 incorrect guesses? Here is a section of my code so far:

#define correct answer for A
Ac=L*xm
#ask user to work out A (monthly interest * capital)
while True:
    A= raw_input("What do you think the monthly interest x the amount you are borrowing is? (please use 2 d.p.) £")
    A=float(A)
    #tell user if they are correct or not
    if A==round(Ac,2):
        print("correct")
        break
    elif A==round(L*x,2):
        print("incorrect. You have used the APR rate, whic is an annual rate, you should have used this rate divided by 12 to make it monthly")
        continue
    elif A==round(L/(x*100),2):
        print("incorrect. You have used the interest rate as a whole number when you should have used it as a decimal, and divided it by 12 for the monthly rate")
        continue
    else:
        print("Wrong, it seems you have made an error somewhere, you should have done the loan amount multiplied by the monthly rate")
        continue
Neuron
  • 5,141
  • 5
  • 38
  • 59
Julie
  • 81
  • 1
  • 1
  • 6
  • I rolled back your edit, since most of the answers "build" on it. Removing it makes the whole thread a bit confusing. If you are unhappy with your code, feel free to alter it (and also alter the answer so they still make sense). You can @answer me if you do, then I can help accelerate the edit review process a little – Neuron Aug 11 '22 at 19:00

4 Answers4

7

The standard library's itertools provide an iterator counting up:

import itertools

for i in itertools.count():
    print(i)

You can set the start and step:

# count(10) --> 10 11 12 13 14 ...
# count(2.5, 0.5) --> 2.5 3.0 3.5 ...
Florian
  • 2,562
  • 5
  • 25
  • 35
rassi
  • 375
  • 3
  • 8
6

The Pythonic way is

max_guesses = 5
solution = ... # Some solution
guessed = False
for wrong_guesses in range(1, max_guesses + 1):
    guess = ... # Get Guess
    if guess == round(solution, 2):
        print("correct")
        guessed = True
        break 
    ...
else:
    print(f"You have exceeded the maximum of {max_guesses} guesses") 

This way the loop is executed at most max_guesses times. The else block is only executed if the loop did not end because of a break statement i.e. when there was no correct guess.

Note the max_guesses + 1 because range is an iterator over the interval [low, high) (excluding the upper limit). So to run from 1 to max_guesses we have to +1.

miraculixx
  • 10,034
  • 2
  • 41
  • 60
  • if you let your range run from `1` to `max_guesses+1` you would not need the `guessed` variable, cutting a total of 4 lines. I think that would make your solution more readable (and pythonic), but thats just my opinion. Alternatively, since the `wrong_guesses` is not used, you could just name it `_` and not care about on what value it ends – Neuron Aug 11 '22 at 18:56
  • 1
    Yes, thanks for the comment. I chose this way to avoid the "max_guesses + 1" (which seemed more confusing, overall) and to make the guessed state explicit. I agree that your suggestion would make the code more concise though, and have updated the range so we can get rid of the last if (which was equally confusing, I guess) – miraculixx Aug 12 '22 at 00:26
4

In general it should look like this:

i = 0
while i < max_guesses:
    i+=1
    # here is your code
MaLiN2223
  • 1,290
  • 3
  • 19
  • 40
  • 2
    this is not a good solution for python. Use a `for x in range()` loop instead – Neuron Jul 16 '22 at 09:49
  • @Neuron is it not performant? – Caleb Jul 25 '22 at 01:01
  • 1
    @Neuron I think this is perfectly good solution for python. Please provide more context, because I think this is just your style opinion. – MaLiN2223 Jul 28 '22 at 15:05
  • 1
    @MaLiN2223 "There should be one-- and preferably only one --obvious way to do it." https://peps.python.org/pep-0020/ . For loops are created exactly for this one scenario. to iterate from start (usually 0) to finish with a certain step size (usually 1). for loops do *exactly* that and are the *perfect* tool to solve this problem – Neuron Jul 28 '22 at 15:45
  • You might want to source your claims after the pep quote. Everything you wrote is just an opinion. I doubt any of creators of python said 'For loops are created exactly for this one scenario' – MaLiN2223 Jun 09 '23 at 07:22
2

Just create a variable to store the amount of incorrect guesses and use an if condition to detect when user guessed wrong 5 times, then stop the loop. As shown below:

Ac=L*xm
incorrect_guesses = 0 # variable to store incorrect guesses
# ask user to work out A (monthly interest * capital)
while True:
    if incorrect_guesses == 5:
        break # stop loop
    else: # if not, continue normally
        guess = raw_input("What do you think the monthly interest x the amount you are borrowing is? (please use 2 d.p.) £")
        guess = float(guess)
        # tell user if they are correct or not
        if guess == round(Ac, 2):
            print("correct")
            break
        elif guess == round(L * x, 2):
            print("incorrect. You have used the APR rate, which is an annual rate, you should have used this rate divided by 12 to make it monthly")
            incorrect_guesses += 1
        elif A == round(L / (x * 100), 2):
            print("incorrect. You have used the interest rate as a whole number when you should have used it as a decimal, and divided it by 12 for the monthly rate")
            incorrect_guesses += 1
        else:
            print("Wrong, it seems you have made an error somewhere, you should have done the loan amount multiplied by the monthly rate")
            incorrect_guesses += 1
Neuron
  • 5,141
  • 5
  • 38
  • 59
Taufiq Rahman
  • 5,600
  • 2
  • 36
  • 44