Python loop just keep going - python

I'm making a dart score keeper but it just keeps going round and round. I just need some help as to why this is.
The code:
import time
import sys
from sys import argv
script, name1, name2 = argv
def dartscore():
print "Play from 501 or 301?"
threeorfive = int(raw_input())
if (threeorfive == 501):
def playerone():
startnum1 = threeorfive
while (startnum1 > 0):
print "Ready ", name1,"?"
print "Please enter your score."
minusnum1 = int(raw_input())
startnum1 = startnum1 - minusnum1
playertwo()
if (startnum1 == 0):
print "Well done! You win!"
elif (startnum1 < 0):
print "Sorry but you have entered a wrong score"
playertwo()
def playertwo():
startnum2 = threeorfive
print "Ready ", name2,"?"
print "Please enter your score."
minusnum2 = int(raw_input())
startnum2 = startnum2 - minusnum2
if (startnum2 == 0):
print "Well done! You win!"
print "Unlucky ", name1,". Well played though."
sys.exit()
if (startnum2 < 0):
print "Sorry but you have entered an incorrect score. Please try again"
startnum2 += minusnum2
playerone()
playerone()
dartscore()
Now the two functions playerone() and playertwo() are different because I was trying something with the playerone() function to see if that solved my problem.

Well you have a while(startnum1 > 0):. It seems like startnum1is always bigger then 0. The only way to exit your loop is player 2 has a startnum2 on 0.

Your problem is:
threeorfive = 501
Throughout the entire game, and you begin each of your functions with
startnum = threeorfive
Which means the game 'resets' after both player takes a turn.
A possible fix would be to add global variables:
cumulative1 = 0
cumulative2 = 0
then update cumulative in each iteration:
cumulative1 += minusnum1
cumulative2 += minusnum2
and change your while loop to:
while(threeorfive - cumulative1 > 0)
while(threeorfive - cumulative2 > 0)

Related

How do I implement a timer on each question asked in a quiz?

I was attempting to create a quiz and one of the criteria is to limit the time available to solve for each question in the quiz. I looked up certain tutorials but some require an input of x seconds for the timer to go off while others looked more like a stopwatch...
I was wondering how do I do like a background timer that ticks down as soon as the question is printed out and skips to the next question if, for example the 30-second period has ended? I'm clueless in the timer function and was having problems to even try to implement them onto my codes. Could someone give out a few pointers so I can sorta progress further in implementing a working timer?
Thank you!
EDITED section below:
The timer that I want to implement onto my coding:
import time
import threading
def atimer():
print("Time's up.")
a_timer = threading.Timer(10.0, atimer)
a_timer.start()
print("")
This is the whole coding that I tried to implement the timer into.
I noticed that when I tried to define qtimer to just print 1 or 2 lines of statements the timer works but I want the timer to stop and go to second question or stop and give the user another attempt to retry the question, so I tried to attach a bunch of codes after the definition and it didn't work. I know I'm most probably doing something wrong here since I'm not quite familiar with time or threading functions. Is there a workaround?
def qtimer():
print("I'm sorry but your time is up for this question.")
print("You may have another attempt if you wish to, with reduced marks allocated.")
response1 = input("Type 'Yes' for another attempt, anything else to skip: ")
if response1 == "Yes":
Answ = input("Which option would you go for this time?: ")
Answ = int(Answ)
if possible[Answ - 1] == qaItem.corrAnsw:
print("Your answer was correct.")
corr += 1
marks += 0.5 * qaItem.diff
else:
print("Your answer was wrong.")
print("Correct answer was: " + qaItem.corrAnsw)
print("Explanation: " + qaItem.expl)
print("")
else:
print("Correct answer was: " + qaItem.corrAnsw)
print("Explanation: " + qaItem.expl)
print("")
class A:
def __init__(self, question, correctAnswer, otherAnswers, difficulty, explanation):
self.question = question
self.corrAnsw = correctAnswer
self.otherAnsw = otherAnswers
self.diff = difficulty
self.expl = explanation
qaList = [A("What is COVID-19?", "Coronavirus Disease 2019", ["Wuhan virus", "I don't understand...", "Coronavirus Disease v19"], 1, "Explanation 1"),
A("What describes COVID-19?", "A disease", ["A virus", "A parasite", "A bacteriophage"], 1, "Explanation 2"),
A("What causes COVID-19?", "SARS-CoV-2", ["Coronavirus", "Mimivirus", "Rubeola Virus"], 1, "Explanation 3"),
A("Which of the following is used in COVID-19 treatment?", "Lopinavir / Ritonavir ", ["Midazolam / Triazolam", "Amiodarone", "Phenytoin"], 2, "Explanation 4"),
A("Which of the following receptors is used by COVID-19 to infect human cells?", "ACE-2 Receptors", ["ApoE4 Receptors", "TCR Receptors", "CD28 Receptors"], 3, "Explanation 5")]
corr = 0
marks = 0
random.shuffle(qaList)
for qaItem in qaList:
q_timer = threading.Timer(5.0, qtimer)
q_timer.start()
print(qaItem.question)
print("Possible answers are:")
possible = qaItem.otherAnsw + [qaItem.corrAnsw]
random.shuffle(possible)
count = 0
while count < len(possible):
print(str(count+1) + ": " + possible[count])
count += 1
print("Please enter the number of your answer:")
Answ = input()
Answ = str(Answ)
while not Answ.isdigit():
print("That was not a number. Please enter the number of your answer:")
Answ = input()
Answ = int(Answ)
Answ = int(Answ)
while Answ > 4 or Answ < 1:
print("That number doesn't correspond to any answer. Please enter the number of your answer:")
Answ = input()
Answ = int(Answ)
if possible[Answ-1] == qaItem.corrAnsw:
print("Your answer was correct.")
corr += 1
marks += 1 * qaItem.diff
else:
print("Your answer was wrong.")
response = input("Would you want to try again? If so, input 'Yes' to attempt it again, if not just input whatever!")
if response == "Yes":
Answ = input("Which option would you go for this time?: ")
Answ = int(Answ)
if possible[Answ - 1] == qaItem.corrAnsw:
print("Your answer was correct.")
corr += 1
marks += 0.5 * qaItem.diff
else:
print("Your answer was wrong.")
print("Correct answer was: " + qaItem.corrAnsw)
print("Explanation: " + qaItem.expl)
print("")
else:
print("Correct answer was: " + qaItem.corrAnsw)
print("Explanation: " + qaItem.expl)
print("")
print("You answered " + str(corr) + " of " + str(len(qaList)) + " questions correctly.")
print("You have achieved a total score of " + str(marks) + ".")
Even with a timer, the main thread can't proceed past waiting for the user to input a number; so if the user doesn't nothing, the timer function runs, and once it has finished the main thread is still waiting for input at
print("Please enter the number of your answer:")
Answ = input()
You could have a global flag that the timer thread sets to tell the main thread to treat the input received as response1 in the timer code, and also have a flag to tell the timer that an answer was received, and so on, and it quickly becomes rather complicated.
So rather than trying to work around the blocking call to input by communicating between the timer and main thread, take the non-blocking input example from https://stackoverflow.com/a/22085679/1527 and stop the loop early if the time is up.
def timed_input(msg, timeout=10):
kb = KBHit()
print(msg)
end_time = time.time() + timeout
warn_time = 5
result = None
while True:
if kb.kbhit():
c = kb.getch()
if '0' <= c <= '9':
result = int(c)
break
print(c)
if time.time() > end_time:
print('time is up')
break
if time.time() > end_time - warn_time:
print(f'{warn_time}s left')
warn_time = warn_time - 1
kb.set_normal_term()
return result
# Test
if __name__ == "__main__":
result = timed_input('Enter a number between 1 and 4')
if result is None:
print('be quicker next time')
elif 1 <= result <= 4:
print('ok')
else:
print(f'{result} is not between 1 and 4')
Note also that breaking up into smaller functions helps make the code easier to follow, the logic of the test doesn't need to know about the logic of the timeout.

Global name 'transact' not defined when trying to run my simple program

I have to create this program for a class. I have been reading in various posts that lists in Python are already global and can be used in def statements.
Here are some of the resources I found that said this:
How to define a global list in python and append local list to it
How to declare python global list
Python global lists
None of these solutions have helped me and I am currently trying to figure this out. I might just have to rewrite it so that it doesn't use "options...". I also have a lot of "\n"s to make it look like it scrolls away from the old outputs because the teacher doesn't want to see them.
Here is the code I am having an issue with:
#!/usr/bin/python
import sys
def Switcher():
selec = 0
while (1):
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n==== WELCOME TO SPACECODE'S BANK ===="
print "==== Select an Option: ====\n"
print " 0. Check Current Balance\n"
print " 1. Deposit Money\n"
print " 2. Withdraw Money\n"
print " 3. Transaction History\n"
print " 4. Exit\n"
options = {0: zero,
1: one,
2: two,
3: three,
4: four
}
selection = input("\n")
if (selection < 0) or (selection > 4):
print '\n'
else:
selec = selection
options[selec]()
def zero():
global current
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n==== YOUR CURRENT BALANCE: ====\n"
print current
raw_input("\n Press enter to continue....")
Switcher()
def one():
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
global current, i
print "\n==== INPUT DEPOSIT AMOUNT: ====\n"
add = input()
current = add + current
i =+ 1
transact.append(i)
account.append(current)
raw_input("\n Press enter to continue....")
Switcher()
def two():
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n==== INPUT AMOUNT TO WITHDRAWL: ====\n"
global current, i
temp = current
wdrw = raw_input()
if (temp == 0):
print "==== YOU DONT HAVE ANY MONEY TO WITHDRAWL ====\n"
Switcher()
elif ((temp - wdrw) < 0):
print "==== YOU CANT WITHDRAWL MORE THAN YOU HAVE IN BALANCE ====\n"
two()
elif ((temp - wdrw) >= 0):
i =+ 1
transact.append(i)
current = temp - wdrw
account.append(current)
print "\n==== TRANSACTION SUCCESSFUL ====\n"
raw_input("\n Press enter to continue....")
Switcher()
def three():
global i
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n ==== TRANSACTION HISTORY (SAVES LAST 30) ====\n"
for w in range(len(trasac)):
print(transac[w]," : ",account[w])
print()
raw_input("\n Press enter to continue....")
Switcher(current)
def four():
sys.exit()
account = []
current = 0
transac = []
i = 0
Switcher()
Is it perhaps because you are declaring transac = [] instead of transact = [] at the bottom of your code?

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 Games high scores [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
hi I have made a game in python were you need to input the specified number before the time runs out. I want to be able to save the top 5 high scores and display them at the end. i have surfed the web looking for solutions but being a amateur at python, I just cant tailor them to my coding. I want to save the name and the score preferably on one line using \t to separate them.
any answers would be much appreciated.
the game:
# number press game
import time
import random
print "Welcome to my Number Press Game"
print "the computer will display a number"
print "you will have to enter the number before the time runs out"
name = raw_input ("please enter your name: "+"\n")
print "\n"+"welcome to the game "+name
print "ready"
time.sleep (1)
print "steady"
time.sleep (1)
print "GO!"
#game
loop = -1
t = 3
while True:
loop = loop+1
x = random.randint(1,3)
print x
start = time.time()
num = input("the number is: ")
end = time.time()
elapsed = end - start
if elapsed > t and num == x:
print "CORRECT, but too slow"
break
elif num != x and elapsed < t:
print "\n"+"WRONG, but in time"
break
elif num != x and elapsed > t:
print "WRONG and too slow"
break
if num == x and elapsed< t:
print "CORRECT and in time"
if t>0.7:
t =t*0.9
print "you loose"
print name+" scored: "+str(loop)
Run this and see if it gives what you have in mind: This runs simulates playing the game n number of times. Then the highest scores is printed out as a list of all scores. Right here I have used y = 5, if you need 5 highest scores, I presume you need to play the game at least 5 times then the scores compared and the highest values printed as your highest scores: in the for loop. The highest_scores is then sorted to pick out the n highest scores you require. That said, you should review your logic it seems to be problematic. vote the answer if it helps. Cheers
import time
import random
high_score = []
def play_game():
print "Welcome to my Number Press Game"
print "the computer will display a number"
print "you will have to enter the number before the time runs out"
name = raw_input ("please enter your name: "+"\n")
print "\n"+"welcome to the game "+name
print "ready"
time.sleep (1)
print "steady"
time.sleep (1)
print "GO!"
loop = -1
t = 3
score = 0
while True:
loop = loop+1
x = random.randint(1,3)
print x
start = time.time()
num = input("the number is: ")
end = time.time()
elapsed = end - start
if elapsed > t and num == x:
print "CORRECT, but too slow"
break
elif num != x and elapsed < t:
print "\n"+"WRONG, but in time"
break
elif num != x and elapsed > t:
print "WRONG and too slow"
break
if num == x and elapsed< t:
print "CORRECT and in time"
score += 1
if t>0.7:
t = t*0.9
high_score.append(score)
print "you loose"
print name + " scored: "+ str(score)
print "All highest_scores =", high_score
highest_scores = sorted(high_score, reverse = True)
print "All highest_scores =",highest_scores[0:3]
y = 5
for i in range (y):
play_game()

Performing an action as python script closes

I was wondering if it was possible to perform an action at any given point in a basic python script, so say when it is close. I have the following code to find prime numbers (Just for fun)
number = 1
primelist = []
nonprime = []
while number < 1000:
number += 1
for i in range(number):
if i != 1 and i != number and i !=0:
if number%i == 0:
nonprime.append(number)
else:
primelist.append(number)
nonprimes = open("nonprimes.txt", "w")
for nonprime in set(primelist) & set(nonprime):
nonprimes.write(str(nonprime) + ", ")
nonprimes.close()
So basically i wanted to run the last part as the script is stopped. If this isn't possible is there a way where say i press "space" while the program is running and then it saves the list?
Cheers in advance :)
EDIT:
I've modified the code to include the atexit module as suggested, but it doesn't appear to be working. Here it is:
import time, atexit
class primes():
def __init__(self):
self.work(1)
def work(self, number):
number = 1
self.primelist = []
self.nonprime = []
while number < 20:
time.sleep(0.1)
print "Done"
number += 1
for i in range(number):
if i != 1 and i != number and i !=0:
if number%i == 0:
self.nonprime.append(number)
else:
self.primelist.append(number)
nonprimes = open("nonprimes.txt", "w")
for nonprime in set(self.primelist) & set(self.nonprime):
nonprimes.write(str(nonprime) + ", ")
nonprimes.close()
def exiting(self, primelist, nonprimelist):
primelist = self.primelist
nonprimelist = self.nonprime
nonprimes = open("nonprimes.txt", "w")
for nonprime in set(self.primelist) & set(self.nonprime):
nonprimes.write(str(nonprime) + ", ")
nonprimes.close()
atexit.register(exiting)
if __name__ == "__main__":
primes()
While I'm pretty certain the file object does cleanup and flushes the stuff to file when it is reclaimed. The best way to go about this is to use a with statement.
with open("nonprimes.txt", "w") as nonprimes:
for nonprime in set(primelist) & set(nonprime):
nonprimes.write(str(nonprime) + ", ")
The boiler plate code of closing the file and such is performed automatically when the statement ends.
Python has an atexit module that allows you to register code you want executed when a script exits:
import atexit, sys
def doSomethingAtExit():
print "Doing something on exit"
atexit.register(doSomethingAtExit)
if __name__ == "__main__":
sys.exit(1)
print "This won't get called"

Categories

Resources