Python while loop ask more than once for input - python

I've been trying to solve the issue with guessing the number program,
The first number the program has to print Ans which is (Startlow + Starthigh)/2 and then Ans gets updated depends on the input
I can't figure out why my while loop keeps waiting for the input for at least 2 times until it prints the results even if I press l or h (unless I press c) which breaks the loop
Startlow = 0
Starthigh = 100
Ans = (Startlow + Starthigh)/2
print("Please think of a number between 0 and 100!")
while True:
print("Is your secret number " + str(int(Ans)))
if input() == "c":
print("Game over,Your secret number was: "+str(int(Ans)))
break
elif input() == "l":
Startlow = Ans
Ans = (Startlow + Starthigh)/2
elif input() == "h":
Starthigh = Ans
Ans = (Startlow + Starthigh)/2
else:
print("Sorry, I did not understand your input.")
any help appreciated :)

You should be asking for input once in the loop, and then comparing that answer to the items you want.
You are instead requesting a (potentially different) answer at each of your conditionals.
The number of questions asked depends on how many conditionals you fall through.

Just do:
x = input()
if x == "c":
#And so on...

Related

Multiplication guessing game in Python | if wrong guess until it is correct

I am trying to write a program as follows:
Python generates random multiplications (factors are random numbers from 1 to 9) and asks to the users to provide the result
The user can quit the program if they input "q" (stats will be calculated and printed)
If the user provides the wrong answer, they should be able to try again until they give the correct answer
if the user responds with a string (e.g. "dog"), Python should return an error and ask for an integer instead
It seems I was able to perform 1) and 2).
However I am not able to do 3) and 4).
When a user gives the wrong answer, a new random multiplication is generated.
Can please somebody help me out?
Thanks!
import random
counter_attempt = -1
counter_win = 0
counter_loss = 0
while True:
counter_attempt += 1
num_1 = random.randint(1, 9)
num_2 = random.randint(1, 9)
result = str(num_1 * num_2)
guess = input(f"How much is {num_1} * {num_2}?: ")
if guess == "q":
print(f"Thank you for playing, you guessed {counter_win} times, you gave the wrong answer {counter_loss} times, on a total of {counter_attempt} guesses!!!")
break
elif guess == result:
print("Congratulations, you got it!")
counter_win += 1
elif guess != result:
print("Wrong! Please try again...")
counter_loss += 1
Hi my Idea is to put the solving part in a function:
import random
counter_attempt = -1
counter_win = 0
counter_loss = 0
def ask(num1, num2, attempt, loss, win):
result = str(num1 * num2)
guess = input(f"How much is {num1} * {num2}?: ")
if guess == "q":
print(
f"Thank you for playing, you guessed {win} times, you gave the wrong answer {loss} times, on a total of {attempt} guesses!!!")
return attempt, loss, win, True
try:
int(guess)
except ValueError:
print("Please insert int.")
return ask(num1, num2, attempt, loss, win)
if guess == result:
print("Congratulations, you got it!")
win += 1
return attempt, loss, win, False
elif guess != result:
print("Wrong! Please try again...")
loss += 1
attempt += 1
return ask(num1, num2, attempt, loss, win)
while True:
num_1 = random.randint(1, 9)
num_2 = random.randint(1, 9)
counter_attempt, counter_loss, counter_win, escape = ask(num_1, num_2, counter_attempt, counter_loss, counter_win)
if escape:
break
Is that what you asked for?
Note that everything withing your while loop happens every single iteration. Specifically, that includes:
num_1 = random.randint(1, 9)
num_2 = random.randint(1, 9)
So you are, indeed, generating new random numbers every time (and then announcing their generation to the user with guess = input(f"How much is {num_1} * {num_2}?: "), which is also within the loop).
Assuming you only intend to generate one pair of random numbers, and only print the "how much is...?" message once, you should avoid placing those within the loop (barring the actual input call, of course: you do wish to repeat that, presumably, otherwise you would only take input from the user once).
I strongly recommend "mentally running the code": just go line-by-line with your finger and a pen and paper at hand to write down the values of variables, and make sure that you understand what happens to each variable & after every instruction at any given moment; you'll see for yourself why this happens and get a feel for it soon enough.
Once that is done, you can run it with a debugger attached to see that it goes as you had imagined.
(I personally think there's merit in doing it "manually" as I've described in the first few times, just to make sure that you do follow the logic.)
EDIT:
As for point #4:
The usual way to achieve this in Python would be the isdigit method of str:
if not guess.isdigit():
print('Invalid input. Please enter an integer value.')
continue # Skip to next iteration
An alternative method, just to expose you to it, would be with try/except:
try:
int(guess) # Attempt to convert it to an integer.
except ValueError: # If the attempt was unsuccessful...
print('Invalid input. Please enter an integer value.')
continue # Skip to next iteration.
And, of course, you could simply iterate through the string and manually ensure each of its characters is a digit. (This over-complicates this significantly, but I think it is helpful to realise that even if Python didn't support neater methods to achieve this result, you could achieve it "manually".)
The preferred way is isdigit, though, as I've said. An important recommendation would be to get yourself comfortable with employing Google-fu when unsure how to do something in a given language: a search like "Python validate str is integer" is sure to have relevant results.
EDIT 2:
Make sure to check if guess == 'q' first, of course, since that is the one case in which a non-integer is acceptable.
For instance:
if guess == "q":
print(f"Thank you for playing, you guessed {counter_win} times, you gave the wrong answer {counter_loss} times, on a total of {counter_attempt} guesses!!!")
break
elif not guess.isdigit():
print('Invalid input. Please enter an integer value.')
continue # Skip to next iteration
elif guess == result:
...
EDIT 3:
If you wish to use try/except, what you could do is something like this:
if guess == "q":
print(f"Thank you for playing, you guessed {counter_win} times, you gave the wrong answer {counter_loss} times, on a total of {counter_attempt} guesses!!!")
break
try:
int(guess)
except ValueError:
print('Invalid input. Please enter an integer value.')
continue # Skip to next iteration
if guess == result:
...
You are generating a new random number every time the user is wrong, because the
num_1 = random.randint(1, 9)
num_2 = random.randint(1, 9)
result = str(num_1 * num_2)
Is in the while True loop.
Here is the fixed Code:
import random
counter_attempt = 0
counter_win = 0
counter_loss = 0
while True:
num_1 = random.randint(1, 9)
num_2 = random.randint(1, 9)
result = str(num_1 * num_2)
while True:
guess = input(f"How much is {num_1} * {num_2}?: ")
if guess == "q":
print(f"Thank you for playing, you guessed {counter_win} times, you gave the wrong answer {counter_loss} times, on a total of {counter_attempt} guesses!!!")
input()
quit()
elif guess == result:
print("Congratulations, you got it!")
counter_win += 1
break
elif guess != result:
print("Wrong! Please try again...")
counter_loss += 1

Why cant i sum up all of my values (user values) problem with while?

I'm new to the coding world. I have a problem with adding up all of the users' input values, as I don't know how many there will be. Any suggestions?
This is how far I've gotten. Don't mind the foreign language.
import math
while(True):
n=input("PERSONS WEIGHT?")
people=0
answer= input( "Do we continue adding people ? y/n")
if answer == "y" :
continue
elif answer == "n" :
break
else:
print("You typed something wrong , add another value ")
people +=1
limit=300
if a > limit :
print("Cant use the lift")
else:
print("Can use the lift")
You don't need to import math library for simple addition. Since you did not mention that what error are you getting, so I guess that you need a solution for your problem. Your code is too lengthy. I have write a code for you. which has just 6 lines. It will solve your problem.
Here is the code.
sum = 0;
while(True):
n = int(input("Enter Number.? Press -1 for Exit: "))
if n == -1:
break
sum = sum+n
print(sum)
Explanation of the Code:
First, I have declared the variable sum. I have write while loop, inside the while loop, I have prompt the user for entering number. If user will enter -1, this will stop the program. This program will keep on taking user input until unless user type "-1". In the end. It will print total sum.
Output of the Code:
Here's something for you to learn from that I think does all that you want:
people = 0
a = 0
while True:
while True:
try:
n = int(input("PERSONS WEIGHT?"))
break
except ValueError as ex:
print("You didn't type a number. Try again")
people += 1
a += int(n)
while True:
answer = input("Do we continue adding people ? y/n")
if answer in ["y", "n"]:
break
print("You typed something wrong , add another value ")
if answer == 'n':
break
limit = 300
if a > limit:
print("Total weight is %d which exceeds %d so the lift is overloaded" % (a, limit))
else:
print("Total weight is %d which does not exceed %d so the lift can be operated" % (a, limit))
The main idea that was added is that you have to have separate loops for each input, and then an outer loop for being able to enter multiple weights.
It was also important to move people = 0 out of the loop so that it didn't keep getting reset back to 0, and to initialize a in the same way.

How to change a range in a while loop with input in Python?

I'm new to python and I'm trying to write a program that will guess the users number.
I'm trying to change the range that's in a while loop, depending on the users answer, but i'm not sure how can I do that.
list = range(100)
half = len(list)//2
def the_guess():
guess = "n"
while guess != "y":
guess = input('is it ' + str(len(list)//2) + '? up(+) or down(-) ?\n')
if guess == 'y':
print('I knew it!!')
break #stops loop?
else:
if guess == '+':
print(list[half:])
# use second part of the range
if guess == '-':
print(list[:half])
# use first part of the range
else:
print("ok, let's try again\n")
the_guess()
The loop works, i'm just not sure how to go about changing the value of the range to something other than 100.
for example:
if the user inputs a "+" I want the range to change to 50 - 100, and will continue to dividing it depending on the users input.

While loop with functions and if/break statement?

I’m just starting to learn functions and I am practicing on implementing some into my code. Just a simple example... how can I code this to loop properly and break out when the user wants?
def profit(i,c):
gain = c - i
print('Your profit is:' + '' + str(gain))
def beginning():
x = float(input("What was your initial investment?"))
y = float(input("What is your investment worth now?"))
profit(x,y)
beginning()
ans = 'y'
while ans == 'y' or ans == 'Y':
ans = str(input('Would you like to calculate another investment? (Y/N)'))
beginning()
if ans != 'y' or ans != 'Y':
break
There are two ways to break out of a while loop. The first way is obviously the break statement, kind of like you have done. For it to work correctly, you need to change the condition:
if ans != 'y' or ans != 'Y':
break
This will always be true, since ans cannot be "y" and "Y" at the same time. You should change it into:
if ans not in ["y", "Y"]:
Or
if ans.upper() != "Y":
In your case however, you don't need it at all. Since in both the if statement and the while condition you are checking ans, you can get rid of the if and just rely on this.
while ans.upper() == "Y":
This will end the loop automatically when ans becomes anything other than "Y" or "y".
The only reason you would use a break here is if you wanted to exit the loop immediately, and not complete the current iteration. For example:
while ans.upper() == "Y":
ans = input("Enter selection: ")
if ans == "I want to stop right now!":
break
print("Do other things, even if ans is not Y")
In this example, "Do other things" will always be printed regardless of ans, unless ans is "I want to stop", in which case it won't get printed.
One thing you can do is ans = ans.capitalize() after you get the user input. Then remove the ans != 'y' since that's causing your loop to break.

User interaction via while-loops / jumping out of 2 while loops

Hello fellow programmers,
I'm quite a Python and overall programming newbie and I don't know how to process user input the bestimmt. A friend of mine suggested while loops and they worked quite well but now I have a serious problem.
The program is about asking the user which one of 3 ways to calculate Pi he wants. After his/her selection, e.g. the way to calculate Pi using a polygon which doubles the number of corners after each iteration, it asks how many digit the user wants to see or how many loops should be calculated etc. I also have added some code that checks what the user has written, e.g. if the user is asked to either type y or n but types b the program reminds him of that and asks again.
This style has led to whiles, inside whiles, inside whiles and now looks more like HTML code than Python and is a little complicated to understand...
Take a look:
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
prgrm_ctrl_main_while_start = 0
while prgrm_ctrl_main_while_start == 0:
print "Please select the type of algorithm you want to calculate Pi."
usr_ctrl_slct_algrthm = raw_input("'p' to use polygons, 'm' to use the Monte-Carlo algorithm or 'c' for the Chudnovsky algorithm: ")
print " "
if usr_ctrl_slct_algrthm == 'p':
#import libraries
import time
from mpmath import *
#starting values
n_corners = mpf(8)
counter = 0
while_loop_check_itertions = 0
while while_loop_check_itertions == 0:
print "Pi will be calculated more precisely the more iterations you select but it'll also take longer!"
loops = int(input("Please select number of iterations (1 - 10.000.000): "))
print " "
if 1 <= loops <= 10000000:
loops = loops - 1
decimals = int(input("Please select the amount of decimals you want to see: "))
print " "
decimals = decimals + 1
starttime = time.clock()
mp.dps = decimals
while counter <= loops:
counter = counter + 1
n_corners = mpf(n_corners) * mpf(2)
circle = mpf(360)
alpha = mpf(circle) / mpf(n_corners)
beta = mpf(alpha) / mpf(2)
radiansBeta = mpf(mp.radians(beta))
opp_leg = mpf(mp.sin(radiansBeta))
edge_lngth = mpf(opp_leg) * mpf(2)
circmfrnce = mpf(n_corners) * mpf(edge_lngth)
pi = mpf(circmfrnce) / mpf(2)
print "Pi: ", mpf(pi)
print "Time to calculate: ", time.clock() - starttime, "seconds"
print " "
prgrm_ctrl_p_algrthm_while_start = 0
while prgrm_ctrl_p_algrthm_while_start == 0:
usr_ctrl_slct_p_algrthm = raw_input("Would you like to try this algorithm again? (y/n): ")
print " "
if usr_ctrl_slct_p_algrthm == 'y':
usr_ctrl_slct_p_algrthm_slction = 0
break
elif usr_ctrl_slct_p_algrthm == 'n':
usr_ctrl_slct_p_algrthm_slction = 1
break
else:
print "You must either type 'y' or 'n'!"
continue
if usr_ctrl_slct_p_algrthm_slction == 0:
continue
else:
usr_ctrl_slct_diffrt_algrthm_while_start = 0
while usr_ctrl_slct_diffrt_algrthm_while_start == 0:
usr_ctrl_slct_diffrt_algrthm = raw_input("Do you want to use another algorithm? (y/n): ")
print " "
if usr_ctrl_slct_diffrt_algrthm == 'y':
usr_ctrl_slct_diffrt_algrthm_slction = 0
break
elif usr_ctrl_slct_diffrt_algrthm == 'n':
print "See you next time!"
print " "
usr_ctrl_slct_diffrt_algrthm_slction = 1
break
else:
print "You must either type 'y' or 'n'!"
continue
if usr_ctrl_slct_diffrt_algrthm_slction == 0: #The program gets to this line and in case of the user selecting 'y' should continue in the first while-loop
continue
else: #if the user says 'n' the program should interrupt and stop, in the best case it should close the command line (in my case IDLE)
break #instead of doing all this the code gets executed again in the 2nd while loop not the 1st
"""NOTE: I also know the lines above continue or quit the 2nd while-loop"""
elif loops < 1:
print "Please select at least one iteration!"
while_loop_check_algrthm_slct = 0
while while_loop_check_algrthm_slct == 0:
usr_ctrl_slct_algrthm_p_try_agn = raw_input("Do you want to try it again? (y/n): ")
print " "
if usr_ctrl_slct_algrthm_p_try_agn == 'y':
usr_ctrl_slct_algrthm_p_try_agn_slction = 0
break
elif usr_ctrl_slct_algrthm_p_try_agn == 'n':
usr_ctrl_slct_algrthm_p_try_agn_slction = 1
break
else:
print "You must either type 'y' or 'n'!"
continue
if usr_ctrl_slct_algrthm_p_try_agn_slction == 1:
break
else:
continue
else:
print "The maximum amount of iterations is 10 million!"
while_loop_check_algrthm_slct = 0
while while_loop_check_algrthm_slct == 0:
usr_ctrl_slct_algrthm_p_try_agn = raw_input("Do you want to try it again? (y/n): ")
print " "
if usr_ctrl_slct_algrthm_p_try_agn == 'y':
usr_ctrl_slct_algrthm_p_try_agn_slction = 0
break
elif usr_ctrl_slct_algrthm_p_try_agn == 'n':
usr_ctrl_slct_algrthm_p_try_agn_slction = 1
break
else:
print "You must either type 'y' or 'n'!"
continue
if usr_ctrl_slct_algrthm_p_try_agn_slction == 1:
break
else:
continue
I have commented the lines that are effected...
I can't solve the problem with the main-while-loop therefore I'm asking you how I can solve this. Is there a better way of handling user input and checking if it's correct? I'm stuck at a point where I wish I had goto because I can't imagine any other solution.
Hopefully you can help me and thank you for reading this long code! I appreciate that! :)
holofox
My first thought is simplify things, please see this "pseudo-code":
while True: #select algorithm type
#code: ask for algorithm
if answer not in "pmc":
#some message
continue #non-valid algorithm selected, ask again
#...
if answer == 'p':
while True: #select iteration range
#code: ask for iteration
if answer_not_in_range:
#some message
continue #non-valid iteration value, ask again
#...
#perform calculation upon valid selections
#...
#calculation ends
#code: ask for try again with other iteration (algorithm stays same)
if answer != "yes":
break #break out of "iteration" loop
#else loop continues asking for new iteration
#code: ask for try again with other algorithm
if answer != "yes":
break #"algorithm" loop ends, program ends
As Robert Rossney says in an answer to another question:
My first instinct would be to refactor the nested loop into a function and use return to break out.

Categories