if statements with while loops - python

I want to make it that after 10 sec you get and random letter of an random word and that the timer starts again like an infinite loop. Here is my code:
words = ["graveyard","church","apple","tree","crispy","air"]
hidden_word = random.choice(words)
hint = random.sample(hidden_word,1)
timer = 0
if timer == 10:
print(hint)
else:
while timer < 10:
timer = timer + 1
time.sleep(1)
print(timer)
I tried to place the if statement in the while loop but didn't work it only gave me errors

This will do what you described, but it will never stop:
import time
import random
words = ["graveyard","church","apple","tree","crispy","air"]
hidden_word = random.choice(words)
hint = random.sample(hidden_word,1)
def random_select():
while True:
time.sleep(10)
print(hint)
random_select()

Related

Why my thread doesn't stop after function finished?

So I wrote this script, which counts income packets on certain port, and in case if there are to many packets script has to do something. On the first received packet is has to start timer, and if timer reaches 60 sec, packet count should start from 0 again. It works, but only for first timer call, in any case, if script has to start timer again I get the error:
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once"`
It's clear, that this thread still running, but i don't understand why. I mean, in case if timer reaches 60 secs, timer loop is finished, and function should be finished too, so i can use timer again? Clearly i don't understand something here, can you guys explain it? Thanks for answers
My code:
from scapy.all import *
from threading import Thread
import time
global count
count = 0
def timer():
global count
i = 0
while i < 60:
if count > 0:
time.sleep(1)
i = i + 1
print(str(count))
else:
print("count is 0, timer turning off...")
break
else:
count = 0
print("60 seconds, timer is off")
background_thread = Thread(target=timer)
def pkt_callback(pkt):
global count
packet_limit = 10
if pkt.haslayer(UDP) and pkt.getlayer(UDP).dport == 5160 and pkt.haslayer(Raw):
raw = pkt.getlayer(Raw).load
s = str(raw)
if 'REGISTER' in s:
count += 1
print(count)
if count == 1:
if background_thread.is_alive() is False:
background_thread.start()
print("Register packet detected, timer is on")
if count >= packet_limit:
print("PACKETLIMIT reached, do smth")
count = 0
sniff(iface='ens160', filter="", prn=pkt_callback)
I think you have to use the return function not break, and either way you have only used it once, also you can change your code a bit, try this:
def timer():
global count
i = 0
while i < 60:
if count != 0:
time.sleep(1)
i += 1
print(str(count))
else:
return "count is 0, timer turning off..."
else:
count = 0
return "60 seconds, timer is off"

math quiz with a time limit (simultaneous functions) - advanced python

So I would like to run two programs, a timer and a math question. But always the input seems to be stopping the timer funtion or not even run at all. Is there any ways for it to get around that?
I'll keep the example simple.
import time
start_time = time.time()
timer=0
correct = answer
answer = input("9 + 9 = ")
#technically a math question here
#so here until i enter the input prevents computer reading the code
while True:
timer = time.time() - start_time
if timer > 3:
#3 seconds is the limit
print('Wrong!')
quit()
So recap i would like the player to answer the question in less than 3 seconds.
after the 3 seconds the game will print wrong and exit
if the player answer within three seconds the timer would be 'terminated' or stopped before it triggers 'wrong' and quit
hope you understand, and really appreciate your help
On Windows you can use the msvcrt module's kbhit and getch functions (I modernized this code example a little bit):
import sys
import time
import msvcrt
def read_input(caption, timeout=5):
start_time = time.time()
print(caption)
inpt = ''
while True:
if msvcrt.kbhit(): # Check if a key press is waiting.
# Check which key was pressed and turn it into a unicode string.
char = msvcrt.getche().decode(encoding='utf-8')
# If enter was pressed, return the inpt.
if char in ('\n', '\r'): # enter key
return inpt
# If another key was pressed, concatenate with previous chars.
elif char >= ' ': # Keys greater or equal to space key.
inpt += char
# If time is up, return the inpt.
if time.time()-start_time > timeout:
print('\nTime is up.')
return inpt
# and some examples of usage
ans = read_input('Please type a name', timeout=4)
print('The name is {}'.format(ans))
ans = read_input('Please enter a number', timeout=3)
print('The number is {}'.format(ans))
I'm not sure what exactly you have to do on other operating systems (research termios, tty, select).
Another possibility would be the curses module which has a getch function as well and you can set it to nodelay(1) (non-blocking), but for Windows you first have to download curses from Christopher Gohlke's website.
import time
import curses
def main(stdscr):
curses.noecho() # Now curses doesn't display the pressed key anymore.
stdscr.nodelay(1) # Makes the `getch` method non-blocking.
stdscr.scrollok(True) # When bottom of screen is reached scroll the window.
# We use `addstr` instead of `print`.
stdscr.addstr('Press "q" to exit...\n')
# Tuples of question and answer.
question_list = [('4 + 5 = ', '9'), ('7 - 4 = ', '3')]
question_index = 0
# Unpack the first question-answer tuple.
question, correct_answer = question_list[question_index]
stdscr.addstr(question) # Display the question.
answer = '' # Here we store the current answer of the user.
# A set of numbers to check if the user has entered a number.
# We have to convert the number strings to ordinals, because
# that's what `getch` returns.
numbers = {ord(str(n)) for n in range(10)}
start_time = time.time() # Start the timer.
while True:
timer = time.time() - start_time
inpt = stdscr.getch() # Here we get the pressed key.
if inpt == ord('q'): # 'q' quits the game.
break
if inpt in numbers:
answer += chr(inpt)
stdscr.addstr(chr(inpt), curses.A_BOLD)
if inpt in (ord('\n'), ord('\r')): # Enter pressed.
if answer == correct_answer:
stdscr.addstr('\nCorrect\n', curses.A_BOLD)
else:
stdscr.addstr('\nWrong\n', curses.A_BOLD)
if timer > 3:
stdscr.addstr('\nToo late. Next question.\n')
if timer > 3 or inpt in (ord('\n'), ord('\r')):
# Time is up or enter was pressed; reset and show next question.
answer = ''
start_time = time.time() # Reset the timer.
question_index += 1
# Keep question index in the correct range.
question_index %= len(question_list)
question, correct_answer = question_list[question_index]
stdscr.addstr(question)
# We use wrapper to start the program.
# It handles exceptions and resets the terminal after the game.
curses.wrapper(main)
Use time.time(), it returns the epoch time (that is, the number of seconds since January 1, 1970 UNIX Time). You can compare it to a start time to get the number of seconds:
start = time.time()
while time.time() - start < 60:
# stuff
You can have a timer pull you out of your code at any point (even if the user is inputting info) with signals but it is a little more complicated. One way is to use the signal library:
import signal
def timeout_handler(signal, frame):
raise Exception('Time is up!')
signal.signal(signal.SIGALRM, timeout_handler)
This defines a function that raises an exception and is called when the timeout occurs. Now you can put your while loop in a try catch block and set the timer:
signal.alarm.timeout(60)
try:
while lives > 0
# stuff
except:
# print score

How do I run one def function inside of a different def function in python?

I'm trying to run a timer inside of a function of my code. I need to start the timer slightly before the user starts typing, then stop the timer when the user has entered the alphabet correctly.
Here is my code:
import time
timec = 0
timer = False
print("Type the alphabet as fast as possible.\nYou MUST be accurate!\nYou will be timed")
timer = True
attempt = input("The timer has started!\nType here: ")
while timer == True:
time.sleep(1)
timec = timec +1
if attempt == "abcdefghijklmnopqrstuvwxyz":
timer = False
print("you completed the alphabet correctly in", timec,"seconds!")
else:
print("There was a mistake! \nTry again: ")
The issue is that it will not let me enter the alphabet. In previous attempts of this code (Which I do not have) i have been able to enter the alphabet, but the timer would not work. Any help is appreciated
import time
start = time.time()
attempt = input("Start typing now: ")
finish = time.time()
if attempt == "abcdefghijklmnopqrstuvwxyz":
print "Well done, that took you %s seconds.", round(finish-start, 4)
else:
print "Sorry, there where errors."
Think carefuly about that you are dong
You ask for a user-entered string
While timer equals True, you sleep for one second and increase the count. In this loop, you do not change the timer.
Obviously, once user stopped entering the alphabet and pressed enter, you start an infinite loop. Thus, nothing seems to happen.
As other answers suggested, the best solution would be to save the time right before prompting user to enter the alphabet and compare it to the time after he finished.
you could do something like:
import datetime
alphabet = 'abcdefghijklmnopqrstuvwxyz'
print('Type the alphabet as fast as possible.\nYou MUST be accurate!\nYou will be timed"')
init_time = datetime.datetime.now()
success_time = None
while True:
user_input = input('The timer has started!\nType here: ')
if user_input == alphabet:
success_time = datetime.datetime.now() - init_time
break
else:
continue
print('you did it in %s' % success_time)

I don't understand why my function doesn't happen

I am trying to write a typing challenge game where the player has to type a word as fast as possible within the time limit. At the end of the game() function it is supposed to execute the round1() function when the timer gets to 0. However, nothing happens and it just stays on the number 1. Any ideas what is causing this behavior?
This is the code I am using:
import random
import time
global timer
timer = 20
global counting
counting = 10
global rounds
rounds = 0
def menu():
print ("Main Menu\nType in 'start' to begin the typing challenge")
start = input()
if start == "start":
game()
else:
menu()
def game():
global counting
choices = ["snazzy", "pizzas", "sizzle", "jackal"]
global word
word = (random.choice(choices))
print ("The word you must type is", word)
print ("You will be timed on how long it takes you to type the word.")
print ("Each round you will have a slightly smaller amount of time to type the word")
time.sleep(10)
print ("Starting in...")
for count in range(10):
print (counting)
time.sleep(1)
counting -=1
round1()
def round1():
useless = 100
global rounds
global word
global timer
while useless > 1:
for count in range(20):
time.sleep(1)
timer -=1
print ("Type", word)
attempt = input()
if attempt == word and timer > 0:
rounds = rounds+1
round2()
else:
lose()
You are getting into the function round1, but once you are there, you are caught in an infinite loop because the variable useless will never change.
Even if you take out the while loop, you will never be able to win because you do not take input in until after the timer has already run out.
Try this code from round 1 on:
def round1():
import sys, select
global rounds
global word
global timer
print ("Type", word)
input, out, error = select.select( [sys.stdin], [], [], timer)
if (input):
attempt = sys.stdin.readline().strip()
if attempt == word:
rounds = rounds+1
round2()
else:
lose()
else:
lose()
if __name__ == '__main__':
menu()
Note that, as-is, it will fail with a NameError since you don't have a round2() function defined. A better solution would be to generalize your function, with something like round_x(number, word, time_to_answer); That way you can reuse the same code and don't have to import globals.
I was playing a bit with your game you're doing too many overhead and mistakes
there so I just changed it's structure to simplify:
import random
import time
current_milli_time = lambda:int(time.time() * 1000)
timer = 20 #suppose user has 20 secs to enter a word
counting = 10
requested_word = ""
choices = ["snazzy", "pizzas", "sizzle", "jackal"]
rounds = 0
def menu():
print ("Main Menu\nType in 'start' to begin the typing challenge")
game() if input().lower() == "start" else menu()
#There is no need to split game and round but I didn't want to mess with
#your program structure too much
def game():
global requested_word
try:
requested_word = (random.choice(choices))
choices.remove(requested_word)
except IndexError:
print "Game is finished"
return
print ("The word you must type is", requested_word)
print ("You will be timed on how long it takes you to type the word.")
print ("Each round you will have a slightly smaller amount of time to type the word")
print ("Starting typing in in...")
for count in range(10,-1,-1):
print (count)
time.sleep(1)
round()
def round():
global timer
start = current_milli_time()
word = input("Enter word -> ")
stop = current_milli_time()
time_delta = stop-start #this is in milliseconds
if time_delta< timer*1000 and word == requested_word :
timer = timer-5 #lower the time to enter a word
game()
else:
print("Game OVER")
menu()
When prompt 'Enter word ->' appears the user has all the time he wants to enter a word, but after it time_delta is calculated and if it passes your limit, it's game over for him.

Python time limit

I have a homework assignment to do and I really need a solution. I have been trying to do this since yesterday but I do not know how.
Program has to generate and print a letter or a number and then a user has to type it as quickly as possible and press ENTER. The game is over after 30 secs.
Well I do not know how to put time limit to a game. I was searching through stackoverflow and I did not find anything useful. Please help me.
**Here it is what I have done so far. I tried code from the answer by SYSS.STDER, but it does not quite work because when the 30 secs are over, the game should also be over, but here in this code the game is over when I type last character.
LOOP WILL NOT STOP UNTIL IT FINISHES AND WE DISCOVER THAT WE ARE PAST OUR DEADLINE. THE TASK NEEDS TO BE INTERRUPTED IN PROGRESS AS SOON AS THE TIME ELAPSES.
max_time =30
start_time = time.time() # remember when we started
while (time.time() - start_time) < max_time:
response = "a" # the variable that will hold the user's response
c = "b" #the variable that will hold the character the user should type
score = 0
number = 0
c = random.choice(string.ascii_lowercase + string.digits)
print(c)
number = number + 1
response = input("Type a letter or a number: ") #get the user's response
if response == c and (time.time() - start_time) < max_time:
# if the response from the previous loop matches the character
# from the previous loop, increase the score.
score = score + 1
Here's my way to do it:
import string
import random
import time
response = "a" # the variable that will hold the user's response
c = "b" #the variable that will hold the character the user should type
score = 0 #the variable that will hold the user's score
start = time.time() #the variable that holds the starting time
elapsed = 0 #the variable that holds the number of seconds elapsed.
while elapsed < 30: #while less than 30 seconds have elapsed
if response == c: #if the response from the previous loop matches the character
score += 1 #from the previous loop, increase the score.
#c is a random character
c = random.choice(string.ascii_lowercase + string.digits)
print(c)
response = input("Type a letter or a number: ") #get the user's response
elapsed = time.time() - start #update the time elapsed
Since you're using Windows you can use the msvcrt.kbhit function to check for keypresses inside timing loops:
import msvcrt #### windows only ####
import os
import random
import string
import time
max_time = 15
def readch(echo=True):
"Get a single character on Windows"
ch = msvcrt.getch()
while ch in b'\x00\xe0': # special function key?
msvcrt.getch() # get keycode & ignore
ch = msvcrt.getch()
if echo:
msvcrt.putch(ch)
return ch.decode()
def elapsed_time():
global start_time
return time.time() - start_time
number = 0
score = 0
start_time = time.time() # initialize timer
while elapsed_time() < max_time:
c = random.choice(string.ascii_lowercase + string.digits)
print(c, end='')
number += 1
print("Type a letter or a number: ", end='')
while elapsed_time() < max_time:
if not msvcrt.kbhit():
time.sleep(0.1) # don't hog processor
else:
response = readch(echo=False) # get the user's response
if response == c:
print(response) # only print if correct
score += 1
break
else:
print()
print()
print("Time's up")
print("You go {} out of {}:".format(score, number))
A sample program to exit prime number function when Time limit has exceeded.
import math
from time import time
start_time = time()
max_time = 2
def prime(n):
for i in range(2, int(math.sqrt(n))):
if(time() - start_time) > max_time:
return "TLE"
if n % i == 0:
return False
return True
print(prime(3900000076541747077))
use "timeit" module available in python for better result.

Categories

Resources