How to stop function from going back in without calling quit() - python

so I've been trying to make a little number-guessing game where the user guesses a number and the computer basically says whether that's higher/lower than the correct number or if it's correct.Basically, everything works correctly up until the user enters an invalid input(anything that isn't an integer). Then it still works correctly but when you eventually guess the right number it tells you that you won and the number of tries that you took būt it also returns a Typerror which says that strings and ints cannot be compared. This is weird because it doesn't do it as soon as you enter the invalid input but rather at the end when you get it correct. Additionally, it shouldn't even be doing that as there is no part in the else statement that tells it to go back into the function.
from random import randint
def game(rand_num = randint(1,10),trys=1): #generates random number and sets trys to 1
user_guess = input('enter your guess 1-10:') #user guess
try: # try except to check for validity of input,restarts functions with preserved random number and # of tries
user_guess = int(user_guess)
except:
print('please try again and enter a valid input')
game(rand_num=rand_num,trys=trys)
# if and elif to check if the number was higher or lower,if it was then it will restart the game function with preserved random number
# and trys increased by 1
if user_guess < rand_num:
print('your guess was lower than the magic number so try again')
game(rand_num=rand_num,trys=trys+1)
elif user_guess > rand_num:
print('your guess was higher than the magic number so try again')
game(rand_num=rand_num,trys=trys+1)
else: #if both don't work then you must have won and it tells you that as well as how many trys you took``
print('hurray you won!!!!!')
print(f'you took {trys} trys')
game()
Also when I tried to use a breakpoint to determine the issue, again everything seemed fine until
after it told the that they won,it mysteriously just went back into the function and started doing stuff with the previously invalid input set as the user_guess variable which is presumably why the Type error happened.
the first place where the function "goes" to after telling the user they won
the 2nd place where it "goes"
It does that for a few more times but yeah it just basically cycles through if elif and try except for some reason
however, I found out that you can use a quit() at the end of the else statement that tells the user they won to solve this but as far as I know that just suppresses the function from doing anything and exits it so it isn't really a solution.

Related

Trouble with While loop for a color guessing game

Having difficulty with this assignment, here is the instructions we we're provided with.
create a program the user to guess your favorite color. Using a while loop, if the user didn’t guess your favorite color then tell them they are incorrect, then ask them again. Whenever they guess
the color correctly, output that they are correct and how many guesses it took them.
Create a variable and assign it the value of 1
Prompt the user to guess your favorite color
While their guess is not equal to your favorite color:
Tell them they are incorrect
Prompt them to guess again
Add one to the variable above
Output to the user that they were correct and how many attempts it took, using the variable
Here is what I have so far it doesn't work correctly
correct_guess='red'
guess_count=0
guess_limit=float('inf')
while guess_count<guess_limit:
guess = input('Guess a color: ')
guess_count += 1
if guess == correct_guess:
print('Congratulations! You won! it took you this many attempts: ' + str(guess_count))
break
else:
guess = input('Incorrect, guess again')
With this code, your if-else statement is outside of the while loop. Since your loop runs forever, it will never exit the loop (so it won't run the rest of your code).
To fix this, try putting the code that is after the while loop inside, like so:
while guess_count<guess_limit:
guess = input('Guess a color: ')
guess_count += 1
if guess == correct_guess:
print('Congratulations! You won! it took you this many attempts: ' + str(guess_count))
break
else:
guess = input('Incorrect, guess again')
Python is very indentation-based, so watch out for your indentation!
Also, next time you ask a question try to be a little more descriptive of your error/issue. Other people might not understand what is going wrong :)
Edit: You should also change the guess = input('Incorrect, guess again) to just a print() statement (you don't want the user to guess again there). Thanks to #quamrana for this!

Why is my if statement not executing when I start my code?

I'm a beginner programmer just starting out and learning and I'm wondering why my code finishes after the first line. If anyone can let me know what is wrong with it, would be greatly appreciated.
I wanted it to print my if statements properly but I'm not sure what's going on.
x = 10
try:
(input("Type in a number:"))
except ValueError:
print('Correct!')
if x > 10:
print('X is bigger than the number given')
if x < 10:
print('X is smaller than the number given')
Since you stated that you're a new programmer (welcome! we've all been in your shoes at one point), I'm going to assume from looking at your code that the goal of your game is to have a "magic number" that is set ahead of time, and you want the user to try and guess it. In general, good programs are self-documenting, meaning the code is written in a way that clearly describes what it does. Comments are also helpful. Take a note of the changes I made to your program and how they help you understand what's going on:
"""
* This comment is known as a module docstring
and describes the module, the file in this case
* guessing_game.py is a command-line game
where users try to guess a random number
while getting hints about their guess.
"""
magic_number = 42 # set this before running the program
while (guess := int(input('enter a guess: '))) != magic_number:
# * use a while loop to loop until the correct answer is entered.
# NOTE: the "walrus operator `:=` is used for consiceness.
# the walrus operator requires python >= 3.8
if guess > magic_number:
print('Too high!')
else:
print('Too low!')
print('You win!')
Now, kuwl, I challenge you to try the following on your own:
generate magic_number automatically when the program starts.
hint: https://docs.python.org/3/library/random.html
Set a special number, called a "sentinel value" in computer science, that will terminate the loop if the user wants to quit before guessing the correct number.
Set a limit on the number of attempts the player can make before he/she "loses". This can be done in several ways, try and think of a few!
Allow users to quit the game with ctrl-c, which is a common way to exit command-line programs like yours. Try catching the exception that gets "thrown" when a users hits ctrl-c gracefully and print a message like "thanks for playing, come again!"
Those changes will introduce you to a lot of key concepts in programming like importing packages, handling exceptions, and writing comments and self-documenting code. If you get stuck, try googling your question. There's a good chance many others have asked the same before. It's a valuable skill in programming to be able to write good questions, both to a search engine and to another human. If you're still stuck, ask a comment on this post and I'll do my best to answer it.
Happy hacking!
You will never get a ValueError in this program from this line input("Type in a number:")
Corrected code:
x = 10
try:
x = input("Type in a number:")
print('Correct!')
except ValueError:
if x > 10:
print('X is bigger than the number given')
if x < 10:
print('X is smaller than the number given')
You can simply do:
x = 10
x = input("Type in a number:")
if x.isnumeric() : # checks if x is numeric or not
print('Correct!')
if x > 10:
print('X is bigger than the number given')
if x < 10:
print('X is smaller than the number given')

Python | while is repeating old data, even if False

I'm trying to create a loop if the condition is not met. If it is met at minimum second run, the print from my last run is also in my output, like in the example its printing the same print() that was printed in the previous run in addition to the result of the second run.
secretcode= r.randint(1, 100)
print("\n\n\nWelcome to the lottery!\n")
print("Guess a number from 1 to 100!")
print(secretcode)
def usrinput():
usrinputnumber = int(input("Your number: "))
schleife(usrinputnumber)
def schleife(usrinputnumber):
while not (secretcode == usrinputnumber):
if usrinputnumber > secretcode:
print("Awh damn! Your number is too high!!")
usrinput()
else:
print("Unlucky! YOur number is too low!")
usrinput()
print("Congratz! You guessed the number!!")
usrinput()
Everything works fine when I do an "if" instead the while and using the last print as "else"
Example:
The "secretcode" is 55.
As input I type 45.
The console prints "Unlucky! The number is too low!"
Now I type 55.
The console prints the "Congratz" message AND the "too low" message. Why the "too low" message?
I know functions are not needed, I just wanna know what the problem is and if I can run it in functions like I did.
Thank you very much!
This control flow does not make any sense. Please keep in mind that calling a function is not at all like telling the code to "go here next". It is a request to compute a result, which you will then use in the current context. It is also important to understand that each call to a function is a separate process. The function is not like a machine that is set in motion when called, but instead like a set of instructions that will be followed by a new executor, each time.
When usrinput() is called from within schleife, right now usrinput will call schleife again. That separate call has its own complete set of local variables, including the usrinputnumber parameter. Supposing that the user typed the correct secretcode, this call to schleife will escape its while loop, print the success message...
... and then return back the result of its computation (which is None) to its caller, the call of usrinput, which returns its result (also None) to the other call of schleife, which also hadn't finished yet. And, within that call, nothing has changed its local value for usrinputnumber, so the loop continues.
Remember that functions are supposed to do one thing. The purpose of usrinput is to get the user's input. The task performed by schleife is not a logical part of that task, therefore usrinput should not call schleife.
Instead: usrinput, instead of trying to feed the result of its computation (i.e., the user's input) to the "next step", should return that result - that is what return is for.
On the other hand, schleife can still call usrinput, because "get new user input to see if it matches this time" is a logical part of its task. Since the value will be returned, we need to make use of that by explicitly assigning it to usrinputnumber. We can also see that since schleife will be calling usrinput in the loop anyway, it makes as much sense to get the initial value that way, too.
Putting it together, we get:
def usrinput():
return int(input("Your number: "))
def schleife():
usrinputnumber = usrinput()
while not (secretcode == usrinputnumber):
if usrinputnumber > secretcode:
print("Awh damn! Your number is too high!!")
usrinputnumber = usrinput()
else:
print("Unlucky! YOur number is too low!")
usrinputnumber = usrinput()
print("Congratz! You guessed the number!!")
schleife()

Interest Calculator looping issue Python

beginner here. I've made an interest calculator program to help me with my loans of different sorts. I'm having two issues to finalize my program. Here's the program. I tried looking up the problems but I wasn't sure how to word it so I thought I'd just ask a question in total.
x=1
while x==1:
import math
loan=input("Enter Loan amount: ")
rate=input("Enter rate: ")
if rate.isalpha() or loan.isalpha():
print("Hey that's not a number!")
break
rate=rate.replace("%","")
loan=float(loan)
rate=float(rate)*0.01
amount1y=round(loan*(math.e**(rate*1)),2)
amount5y=round(loan*(math.e**(rate*5)),2)
amount10y=round(loan*(math.e**(rate*10)),2)
monthlypay=round(amount1y-loan,2)
print("Year 1 without pay: " + str(amount1y))
print("Year 5 without pay: " + str(amount5y))
print("Year 10 without pay: " + str(amount10y))
print("Amount to pay per year: " + str(monthlypay))
print("Want to do another? Y/N?")
ans=input('')
ans=ans.lower()
y=True
while y==True:
if ans=="n" or ans=="no":
x=0
break
elif ans=="y" or ans=="yes":
y=False
else:
print("You gotta tell me Yes or No fam...")
print("I'll just assume that mean's yes.")
break
My issue is in two locations. First during the
if rate.isalpha() or loan.isalpha():
print("Hey that's not a number!")
break
How do I write this so that instead of it ending the program all together, it instead restarts from the top until they put in a number. Also as a side just for fun and knowledge. Lets say they enter text three times in a row, and at that point it just executes the program how would I go about doing that also?
Finally during this part of the code:
while y==True:
if ans=="n" or ans=="no":
x=0
break
elif ans=="y" or ans=="yes":
y=False
else:
print("You gotta tell me Yes or No fam...")
print("I'll just assume that mean's yes.")
break
the else at the end, without that break, will continue printing "You gotta tell me Yes or No fam..." forever. How do I make it so that instead of breaking the while statement, it'll just restart the while statement asking the question again?
Thanks for your help!
P.S. This is python 3.4.2
You make an infinite loop, that you break out of when all is well. Simplified:
while True:
x_as_string = input("Value")
try:
x = float(x_as_string)
except ValueError:
print("I can't convert", x_as_string)
else:
break
It is easier to ask forgiveness than permission: You try to convert. If conversion fails you print a notice and continue looping else you break out of the loop.
On both of your examples, I believe your looking for Python's continue statement. From the Python Docs:
(emphasis mine)
continue may only occur syntactically nested in a for or while loop, but not nested in a function or class definition or finally clause within that loop. It continues with the next cycle of the nearest enclosing loop.
When continue passes control out of a try statement with a finally clause, that finally clause is executed before really starting the next loop cycle.
This basically means it will "restart" your for/while-loop.
To address your side note of breaking the loop if they get the input wrong after three tries, use a counter variable. increment the counter variable each time the user provides the wrong input, and then check and see if the counter variable is greater than 3. Example:
counter = 0
running = True:
while running:
i = input("Enter number: ")
if i.isalpha():
print("Invalid input")
counter+=1
if counter >= 3:
print("Exiting loop")
break
Unrelated notes:
Why not use a boolean value for x as well?
I usually recommend putting any imports at the module level for the structure an readability of one's program.
Your problem is straightforward. You have to use continue or break wisely. These are called control flow statements. They control the normal flow of execution of your program. So continue will jump to the top-most line in your loop and break will simply jump out of your loop completely, be it a for or while loop.
Going back to your code:
How do I write this so that instead of it ending the program all together, it instead restarts from the top until they put in a number.
if rate.isalpha() or loan.isalpha():
print("Hey that's not a number!")
continue
This way, you jump back (you continue) in your loop to the first line: import math. Doing imports inside a loop isn't useful this way the import statement is useless as your imported module is already in sys.modules list as such the import statement won't bother to import it; if you're using reload from imp in 3.X or available in __builtin__ in Python 2.x, then this might sound more reasonable here.
Ditto:
if ans=="n" or ans=="no":
x=0
break
elif ans=="y" or ans=="yes":
continue
else:
print("You gotta tell me Yes or No fam...")
print("I'll just assume that mean's yes.")
continue
To state this snippet in English: if ans is equal to "n" or "no" then break the loop; else if ans is equal to "y" or "yes" then continue. If nothing of that happened, then (else) continue. The nested while loop isn't needed.
Lets say they enter text three times in a row, and at that point it just executes the program how would I go about doing that also?
Not sure if I understood your question, you can take input three times in different ways:
for line in range(3):
in = input("Enter text for lineno", line)
...do something...

Python program, how to make an atm program loop

How do i make it loop back to the start after doing this? After each transaction, it ends and doesn't go back to see if you can pick another option.
Thanks and it's greatly appreciated.
balance=7.52
print("Hi, Welcome to the Atm.")
print("no need for pin numbers, we already know who you are")
print("please selection one of the options given beneath")
print("""
D = Deposit
W = Withdrawal
T = Transfer
B = Balance check
Q = Quick cash of 20$
E = Exit
Please select in the next line.
""")
option=input("which option would you like?:")
if option==("D"):
print("How much would you like to deposit?")
amount=(int(input("amount:")))
total=amount+balance
elif option ==("W"):
print("How much would you like to withdrawl?")
withdrawl=int(input("how much would you like to take out:?"))
if balance<withdrawl:
print("Error, insufficent funds")
print("please try again")
elif option == "T":
print("don't worry about the technicalities, we already know who you're transferring to")
transfer =int(input("How much would you like to transfer:?"))
print("you now have", balance-transfer,"dollars in your bank")
elif option=="B":
print("you currently have",balance,"dollars.")
elif option=="Q":
print("processing transaction, please await approval")
quicky=balance-20
if balance<quicky:
print("processing transaction, please await approval")
print("Error, You're broke.:(")
elif option=="E":
print("Thanks for checking with the Atm")
print("press the enter key to exit")
It seems like you are asking about a loop with a sentinel value.
Somewhere right before you print your menu, set a sentinel value:
keep_going = True
Then, preferably on the next line (before you print the first thing you want to see when it loops), you start your loop.
while keep_going: # loop until keep_going == False
As written, this is an infinite loop. Everything in the indented block beneath the while statement will be repeated, in order, forever. That's obviously not what we want -- we have to have some way to get out so we can use our computer for other things! That's where our sentinel comes in.
Build in a new menu option to allow the user to quit. Suppose you key that to "Q", and the user picks it. Then, in that branch:
elif option == 'Q':
keep_going = False
Since that's all there is in that branch, we "fall off" the bottom of the loop, then go back to the while statement, which now fails its check. Loop terminated!
By the way, you should think about reading The Python Style Guide. It's very easy to read and gives you an idea how to make your code also very easy to read. Most every Python programmer abides by it and expects others to do the same, so you should too! If you want help learning it, or aren't sure if you're doing it right, there are tools to check your code to help you keep it clean and error-free.
Happy programming!

Categories