Timers, dates and script. - python

So i'm doing a project and have wanted to add some extra features to make it unique.
How do I make it output a timer sort of thing where it would say "It took you (minutes:seconds) to answer this question" after each question and then a overall timer at the end of the exam (Script). Also, how would I add a date on when the exam was taken. What else could i add to make this more unique and users actually interested in doing this. I have simple input features where it asks for their name, class name and then adds up the total score and outputs into a file, named after the class name using 'with' and 'open' commands.
OPERATIONS = [ # this is stating what the operations are.
(operator.add, "+"),
(operator.mul, "*"),
(operator.sub, "-")
]
for _ in range(10):
num1 = random.randint(1,10)#This will randomly select num1 & num2 to be from 1-10
num2 = random.randint(1,10)
op, symbol = random.choice(OPERATIONS) #this will make the symbol equal to the operations and randomly select it by using .choice
print("What is", num1, symbol, num2,"?")
if get_int_input() == op(num1, num2):#this will check if the input is true or false by using ValueError if its false.
print("Well done",name,"you got it correct!")
score += 1
else:
print("Incorrect, better luck next time!")

You can keep state of when you asked the question by using datetime.now() and checking how long it took with datetime.now() - prior time like below. Getting the date is pretty easy as well, datetime.strftime("DD-MM-YYYY") but what I had wrote below has the added benefit of keeping the day as well.
OPERATIONS = [ # this is stating what the operations are.
(operator.add, "+"),
(operator.mul, "*"),
(operator.sub, "-")
]
test_begin = datetime.now()
for _ in range(10):
num1 = random.randint(1,10)#This will randomly select num1 & num2 to be from 1-10
num2 = random.randint(1,10)
op, symbol = random.choice(OPERATIONS) #this will make the symbol equal to the operations and randomly select it by using .choice
start = datetime.now()
print("What is", num1, symbol, num2,"?")
if get_int_input() == op(num1, num2):#this will check if the input is true or false by using ValueError if its false.
print("Well done",name,"you got it correct!")
score += 1
else:
print("Incorrect, better luck next time!")
time_taken = datetime.now() - start
test_length = datetime.now() - test_begin
print(test_length.strftime("DD-MM-YYYY"))

What you want to do is make use of time from the time module.
You want one timer that starts when your entire application runs, and then you want a question timer that you reset after every question.
Here is an example. I leave the refactoring of injecting in to your code up to you.
Make use of a dictionary to store your your results so you can easily look them up later. And then you can just output your dictionary for your results.
from time import time
exam_time = {}
exam_timer_start = time()
for i in range(1, 10):
question_timer_start = time()
answer = input('question')
exam_time["question_{}".format(i)] = time() - question_timer_start
question_timer_end = time() - question_timer_start
print("That question took you {}s to complete".format(question_timer_end))
exam_time["total_exam"] = question_timer_end
print(exam_time)

Related

ATBSWP2 Chapter 8 Practice Project: How do I set timed input using the time module?

Hi this is my first time using this website so if I mess up the formatting please bear with me. I'm currently stuck at one of the practice projects in Chapter 8 and I can't seem to find any decent answers for this project.
This is the question:
**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.**
import random, time
num_of_ques = 10
tries = 3
correct_ans = 0
start_time = 0
elapsed = 0
for ques_num in range(num_of_ques):
num1 = random.randint(0, 9)
num2 = random.randint(0, 9)
result = num1 * num2
while tries > 0:
if start_time == 0:
start_time = time.time()
while True:
ans = input(f'{ques_num+1}: {num1} * {num2} = ? ')
try:
ans = int(ans)
break
except ValueError:
print('Not a number, please try again.')
elapsed = time.time() - start_time
if ans == result and elapsed<=8:
print('Correct!')
correct_ans += 1
time.sleep(1)
break
elif ans == result and elapsed>8:
print("Time's up!")
break
else:
print('Incorrect, try again!')
tries -= 1
ques_num += 1
time.sleep(1)
print('Score: %s / %s' % (correct_ans, num_of_ques))
I can't really seem to get the 8 second timer part correct. I'm also a complete beginner at python so I try to use the modules that are taught in the book. Are there any other places that I can put the (elapsed = time.time() - start_time) so the code works? Any help would be appreciated.
(using Python 3.9 btw)

time pass algorithm in python

import time
import random
info = """welcome to contest!..
pls answer question as quick as possible you can
pls enter small letter...\n"""
print(info)
questions = {"2 * 2 ?":"4",
"what is the capital city of turkey?":"ankara",
"what is the king of jungle?":"lion",
"what is the meaning of book in turkish language?":"kitap",
"who is the foundation of turkish government":"atatürk",
"what is the most popular drink in turkey?":"raki",
"pls tell us a hero as comic":"temel"}
correct = 0
wrong = 0
blank = 0
current_time = time.time() #system time
allowed_time = 25 #total time to reply the question
for i in random.sample(list(questions), 5):
question = questions[i]
if time.time() < current_time+allowed_time:
answer = input("1. soru --> {} : ".format(i))
if answer == question:
correct += 1
elif answer == "":
blank += 1
else:
wrong += 1
print()
print("right answer :", correct)
print("wrong answer :", wrong)
print("blank answer :", blank)
Please see my survey code above. It's selecting random 5 question in total time 25 seconds. But, I'd like to make it time option for every single question.
For example, questions must be replied with in ten seconds otherwise change question automatically.
Could you help on how to do that?
here's the steps to proceed(algorithm):
Add a timer to each question.
Run a counter or a timer inside the for loop, then, for every iteration passed, store the time in a variable x, check if x is less than 10.
Check whether it is answered within 10 seconds.
Iterate to the Next question, this i+1.
If NOT, jump to the next question.
The input() function - by its definition - waits for the input infinitely. Probably there is no cross-platform solution for it.
For *nix operating systems you may do this:
Create another thread with the timer which will interrupt the main thread after some time limit.
You may define a function for your input which will do it:
import thread # _thread for Python 3.x
import threading
def timed_input(prompt, timeout=25.):
timer = threading.Timer(timeout, thread.interrupt_main)
answer = ""
try:
timer.start()
answer = input(prompt)
except KeyboardInterrupt:
pass
timer.cancel()
return answer
and then use it instead of the standard input() function in your code (and of course without your original attempts with the time module).
Probably the most simple and the most elegant (from the programmer's point of view) is simply to keep infinitely time for an answer but then reject it if it was answered after the given time limit:
start_time = time.time()
answer = input("1. soru --> {} : ". format(i))
if time.time() - start_time > allowed_time:
# code for rejecting the answer
So instead of your for loop use this (a tested one, and with an improvement):
for j, i in enumerate( random.sample(list(questions), 5) ): # Slight change
question = questions[i]
start_time = time.time()
answer = input("{}. soru --> {} : ". format(j + 1, i)) # Sligth change
if time.time() - start_time > allowed_time:
print(" Time-out: You didn't answer quickly enough.")
answer = ""
if answer == question:
correct += 1
elif answer == "":
blank += 1
else:
wrong += 1
Not that I slightly changed your for statement and the answer = ... for the sake of printing correct ordinal numbers of questions (yours were always 1.)

Counting the number of loops python

I am learning python, and one of the exercises is to make a simple multiplication game, that carries on every time you answer correctly. Although I have made the game work, I would like to be able to count the number of tries so that when I've answered correctly a few times the loop/function should end. My problem is that at the end of the code, the function is called again, the number of tries goes back to what I originally set it, obviously. How could I go about this, so that I can count each loop, and end at a specified number of tries?:
def multiplication_game():
num1 = random.randrange(1,12)
num2 = random.randrange(1,12)
answer = num1 * num2
print('how much is %d times %d?' %(num1,num2))
attempt = int(input(": "))
while attempt != answer:
print("not correct")
attempt = int(input("try again: "))
if attempt == answer:
print("Correct!")
multiplication_game()
You could surround your call of multiplication_game() at the end with a loop. For example:
for i in range(5):
multiplication_game()
would allow you to play the game 5 times before the program ends. If you want to actually count which round you're on, you could create a variable to keep track, and increment that variable each time the game ends (you would put this inside the function definition).
I would use a for loop and break out of it:
attempt = int(input(": "))
for count in range(3):
if attempt == answer:
print("correct")
break
print("not correct")
attempt = int(input("try again: "))
else:
print("you did not guess the number")
Here's some documentation on else clauses for for loops if you want more details on how it works.
NB_MAX = 10 #Your max try
def multiplication_game():
num1 = random.randrange(1,12)
num2 = random.randrange(1,12)
answer = num1 * num2
i = 0
while i < NB_MAX:
print('how much is %d times %d?' %(num1,num2))
attempt = int(input(": "))
while attempt != answer:
print("not correct")
attempt = int(input("try again: "))
if attempt == answer:
print("Correct!")
i += 1
multiplication_game()

Is there any way to store functions in variables and create lists of variable-housed functions?

Am new to Python - have done some scripting in PHP, javascript, but am not a programmer (though am a tech writer with experience documenting APIs etc, so pretty extensive 'passive' programming know how).:
Was following steps here: https://en.wikibooks.org/wiki/A_Beginner's_Python_Tutorial/Functions. Specifically see the link re: simple calculator program
Wanted to figure out if I could make the program less redundant by storing all components for different calculations in list form, then have a very simple, generic means of processing any calculation request, by using the user's menu choice as an index into the list. I'm assuming it's good form to structure things in this way, but don't know! The original tutorial is obviously much more readable, but would mean the same error checking would need to be done repeatedly for each little "if" block...
In any case though, I couldn't figure out how to store the actual calculations as elements within a list. Is that possible? Here's as far as I got... where I managed to encapsulate, and call on, some of the specifics within lists, but had to still do a series of "if" statements for each individual calculation.
(Sorry if these questions are basic.. I did a bunch of searching without finding definitive documentation re: here's everything you can and Cannot capture in list form) So - my variation of the linked-to code:
#simple calculator program
# Prompts for possible calculations
add = ["Add this: ", "to this: ", "+"]
subtract = ["Subtract this: ", "from this: ", "-"]
multiply = ["Multiply this: ", "by this: ", "*"]
divide = ["Divide this: ", "by this: ", "/"]
# List of possible calculations
calcPrompts = [add, subtract, multiply, divide]
def promptEntries(Arg):
try:
op1 = int(input(Arg[0]))
op2 = int(input(Arg[1]))
operator = (Arg[2])
return op1, op2, operator
except:
print("Invalid entry. Please try again.")
choice = 0
#This variable tells the loop whether it should loop or not.
# 1 means loop. Anything else means don't loop.
loop = 1
while loop == 1:
#Display the available options
print ("\n\nCalculator options are:")
print (" ")
print ("1) Addition")
print ("2) Subtraction")
print ("3) Multiplication")
print ("4) Division")
print ("5) Quit calculator.py")
print (" ")
try:
choice = int(input("Choose your option: "))
choice = choice - 1
op1, op2, operator = promptEntries(calcPrompts[choice])
print(op1, operator, op2, "=", end=" ")
if choice == 0:
print(op1 + op2)
elif choice == 1:
print(op1 - op2)
elif choice == 2:
print(op1 * op2)
elif choice == 3:
if op2 != 0:
print(op1 / op2)
else:
print("Division by zero is invalid, please try again.")
elif choice == 4:
loop = 0
print ("Thank you for using calculator.py")
except:
print("invalid entry, please try again.")
In your case, you can use the operators as functions, provided by the operator standard library module.
As you can see, you can assign such functions to a variable, e.g. inserting all of them in a list
import operator as op
f = [op.add,
op.sub,
op.mul,
op.div,
op.pow,
op.mod]
then the loop can become
while True:
#Display the available options
print ("\n\nCalculator options are:")
for i, fun in enumerate(f):
print("{}) {}".format(i+1, fun.__name__))
print ("{}) Quit calculator.py".format(len(f)))
choice = int(input("Choose your option: ")) - 1
if choice == len(f):
print("Thank you for using calculator.py")
break
op1 = int(input("enter operand1: "))
op2 = int(input("enter operand2: "))
try:
result = f[choice](op1, op2)
except IndexError:
print("invalid entry, please try again.")
except ZeroDivisionError:
print("Division by zero is invalid, please try again.")
print('{} {} {} = {}'.format(op1, f[choice].__name__, op2, result))
Note: the example works for dyadic functions only. Further work is needed in case you want to offer a mix of functions with a different number of arguments.
Yes, in python functions are first class objects and you can use them any way that you would use any other object. For example you can have two variables reference the same object:
def myFunction():
pass
newVariable = myFunction
print(newVariable is myFunction)
or reference functions from a list or dictionary:
myList = [myFunction, 1, 2, 3]
print(myList[0] is myFunction)
myDict = {0:myFunction, 1:1}
print(myDict[0] is myFunction)
The above is true for both python's built in functions, functions in the standard library and functions you write. For example:
from operator import add
def countZeros(a):
return sum(item == 0 for item in a)
listOfFunctions = [sum, add, countZeros]

python quiz validation not working

The validation doesnt work. im not sure why, is there a way to validate a string. The questions asked are endless i need 10 questions to be asked
import random
name=(input("Please enter your name"))
print("welcome",name,"the arithmetic is about to start")
question=0
while question<10:
number=random.randint(1,10)
numbers=random.randint(1,10)
arith=random.choice("+" "-" "/")
if arith=="+":
print(number,arith,numbers)
answer=number+numbers
if arith=="-":
print(number,arith,numbers)
answer=number-numbers
if arith=="/":
print(number,arith,numbers)
answer=number/numbers
while True:
try:
usersanswer= int(input())
except ValueError:
print ("That is not a valid answer")
continue
if usersanswer==answer:
print("correct")
break
else:
print("incorrct")
The validation doesnt work. im not sure why, is there a way to validate a string
I've taking silentphoenix's answer and made it somewhat more pythonic and six'ed.
You should almost never use python2's input, because on top of being massive security hole, it sometimes does things that can be...rather unexpected.
import random
import operator # contains the python operators as functions
try:
input = raw_input # rebind raw_input to input, if it exists
# so I can just use input :P
except NameError:
pass
name = input("Hi, what is your name?\n")
print("Hi {} let's get started! Question 1".format(name))
#Get out of the habit of using string concatenation and use string
#formatting whenever possible. Strings are *immutable*;
#concatenation has to produce a lot temporary strings and is *slow*
#str.join and str.format are almost always better ideas.
#Python does not have a switch-case, so emulating one with a dictionary
operator_mapping = {'+': operator.add,
'-': operator.sub,
'*': operator.mul,
#'/': operator.truediv, #hey, division exists.
#But if you want division to actually work, you'll
#have to introduce a fudge factor :P
}
for i in range(10): # If you're just going for 10 iterations, it should be a for loop
# Brevity :P This is a list comprehension
first_number, second_number = [random.randint(1,10) for _ in range(2)]
oper = random.choice(list(operator_mapping))
answer = operator_mapping[oper](first_number, second_number)
while int(input("{} {} {} = ".format(first_number, oper, second_number))) != answer:
#while abs(float(input("{} {} {} = ".format(first_number, oper, second_number)))-answer) < 0.001: if you want truediv.
print('Wrong answer! try again!')
#If I've left the loop, user has given correct (enough) answer
if i <9: # all but last
print('Well done! Now onto question number {0}'.format(i+2))
print('Well done! You are done!')
In the third line, you ask for input. But a name is a string, so you need raw_input. raw_input takes strings, input only takes numerical values.
Python 2.7 getting user input and manipulating as string without quotations
Nowhere in your code do you update the variable questions, which I am guessing is a counter. You have to update that whenever a question is asked, using question += 1.
Finally, your code at the end does not really make sense. Based off the code, it checks for whether or not it is a string, but then compares it to the answer regardless. The if statement needs to be within the try.
The else statement does not match any outer indentation.
Finally, because of the while True: your code will never exit the loop unless the answer is wrong. At the point the entire program terminates. I see what kind of program you are trying to write, but the parameters for random number generation have to be within some kind of a while question <= 10 loop. As of now, only two lines in the program are being affected by that first while loop.
EDIT: I am working on a good example code. Hopefully this answer will help until I can finish it.
EDIT: Here is code that shows how it works within a while loop.
import random
from random import randint
name = raw_input("Hi, what is your name?\n") # Asks for name
print "Hi " +name+ " let's get started!"
score_count = 0
question_count = 0 # creates counter
while question_count <= 10: # Everything MUST BE WITHIN THIS LOOP
# makes numbers and operator
first_number = randint(1,10)
second_number = randint(1,10)
oper = random.choice("+""-""*")
# determines the problem
if oper == "+":
answer = first_number + second_number
print first_number,second_number,oper
elif oper == "-":
answer = first_number - second_number
print first_number,second_number,oper
elif oper == "*":
answer = first_number*second_number
print first_number, second_number, oper
user_answer = int(raw_input("Your answer: "))
if user_answer != answer:
print 'Wrong answer! try again!'
user_answer = int(raw_input('Your answer: '))
if user_answer == answer: # exits the while loop when the correct answer is given
if question_count < 10:
print 'Well done! Now onto question number {0}'.format(question_count+1)
score_count += 1
elif question_count == 10:
print 'Well done! You are done!'
score_count += 1
else:
print 'Something is wrong.'
question_count += 1 # updates the variable
# GOES BACK TO THE BEGINNING UNTIL question_count IS GREATER THAN OR EQUAL TO 10
print "Your score was: {}".format(score_count)
Happy coding! and best of luck!
hi im Nathan and I saw this post I am 5 years to late but I figured if someone on here is knew to python I have a much easier (in my opinion) way to do this in python 3, the code is below:
import random #random module automatically downloaded when you install python
name = input("Please enter your name ")
print("welcome",name,"the arithmetic is about to start")
question=0
while question<10:
number=random.randint(1,10) #creating a random number
numbers=random.randint(1,10) #creating a random number
list = ["+","-","/"] #creating a list (or sometimes called array)
arith=random.choice(list) #getting random operators from list (+,-,/)
question += 1 #basically means add one to question variable each time in loop
if arith=="+":
print(number,arith,numbers)
answer=number+numbers
elif arith=="-":
print(number,arith,numbers)
answer=number-numbers
elif arith=="/":
print(number,arith,numbers)
answer=number/numbers
answer = int(answer)
#from HERE
useranswer = "initialising this variable"
while useranswer == "initialising this variable":
try:
usersanswer= int(input())
if usersanswer==answer:
print("correct")
break
else:
print("incorrect")
except ValueError:
print ("That is not a valid answer")
#to HERE it is input validation this takes a while to explain in just commenting
#but if you dont know what this is then copy this link https://youtu.be/EG69-5U2AfU
#and paste into google for a detailed video !!!!!!
I hope this helps and is a more simplified commented bit of code to help you on your journey to code in python

Categories