Program stuck in while loop not printing - python

import random
def usertype():
randletter = random.choice('qwer')
userinput = raw_input('Press '+str(randletter))
if userinput == randletter:
return 'Correct'
else:
return 'Incorrect'
def usertypetest(x,y,result):
while x <= 9:
result = usertype()
if result == 'Correct':
x = x+1
y = y+5
else:
x = x+1
y = y-2
return str(y)+'is your score'
print usertypetest(0,0,usertype)
Here is my code. I want it to ask the user to press a button, randomly chosen from the set (Q, W, E, R), then print either correct or incorrect, depending on which button they press. I want this to happen 10 times. After ten tries it will print their score: 5 for each 'Correct' and -2 for 'Incorrect'. Instead I receive this.
Press e(e)
Press e(e)
Press w(e)
Press q(e)
Press q(e)
Press q(e)
Press r(e)
Press e(e)
Press w(e)
Press q(e)
Press e(e)
Press e(e)
Press e(e)
Press e(e)
Press q(e)
Press w(e)
Press r(e)
Press w(e)
Press r(e)
Press w(e)
Press r(e)
Press r(e)
Regardless of what I enter, it returns neither 'Correct', nor 'Incorrect'. It also continues on past 10 and does not show their score. There is clearly a problem I am not seeing.
My input is in brackets.
For clarification, this is what I want:
Press q(q)
Correct
Press e(q)
Incorrect
Press w(w)
Correct
Press q(q)
Correct
Press e(eq)
Incorrect
Press e(e)
Correct
Press q(q)
Correct
Press q(r)
Incorrect
Press w(w)
Correct
Press r(r)
Correct
29 is your score

In Python indentation is very important.
In this code, the x for the while loop is never changed as the if block is on the same indent level as the while loop. So the only looped instruction is result = usertype()
while x <= 9:
result = usertype()
if result == 'Correct':
x = x+1
y = y+5
Two additional critiques:
You are incrementing x in two places, when it only needs to be done once.
while x <= 9:
result = usertype()
if result == 'Correct':
y = y+5
else:
y = y-2
x += 1
Also, since you are looping a fixed number of times, why not ignore incrementing x and use a for loop, like so:
for x in range(10):
result = usertype()
if result == 'Correct':
y = y+5
else:
y = y-2

You need to put the if result == 'Correct': block under the while x <= 9: loop where you get the user input, so that it gets evaluate every time. And you can add the print(result) to get the correct/incorrect feedback as in your example:
def usertypetest(x,y,result):
while x <= 9:
result = usertype()
if result == 'Correct':
x = x+1
y = y+5
else:
x = x+1
y = y-2
print(result)
return str(y)+'is your score'

Your main problem was that you had the if/else block in the wrong scope. You needed it to be under the while block. This makes sure that it checks whether the user entered the correct input each time usertype() is run.
import random
moves = 0
score = 0
def usertype():
randletter = random.choice('qwer')
userinput = raw_input('Press '+str(randletter))
if userinput == randletter:
return True
else:
return False
def usertypetest(moves, score):
while moves < 10:
result = usertype()
moves = moves + 1
if result:
score = score + 5
else:
score = score - 2
return str(score) + ' is your score'
print usertypetest(moves, score)

Also, you are not printing the value of the variable result. After evaluating result, add the following:
print result

Apart from the indentation problem that other people have identified, the code is not particularly idiomatic Python. The usertypetest() function could be:
def usertypetest(x,y,result):
for x in range(10):
if usertype() == 'Correct':
y = y + 5
else:
y = y - 2
return '%d is your score' % y
There might be better ways to do this, but this is a little simpler and a little more Pythonic.
I'll also observe that I don't see the parentheses around the input that the example claims to see.
If you want to see the verdict on each letter, then you need to save the return from usertype() after all:
def usertypetest(x,y,result):
for x in range(10):
result = usertype()
print result
if result == 'Correct':
y = y + 5
else:
y = y - 2
return '%d is your score' % y

There are several problems here.
You need to print 'correct' before usertype returns.
You don't need to put 'result' in usertypetest.
Put if...else inside the loop in usertypetest.
Change your last print.
Here is the correct code.
import random
def usertype():
randletter = random.choice('qwer')
userinput = raw_input('Press '+str(randletter))
if userinput == randletter:
print 'Correct'
return 'Correct'
else:
print 'Incorrect'
return 'Incorrect'
def usertypetest(x,y):
while x <= 9:
result = usertype()
if result == 'Correct':
x = x+1
y = y+5
else:
x = x+1
y = y-2
return str(y)+'is your score'
print usertypetest(0,0)

Just put if block under the while loop.
Problem solved.
Try with this code :
import random
def usertype():
randletter = random.choice('qwer')
userinput = raw_input('Press '+str(randletter))
if userinput == randletter:
return 'Correct'
else:
return 'Incorrect'
def usertypetest(x,y,result):
while x <= 9:
result = usertype()
if result == 'Correct':
x = x+1
y = y+5
else:
x = x+1
y = y-2
return str(y)+'is your score'
print usertypetest(0,0,usertype)

Related

How to nest a function that responds to outside of function call?

I'm trying to figure out how I can solve this issue. I have a Raspberry Pi that is set up with a breadboard that consists of:
1 RGB light
2 buttons (left and right)
1 OLED screen
Each component works and I can run each one. What I'm trying to do is write a script that will allow me to select the "mode" with the left button (everything off vs lights vs screen on).
When a mode is selected, the right button then allows me to select between options within that mode. Below is the code as I have it:
def off():
lights = [red,green,blue]
for light in lights:
light.off()
def lightSelector():
off()
number = 0
while number < 5:
if rightButton.is_pressed:
if number == 0:
off()
red.on()
sleep(1)
number += 1
elif number == 1:
off()
green.on()
sleep(1)
number += 1
elif number == 2:
off()
blue.on()
sleep(1)
number += 1
elif number == 3:
off()
row()
sleep(1)
number+= 1
else:
number = 0
def picture():
image = Image.open('grant.jpeg')
image_r = image.resize((width,height), Image.BICUBIC)
image_bw = image_r.convert("1")
for x in range(width):
for y in range(height):
oled.pixel(x,y,bool(int(image_bw.getpixel((x,y)))))
oled.show()
def oledOff():
oled.fill(0)
oled.show()
def buttons():
x = 0
y = 0
while y is 0:
print('x = ' , x)
print('y = ' , y)
if leftButton.is_pressed:
if x == 0 :
oledOff()
off()
sleep(0.5)
x += 1
elif x == 1:
oledOff()
off()
lightSelector()
sleep(0.5)
x += 1
elif x == 2:
oledOff()
off()
picture()
sleep(0.5)
x += 1
else:
x = 0
oledOff()
off()
buttons()
The idea is that the buttons() function is the main overall function and will call the others as needed. My issue is that once I get to y == 1, or the lightSelector() function, it no longer registers that the leftButton is being pressed and won't switch to the next mode and I'm stuck in the lightSelector() function.
I know at baseline I can spell out lightSelector within the buttons function instead of calling another function but I'm trying to not be as verbose. I don't have any experience with threading or multprocessing and looked into it but couldn't see how that would help.

While loop not terminating when the condition has been satisified

While programming in Python I got stuck in a case where the while loop is not terminating even after the condition is being satisified then also
the code is as follows:
print('--- Alex\'s Calculator ---')
print('1. ADDition')
print('2. SUBstraction')
print('3. MULtiply')
print('4. DIVide')
print('5. EXIT')
x = int(input())
command = ' Enter Your Two numbers To Perform The Operation : '
def ini():
a = int(input())
b = int(input())
return a, b
def resultoo():
result = ' Your Result after Performing The Operation from {} and {} is {}'
print(result.format(a,b,c))
print(' Want To Continue If Yes then Enter Your Choice else Press any number exept 1 - 4')
x = int(input())
while x < 5:
if x == 1:
print(command)
a, b = ini()
c = a + b
resultoo()
elif x < 5:
break
As kuro specified in the comment, x can't be seen by your while loop because it's local to resultoo().
To solve it easily just add :
return x
at the end of resultoo()
and
x = resultoo()
in your while loop
You can use global var to this, change the this:
def resultoo():
result = ' Your Result after Performing The Operation from {} and {} is {}'
print(result.format(a,b,c))
print(' Want To Continue If Yes then Enter Your Choice else Press any number exept 1 - 4')
x = int(input())
into:
def resultoo():
global x
result = ' Your Result after Performing The Operation from {} and {} is {}'
print(result.format(a,b,c))
print(' Want To Continue If Yes then Enter Your Choice else Press any number exept 1 - 4')
x = int(input())
Explnation:
x is a global argument, that will be the same out of the function closure, but not inside of it, the function has it own params, so if you want to change a global argument that is initalizing outside the function, you will need to call the global statement before, that will make x the global x
When option 5 is entered you want to exit.
I added
import sys
and changed
elif x < 5:
to
elif x == 5:
and added
sys.exit(0)
I also added the getMenu() function
This is the complete code that is working in my editor:
import sys
def ini():
command = ' Enter Your Two numbers To Perform The Operation : '
print(command)
a = int(input())
b = int(input())
return a, b
def resultoo(a, b, c):
result = ' Your Result after Performing The Operation from {} and {} is {}'
print(result.format(a, b, c))
def getMenu(x):
if x == 0:
print("Choose menu item")
x = int(input())
elif x != 0:
print(' Want To Continue If Yes then Enter Your Choice else Press any number exept 1 - 4')
x = int(input())
return x
def main():
x = 0
while x < 5:
print('\n\n1. ADDition')
print('2. SUBstraction')
print('3. MULtiply')
print('4. DIVide')
print('5. EXIT\n')
x = getMenu(x)
if x == 1:
a, b = ini()
c = a + b
resultoo(a, b, c)
elif x == 5:
sys.exit(0)
else:
print("No valid menu item")
if __name__ == '__main__':
print('----------------------------------------------------------------------------------------------------------')
print('-------------------------------------------- Alex\'s Calculator -------------------------------------------')
main()
I also formatted your code (alt+Enter in Pycharm) to comply to PEP8 standards ;)

Python text game - Cant exit a while loop

this is the main code:
import MainMod
print("Welcome!")
print("Note: In this games you use wasd+enter to move!\nYou press 1 key and then enter,if you press multiple kets it wont work.\nYou will always move by 5 meters.")
CurrentRoom = 1
#Limits work this way!1st and 2nd number are X values(1st is <---- limit,2nd is ---> limit)
#3rd and 4th are y values(1st is v limit,2nd is ^ limit)
# X and Y are coordinates; 0,0 is the starting point of every room
while True:
if CurrentRoom ==1:
print("This is room 1")
MainMod.roomlimits = [-15 , 15, -15 , 15]
MainMod.doorloc1 = [-15,10,15]
MainMod.doorloc2 = [15,-2,2]
while CurrentRoom == 1:
MainMod.MainLel()
if MainMod.door1 == 1:
print("DAMN SON")
CurrentRoom = 2
break
elif MainMod.door2 == 1:
print("Plz no")
CurrentRoom = 3
break
while CurrentRoom == 2:
MainMod.MainLel()
and this is the MainMod module is :
x = 0
y = 0
roomlimits = 0
doorloc1=0
doorloc2=0
door1 = 0
door2 = 0
direct = 0
def MainLel():
global direct
movementinput()
movement(direct)
doorcheck()
def movement(dir):
global x,y,roomlimits,door1,door2,doorloc1,doorloc2
if dir == "w":
y += 5
if y > roomlimits[3]:
y = roomlimits[3]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "s":
y -= 5
if y < roomlimits[2]:
y = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "d":
x += 5
if x > roomlimits[1]:
x = roomlimits[1]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "a":
x -= 5
if x < roomlimits[0]:
x = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
def movementinput():
global direct
while True:
direct = input("")
if direct in ("w","a","s","d","W","A","D","S"):
break
else:
print("You failure.")
def doorcheck():
global x,y,doorloc1,doorloc2,door1,door2
if x == doorloc1[0] and doorloc1[1] <= y <= doorloc1[2]:
door1 = 1
elif y == doorloc2[0] and doorloc2[1] <= x <= doorloc2[2]:
door2 = 1
else:
door1,door2 = 0,0
Im using a module instead of classes because i dont know how to use classes yet,anyways,what happens in the program is that if i am in the door location,it simply prints "DAMN SON" and doesnt break out of the Room loop,any help? EDIT NOTE: I added the break statement later on to try if it would help,sadly it didnt,i am also a bit tired so im guessing i made a logic mistake somewhere,thanks in advance for help.
Final edit: The code was functional all along,i was just testing it incorrectly!Thanks for the awnsers,ill close this question now.
Since I could not imagine it didn't work, I added two markers (print commands), to room 1 and 2:
while CurrentRoom == 1:
print("one")
mod.MainLel()
and
while CurrentRoom == 2:
print("two")
mod.MainLel()
This is what happened:
Youre current coordinates are x: -5 y: 15
one
a
Youre current coordinates are x: -10 y: 15
one
a
Youre current coordinates are x: -15 y: 15
DAMN SON
two
a
Youre current coordinates are x: -15 y: 15
two
It turned out to be working fine. The break is redundant however. The loop will break anyway, since the condition becomes False.

Python: If condition appears to be met but isn't triggering

I know this seems like it should be very simple, but at this point I'm at my wit's end trying to figure this out. I've coded up a calculator in python, but for some reason the ending if-else statement is only firing the else segment.
import sys
import re
#setting values
x = 0
n = '+'
y = 0
#valid input flag
valid = True
#continue operations flag
run = True
again = "k"
#addition function
def add(x, y):
return x + y
#subtraction function
def subtract(x, y):
return x - y
#multiplication function
def multiply(x, y):
return x * y
#division function
def divide(x, y):
return x / y
#continuation loop
while run == True:
#Prompt for and accept input
equation = raw_input("Please insert a function in the form of 'operand' 'operator' 'operand' (x + y): ")
equation.strip()
#Divide input into 3 parts by spaces
pieces = re.split('\s+', equation)
#set part 1 = x as float
x = pieces[0]
try:
x = float(x)
except:
print "x must be a number"
valid = False
#set part 2 = operator
if valid == True:
try:
n = pieces[1]
except:
print "Please use valid formating (x [] y)."
valid = False
#set part 3 = y as float
if valid == True:
y = pieces[2]
try:
y = float(y)
except:
print "y must be a number"
valid = False
#If input is valid, do requested calculations
while valid == True:
if n == '+' :
print equation + " =", add(x,y)
elif n == '-' :
print equation, " =", subtract(x,y)
elif n == '*' :
print equation, "*", y, " =", multiply(x,y)
elif n == '/' :
if y == 0:
print "You cannot divide by zero."
else:
print equation, " =", divide(x,y)
else:
print "Please use an appropriate operator ( + - * / )."
#play again
again = raw_input("Play again? ")
print again
if again == ("yes", "y", "YES", "Yes","yes"):
run = True
print "yes'd"
else:
print "no'd"
run = False
When I run this code, I get two different problems:
If I enter a valid input (ie: 2 + 2), then my output is
"2 + 2 = 4.0"
"2 + 2 = 4.0"
"2 + 2 = 4.0"
repeating forever.
If I enter an invalid input, I get the "Play again? " Prompt, but
no matter what I enter, the else statement fires.
(for instance, in the case that I enter "yes" into "Play again? ", it will print:
"yes" (<-- this is from "print again" line )
"no'd" (<-- this is from "else: print "no'd" )
I dont know how to solve either of these problems at this point, so any help would be greatly appreciated.
Edit: Thank you everyone, I wish I could check mark all of you for helping me understand different things about what I did wrong.
In while valid == True:, you never change the value of valid, so it's always True and the loop is infinite. I don't see why it's even a loop - change it to if like the blocks above it and it will behave as expected.
Also, in if again == ("yes", "y", "YES", "Yes","yes"):, change == to in and it will behave as expected.
Perhaps you should replace this code:
while valid == True:
if n == '+' :
print equation + " =", add(x,y)
elif n == '-' :
print equation, " =", subtract(x,y)
elif n == '*' :
print equation, "*", y, " =", multiply(x,y)
elif n == '/' :
if y == 0:
print "You cannot divide by zero."
else:
print equation, " =", divide(x,y)
else:
print "Please use an appropriate operator ( + - * / )."
With this...
if valid:
Or...
while valid == True:
# Insert your previous code here.
break
You could also just simply set valid to false at the bottom of your loop too. That would work.
I think valid is constantly true in this case. You have also written while valid is true, which means it will keep iterating over the loop until valid is equalled to false. It appears that within this block of code in the while loop, valid isn't switched to false.
while valid == True: should probably be if valid == True
and for your second problem:
if again == ("yes", "y", "YES", "Yes","yes"): should probably be:
again = again.lower();
if again == "yes" or again == "y":
Your answer is looping because of
while valid == True:
Replace the loop with the if statement
You get "no'd" because of
if again == ("yes", "y", "YES", "Yes", "yes"):
Here you are equating string with a tuple, instead of checking whether the string is contained within a tuple. Try this instead:
if again in ("yes", "y", "YES", "Yes""):

Python simple project not quite working

# program to test truth tables v2
import time
import sys
x = 0
while x == 0:
x = str(raw_input("Please enter True or False..."))
x = x[0].upper()+ x[1:]
if x == "True":
x = True
elif x == "False":
x = False
else:
print 'invalid input!'
x = 0 # very difficult but this works now!
print x
y = 0
while y == 0:
y = str(raw_input("Please enter True or False again..."))
y = y[0].upper()+ y[1:]
if y == "True":
y = True
elif y == "False":
y = False
else:
print 'invalid input!'
y = 0
problem = 0
while problem == 0:
problem = input("Please enter number: \n1 for AND, 2 for OR, 3 for NAND, 4 for NOR...")
if problem == 1:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1.0)
print x, "AND", y, "is", x and y
elif problem == 2:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "OR", y, "is", x or y
elif problem == 3:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "NAND", y, "is", not(x and y) # not working for false/false or false/true
elif problem == 4:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(0.5)
print x, "NOR", y, "is", not(x or y) # not working for false/false
else:
print 'invalid input'
problem = 0
I thought this project worked then once I had tested all the combos, I found that there is a problem with the elif in the first while loop. See the comments in the last section. Any help gratefully received
The problem in your first while loop is that 0 == False. Toss that in the interpreter and see.
Here's my guess. You need to turn your booleans into strings. For example, in the first while loop, you set x equal to True and False instead of "True" and "False." Because Python sees booleans True and False as 1 and 0, respectively, your while loop variables (x and y) remain equal to zero in the case of False. It's likely causing you to repeat whenever the user inputs False
Try it and see. Let me know. And whatever you do, keep practicing!! You'll get it.
EDIT: Yep that was the problem. Here's your working code.
import time
import sys
x = 0
while x == 0:
x = str(raw_input("Please enter True or False..."))
#x = x[0].upper()+ x[1:]
print "THIS IS X: {}".format(x)
if x == "True":
x = "True"
elif x == "False":
x = "False"
else:
print 'invalid input!'
x = 0 # very difficult but this works now!
print x
y = 0
while y == 0:
y = str(raw_input("Please enter True or False again..."))
y = y[0].upper()+ y[1:]
if y == "True":
y = "True"
elif y == "False":
y = "False"
else:
print 'invalid input!'
y = 0
problem = 0
while problem == 0:
problem = input("Please enter number: \n1 for AND, 2 for OR, 3 for NAND, 4 for NOR...")
if problem == 1:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1.0)
print x, "AND", y, "is", x and y
elif problem == 2:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "OR", y, "is", x or y
elif problem == 3:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "NAND", y, "is", not(x and y) # not working for false/false or false/true
elif problem == 4:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(0.5)
print x, "NOR", y, "is", not(x or y) # not working for false/false
else:
print 'invalid input'
problem = 0
The other posters have it right -- Python sees 0 and False as the same thing, at least truth-wise. We humans know that they are not the same thing type-wise, of course, and you can force Python to tell the difference by using "is" instead of "==", so the line should become...
while y is 0: # <-- change that line there
y = str(raw_input("Please enter True or False again..."))
y = y[0].upper()+ y[1:]
This is a "strict comparison" that compares both the value (which Python thinks are the same) and type (False is a Boolean, 0 is a Number)

Categories

Resources