Python | while is repeating old data, even if False - python

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()

Related

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

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.

Write a program that prints out the first N emirps, five on each line, using python

An Emirp is a prime number whose reversal is also a prime number. For example, 17 is a prime and 71 is a prime, so 17 and 71 are emirps.
The following code compiles and accepts input. The input validation is correct but the program keeps running and does not output anything. I also wanted to know how it's possible to find errors in python. Please ignore indentation errors if there are any.
class negerror(UserWarning):
pass
while True:
prompt = input('Please enter a positive number: ')
try:
number=int(prompt)
if number<=0:
raise negerror
break
except ValueError:
print('You did not enter an integer. Please try again. ')
except negerror:
print('You entered a negative number. Please make sure to enter a positive number')
def isPrime(value):
count=0
for i in range(1,value+1):
if value%i==0:
count=count+1
if count<=2:
return True
else:
return False
def reverse(value):
val=str(value)
val=val[::-1]
val=int(val)
return val
Test=2
countemirps=0
numberinoneline=0
while countemirps<number:
if isPrime(Test) and isPrime(reverse(Test)):
print('%6s'%Test, end = ' ')
countemirps=countemirps+1
Test=Test+1
numberinoneline=numberinoneline+1
if numberinoneline%5==0:
print('\n')
Your isPrime function is off. It counts the number of divisors of value and stores it in variable count. However, you return True if count>2 and False otherwise. It should be the other way around: a prime number has two divisors and composite numbers have more then two. So change the test to count <= 2. Even better and more pythonic, replace the last lines of that function with
return count <= 2
or perhaps
return count == 2
Do you see why that works?
(I see that you have now corrected this error and edited your question but the program still does not work.)
Another error is that in your main loop you have the test
if isPrime(Test) and isPrime(reverse(Test)):
If that test is passed, you print the number and update your variables including Test--all is well. However, if the test fails you do nothing, and in particular the value of Test is not changed. The loop repeats and you do exactly the same test, and nothing changes. The program is stuck in an infinite loop.
You can fix this by moving the line that updates Test out of the if test and place it at the end of the loop so it is executed on each loop. Your loop then becomes
while countemirps<number:
if isPrime(Test) and isPrime(reverse(Test)):
print('%6s'%Test, end = ' ')
countemirps=countemirps+1
numberinoneline=numberinoneline+1
if numberinoneline%5==0:
print('\n')
Test=Test+1
When I test your program now, it seems to work.
There may be other errors as well that I do not see. You should test function isPrime separately from the rest of your code. When that works well, then test function reverse. Then test sections of your code. Running your code all at once makes it difficult to localize and find errors.
Finally, you ask "how it's possible to find errors in Python". This is too broad a question for this site--you should read a book chapter or a tutorial on debugging. But in brief, there are two main approaches for beginners. The first is to liberally put print statements in your code, showing the flow of the program execution and the values of your key variables. If you had place the statement
print(Test)
at the beginning of your loop, you would have seen that the loop was repeating indefinitely and the value of Test was not changing. When the errors seem to be gone, you can remove or comment-out the print statements. Logging can do this a bit more easily
Another, better approach is to use a debugger. I do most of my Python programming in Spyder, a development environment which includes a debugger. I used that to execute your program one line at a time, and one window in Spyder showed my the values of your variables. There also are debuggers that work outside a development environment. I encourage you to find, learn, and use an Integrated Development Environment that includes a debugger. Spyder is a free, excellent one that specializes in scientific programming. I use it for my mathematics programming.

Python game; Why can't I re-call my input and if/else function?

I'm still kind of learning Python, but my friend who has programmed in Python before says this should work fine, but it wont?
All code before this was the beginning story for this basic "escape the room" game I'm making. The code up until here works, (basic print functions describing the game).
I give the player the scenario that they're in a room and they can do one of two things:
def intro_room_input():
intro_action = input("What would you like to do? (Please enter either: 1 or 2) ")
return intro_action;
These two functions are for when they choose 1 or 2, the next if/elif function runs these functions
If they choose 1:
def intro_room_result1():
print(
"""
(Story stuff for the result of option 1. Not important to the code)
""")
return;
This function will play out if they choose 2
def intro_room_result2():
print(
"""
(Story stuff for the result of option 2. Not important to the code)
""")
return;
This will be the function for taking the player's input and continuing the story from there.
def intro_action_if(string):
if string == "1":
intro_room_result1()
elif string == "2":
intro_room_result2()
else:
print("I'm sorry, that wasn't one of the options that was available..."+'\n'+
"For this action, the options must be either '1' or '2'"+'\n'+
"Let me ask again...")
intro_room_input()
intro_action_if(string)
return;
that last intro_room_input runs fine, it re-runs the previous input, but when you actually enter 1 or 2, it doesn't do anything with them. It doesn't want to re-run the if/elif/else function to give the results.
finally I have a main that runs everything:
def main():
string = intro_room_input()
intro_action_if(string)
return;
main()
Please help, I have no idea what's wrong with this code!?
The problem is in your intro_action_if(). When you are calling the function to get values again, you forgot to change the string value.
ie,
#intro_room_input() #wrong
string = intro_room_input() #right
intro_action_if(string)
As you can see, even though in your code you asked for the user input and returned it, you forgot to reassign string with the returned value. Hence it kept the same input you had given previously and passed that old value to intro_action_if().

How to fix a loop that runs once if value is correct 1st time. But runs for ever if the 1st value is wrong and 2nd value is correct.

I'm doing this controlled assessment. I am just a beginner so I don't know too much about python.
I have this code:
# defining qualification
def qualification():
print("\nQualification Level") # informs user what is AP + FQ
print('\n"AP" = Apprentice', '\n"FQ" = Fully-Qulaified')
user_qual = input("Enter your Qualification Level")
# error message if any other data is entered
while user_qual not in ("AP", "FQ"):
print("You have entered one or more data wrong!")
print("Please re-enter Qualification Level!")
qualification()
Every time this code runs, it runs good until the while loop. If I enter the correct value (i.e. AP or FQ) the fist time I run the code, then the while loop doesn't run, as it should. But if I enter the wrong value the first time (any value that is not FQ or AP) the while loop runs as it should but then after it runs the first time, eve if I enter the correct value after entering the wrong value the while loop doesn't stop looping. A infinite loop is being created.
Please provide an answer, remember I'm just a beginner at programming with python, so please don't let the solution be too complicated.
You tried to use recursion at the wrong place.
If the user input is wrong for the first time, you will get into a deeper level recursion that will (maybe) input the right input (or will go deeper).
But then, it will end and go back to the previous level of recursion, where the user_qual variable is still the same, which will result in infinite loop.
Note: variables are not the same while running into a different recursion level. You are getting into another local scope. You might want to do a little search about scopes before you continue with your program.
So, instead of calling to qualification() on the last line, just input again:
while user_qual not in ("AP", "FQ"):
print("You have entered one or more data wrong!")
user_qual = input("Please re-enter Qualification Level!")
Another solution will be to use global user_qual in the beginning of the function and in the beginning of the loop. Read about global variables in python if you plan to act so.

Python code gives none

I am new to python,trying to write program for finding amstrong and modulus . But I have problem in finding amstrong no,it will not go to end state,hang in the middle. However,modulus is working fine. It will not throw any error. Here is my code:
try:
def check(s):
if(s==1):
print 'enter the no'
v=[]
s=int(raw_input())
print s
for x in str(s):
print x
v.append(x)
print v
x=len(v)
i=0
y1=0
print v[0]
while(i<x):
y=int(v[i])
y=y**3
y1=y1+y
print y1
if(y1==s):
print "given no",s,"is amstrong no"
else:
print "given no",s,"is not a amstrong no"
elif(s==2):
print 'enter the 1st no'
s=int(raw_input())
print 'enter the 2nd no'
s1=int(raw_input())
ans=s%s1
print 'modulus ans is',ans
finally:
print "bye bye"
try:
print "1.amstrong 2.modulus"
x=int(raw_input())
if(x>=1 and x<=2):
check(x)
finally:
print 'bye bye'
Please help me on this.
The reason it's hanging in the middle is that you enter into the while loop while(i<x):, but you never change the value of either i or x. (You do change y and y1, but your conditional doesn't involve either.) The condition never ends up being false, and can't ever end up being false, so it continues to execute forever.
Note also that you're not really using try blocks correctly. There's no point in using try unless you're using except to handle any exceptions. (On a different level, you shouldn't be wrapping the entirety of your code in a try block in the first place - exceptions are useful information that make it easier to discover ways your program isn't working correctly, and ignoring them can lead to unpredictable, difficult-to-debug states.)
Last piece of advice - recognizing and fixing your problems is almost universally made easier (for both of us) by using distinct, pertinent names to your variables - it's very difficult to figure out what you're doing when every single variable is a single letter, and some are just a letter you've already used with a number appended.
You can check if a number is a 3-digit ammstrong using the function coded below.
This however is restricted to only 3 digits, but using loops correctly this will work of a greater number of digits as well. Almost in the way you have done. But always remember to increment or decrement the loop counter to prevent infinite loop. Otherwise the loop "will not go to end state,hang in the middle".
def Ammstrong(s):
n1=s/100
#n1 contains the 1st digit of number, s.
n2=s%100
n2=n2/10
#n2 contains the 2nd digit of number, s.
n3=s%10
#n3 contains the 3rd digit of number, s.
number=(n1**3)+(n2**3)+(n3**3)
if number==s:
print number,"is an Ammstron Number"
#return number
else:
print number,"is not an Ammstron Number"
#return number
num=input(Enter a number: ")
Ammstrong(num)
#use this if return is uesd:
#number=Ammstrong(num)
This function will print the answer. So, there wont be any need to use the print function in the main function to print your answer.
If you wish to perform further calculations, use 'return'. This is illustrated in the coded using comments. But, as soon as the return execution is executed, the program in which the statement is executed, terminates. Meaning the function will terminate not the main program. So, use the return function after the print function.
If you do use the return function u'll have to store the returned value in a variable.
One thing more:
You have made use of the variable x before initiating it.
And, instead of using (s==2) statement use (s!=0). "!=" is the symbol for "not equal"
Best of luck with learning python. It is a very interesting language.
http://pythontutor.com will show you the execution of the code step by step.

Categories