This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 5 years ago.
I was trying to make a simple timer and countdown in python, but for the first question, where you pick either timer or countdown, no matter what you type, it gives you the timer instead of countdown. How do i change this?
import time
def resetVar():
x = input("Timer or countdown?:")
minsum = int(input("How long do you want the timer to go?: "))
reminder = int(input("How often do we notify you in minutes?: "))
mins = 0
countminsum = 0
mins = 0
x = input("Timer or countdown?:")
if(x == "Timer" or "timer"):
minsum = int(input("How long do you want the timer to go?: "))
reminder = int(input("How often do we notify you in minutes?: "))
print("Countdown has started.")
while mins != minsum:
time.sleep(reminder * 60)
mins += reminder
print(str(reminder) + " Minute(s) have passed")
if mins == minsum:
print("timer has ended")
resetVar()
print(x)
if(x == "Countdown" or "countdown"):
countminsum = int(input("How long shout the countdown go for?: "))
remider = int(input("How often should we notify you how much time is left? (in minutes): "))
print ("countdown has started")
while countminsum != mins:
time.sleep(remider * 60)
countminsum -= remider
printe(str(remider) + " Minute(s) have passed.")
if countminsum == 0:
print ("Countdown has ended.")
resetVar()
print (x)
You can't check if x is timer or Timer like that, as it evaluates to x == 'Timer', ("Timer" or "timer" == 'Timer'), instead you can say x in ['timer', 'Timer'].
The same goes for countdown.
Related
I created a small app where the user can add number of instances and then add arbitrary numbers, making it all end up in a pandas df. However, attempting to challenge the user doing aforementioned process, the user ends up being able to complete the process of adding values. This should stop abruptly, if time deadline is not met.
Try run the code yourself:
import time
import pandas as pd
# define the countdown func.
def countdown(t):
while t:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
a = int(input("Enter number of instances: "))
test3 = []
i = 0
while i < a:
pl = int(input("Enter arbitrary integer: "))
test3.append(pl)
i += 1
print(list(test3))
DF1 = pd.DataFrame(test3)
return DF1
time.sleep(1)
t -= 1
print('Game over')
# input time in seconds
t = input("Enter the time in seconds: ")
# function call
print(countdown(int(t)))
I'd suspect that I am missing an if-statement, but that is potentially what I need help doing or...?
Any help is appreciated...thx
EDIT:
import pandas as pd
from threading import Timer
timeout = 8
t = Timer(timeout, print, ['Game over'])
t.start()
prompt = "You have %d seconds to choose the correct answer...\n" % timeout
answer = input(prompt)
a=int(input("Enter number of instances: "))
test3=[]
i=0
while i < a:
pl=int(input("Enter arbitrary integer "))
test3.append(pl)
i+=1
print(list(test3))
DF1 = pd.DataFrame(test3)
print(DF1)
t.cancel()
I'm creating a simple program to take in time and distance to then state the speed, but I want to do this with classes to learn about oop in python. I'm not figuring out how to set the loop to keep going until the user decides to not go again.
y=True
while y:
class Timer:
def __init__(self,speed):
self.speed=speed
def log(self):
print(mph)
again=input('Go again? y or n: ')
if again=='y':
y=True
else:
print('Thank you')
y=False
m=float(input('Enter the minutes: '))
s=float(input('Enter the seconds: '))
d=float(input('Enter distance: '))
x=(m*60)+s
x_tot=(x/3600)
mph=d/x_tot
t=Timer(mph)
t.log()
You need following code:
y=True
while y:
class Timer:
def __init__(self,speed):
self.speed=speed
def log(self):
print(mph)
global y
again=input('Go again? y or n: ')
if again=='y':
y=True
else:
print('Thank you')
y=False
if y:
m=float(input('Enter the minutes: '))
s=float(input('Enter the seconds: '))
d=float(input('Enter distance: '))
x=(m*60)+s
x_tot=(x/3600)
mph=d/x_tot
t=Timer(mph)
t.log()
else:
break
The y variabel inside log function should be global else it won't change global y referred inside if-else. We need if-else with y so that we can break out of loop if user chooses n. The t=Timer(mph) has to be inside while loop because class is not known outside the loop. Same applies for t.log function call.
Honestly to make your code easier to debug and track where changes are occuring, you should pull the class out of the loop and then reference it inside the loop when you need to use it.
In the init, I would pull out the assignment of the speed variable and just initialize it as none.
def __init__(self):
self.speed = None
Then you can add a separate private setter function to set the speed with user input and do error checking around it. Note, I have set the program to exit with a 0 code if the user inputs something wrong, but you can easily make another loop here that will wait until the user finally does input valid values for all the inputs. The __ double underscore in front of the function name makes it private to the class.
def __set_mph(self):
try:
m = float(input('Enter the minutes: '))
s = float(input('Enter the seconds: '))
d = float(input('Enter distance: '))
x = (m * 60) + s
x_tot = (x / 3600)
self.mph = d / x_tot
except (ValueError, ArithmeticError) as e:
print(f'Invalid user input: {e}')
exit(0)
except Exception as e:
print(f'Unexpected error: {e}')
exit(0)
Now you can update the log function to not even worry about the y variable by changing it to this:
def log(self):
self.__set_mph()
print(mph)
again = input('Go again? y or n: ')
if again == 'y':
return True
else:
print('Thank you')
return False
Now we just initialize the class before the loop and clean it up to be make it more manageable.
t = Timer()
while True:
if not t.log():
break
Final Code:
class Timer:
def __init__(self):
self.speed = None
self.mph = None
def __set_mph(self):
try:
m = float(input('Enter the minutes: '))
s = float(input('Enter the seconds: '))
d = float(input('Enter distance: '))
x = (m * 60) + s
x_tot = (x / 3600)
self.mph = d / x_tot
except (ValueError, ArithmeticError) as e:
print(f'Invalid user input: {e}')
exit(0)
except Exception as e:
print(f'Unexpected error: {e}')
exit(0)
def log(self):
self.__set_mph()
print(self.mph)
again = input('Go again? y or n: ')
if again == 'y':
return True
else:
print('Thank you')
return False
t = Timer()
while True:
if not t.log():
break
OOP is all about modeling your real world objects into programmatic objects that maintain the features and functionality of the real world object to its programatic counterpart's attributes and features, respectively.
Also, those objects should be separated on its own. Creating and calling a class from within a while loop is pretty bad practice. I would encourage you to separate the code based on its purpose. for example, I would have a file called timer.py to handle the Object that matches the timer like so:
# The timer class
class Timer:
def calculate_speed(self, minutes, seconds, distance):
hours = (minutes * 60) + seconds
tot_time = (hours / 3600)
return distance / tot_time
def get_speed(self):
minutes = float(input('Enter the minutes: '))
seconds = float(input('Enter the seconds: '))
distance = float(input('Enter distance: '))
return self.calculate_speed(minutes, seconds, distance)
Then in your main file:
from timer import Timer
timer = Timer()
while True:
user_response = input('Go again? y or n: ').lower()
if user_response == 'n':
break
elif user_response == 'y':
speed = timer.get_speed()
print(f'Your speed is {speed}')
else:
print('Not a valid response')
This makes it easier on the backend too. In other words, if you have an error that relates to the calculations, you know where to start looking.
import random
import time
num_questions = 10
score = 0
print('''
Welcome to the math quiz.
You will have 3 tries and 8 seconds to answer each question.
Good luck.
''')
time.sleep(3)
for question_num in range(num_questions):
max_chances = 3
current_chances = 0
num1 = random.randint(0, 9)
num2 = random.randint(0, 9)
correct_answer = num1 * num2
while current_chances < max_chances:
current_chances += 1
user_answer = input('#%s: %s * %s = ' % (question_num+1, num1, num2))
if int(user_answer) == correct_answer:
print('Correct.')
break
else:
if current_chances == max_chances:
print('Out of tries. Please wait for the next question.')
time.sleep(1)
else:
print('Not quite. Try again.')
continue
I have this program that asks 10 math questions with 3 tries per question. This is for a practice project I am doing from Automate the Boring Stuff with python in which the directions read:
To see how much PyInputPlus is doing for you, try re-creating the multiplication quiz project on your own without importing it. This program will
prompt the user with 10 multiplication questions, ranging from 0 × 0 to
9 × 9. You’ll need to implement the following features:
• If the user enters the correct answer, the program displays “Correct!”
for 1 second and moves on to the next question.
• The user gets three tries to enter the correct answer before the
program moves on to the next question.
• Eight seconds after first displaying the question, the question is
marked as incorrect even if the user enters the correct answer after
the 8-second limit.
I believe I've met all the requirements besides the 8-second limit. I'm not exactly sure how to implement this into my code. The book has not yet introduced asyncio or threading, some of the ideas friends of mine have suggested, and I'm not exactly sure what other way I could implement a sort of timer to this program. Would anyone be able to help? Thank you.
I think there is no way of doing this without creating another thread for timer. Because you have to do two processes(timer and input) at once.
I think threading.Timer useful for your case. It is easy. Firstly, you have to create a timer :
t = threading.Timer(8,print,["Your time is up"])
Timer with timeout of 8 seconds, when it ends, it will print specified message.
Then, you have to start your timer just before input. After input, you can cancel your timer. So your input statement will be like this :
timer = threading.Timer(8,print,["Your time is up"]) # creating timer
timer.start() # starting timer
user_answer = input('#%s: %s * %s = ' % (question_num+1, num1, num2))
timer.cancel() # cancelling
Note : When 'your time is up' message appears input still goes on, it just prints the message. There are ways to terminate it too, but they are more complicated and OS dependent.
Check this answer.
Your code will be like this :
for question_num in range(num_questions):
max_chances = 3
current_chances = 0
num1 = random.randint(0, 9)
num2 = random.randint(0, 9)
correct_answer = num1 * num2
while current_chances < max_chances:
current_chances += 1
timer = threading.Timer(8,print,["Your time is up"]) # creating timer
timer.start() # starting timer
user_answer = input('#%s: %s * %s = ' % (question_num+1, num1, num2))
timer.cancel() # cancelling
# user_answer likely to be empty, but, still user could write something,
# because we are not terminating input process, just printing a message.
if user_answer == ""
if int(user_answer) == correct_answer:
print('Correct.')
break
else:
if current_chances == max_chances:
print('Out of tries. Please wait for the next question.')
time.sleep(1)
else:
print('Not quite. Try again.')
continue
I am trying to code a chess timer in which there are two timers counting down alternatingly. Only one timer runs at a time, and when a certain input is given by the user, which I am using keyboard.is_pressed("some_key") for, one timer pauses and the other begins counting down and vice versa. My problem is that to countdown by intervals of 1 second, I am using time.sleep(1) and the program will not receive user input during this time, so unless the user gives input on exactly the 1 second mark, nothing happens. How can I make the countdown process and the checking for user input process run at the same time?
Here is the code:
import time
import keyboard
def timers(t1, t2):
pause = True
while t1 or t2:
if pause:
while pause:
mins1 = t1 // 60
secs1 = t1 % 60
timer1 = '{:02d}:{:02d}'.format(mins1, secs1)
print("Timer1: ", timer1)
time.sleep(1)
t1 -= 1
if keyboard.is_pressed("w"):
pause = False
break
else:
continue
else:
while not pause:
mins2 = t2 // 60
secs2 = t2 % 60
timer2 = '{:02d}:{:02d}'.format(mins2, secs2)
print("Timer2: ", timer2)
time.sleep(1)
t2 -= 1
if keyboard.is_pressed("w"):
pause = True
break
print("Beep")
tWhite = int(input("Enter the time in seconds for White: "))
tBlack = int(input("Enter the time in seconds for Black: "))
timers(tWhite, tBlack)
so i am trying to figure this out for school. Im trying to print x out every minute and every ten min it will print on a new line. so far i cant get the "printing x" every min down. can someone please help.
this is my code
import time;
inTime = float(input("type in how many second"))
oldTime = time.time()-inTime
print (time.time())
def tenMin(oldTime):
newTime = time.time()
if ((newTime - oldTime)>= 25):
return True
else:
False
while (True):
if (tenMin==True):
print ("x")
newTime = time.time()
oldtime = time.time()
else:
oldTime = time.time()
continue
Your first problem is in the line
if (tenMin==True):
You compare a function reference to a boolean, clearly the answer would be False. You have to pass a parameter
if (tenMIn(oldTime)):
...
First you have some issues with you code:
else:
False - This is not true syntax in python.
If you want timer, why are you asking the user for input?
You have a logic problem:
inTime = float(input("type in how many second"))
oldTime = time.time()-inTime
time.time is float yes, but can a user really know what to print in UnixTime?
I'll suggest a simple solution it's not the very best but it works.
It will print "x" every 1 Min and after 10 Min it will print "\n" (new line)
import time
def main():
#both timers are at the same start point
startTimerTen = time.time()
startTimerMin = startTimerTen
while True:
getCurrentTime = time.time()
if getCurrentTime - startTimerTen >= 600:
# restart both parameters
startTimerTen = getCurrentTime
startTimerMin = getCurrentTime
print "This in 10 min!\n"
if getCurrentTime - startTimerMin >= 60:
# restart only min parameter
startTimerMin = getCurrentTime
print "x"
#end of main
if __name__ == "__main__":
main()