Created
August 31, 2018 16:32
-
-
Save gpalsingh/48521b8faaff3c5c28dbb17a5db67387 to your computer and use it in GitHub Desktop.
Round numbers quiz for class 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!usr/bin/python | |
from random import randrange, choice | |
from decimal import Decimal | |
from collections import defaultdict | |
from operator import itemgetter | |
import argparse | |
import sys | |
#Global variables | |
name_to_zeroes = { | |
"": 0, | |
"one": 0, | |
"ten": 1, | |
"hundred": 2, | |
"thousand": 3, | |
"lakh": 5, | |
"crore": 7 | |
} | |
rounding_choices = [ | |
'ten thousandth', | |
'thousandth', | |
'hundredth', | |
'tenth', | |
'one', | |
'ten', | |
'hundred', | |
'thousand', | |
'lakh', | |
'crore' | |
] | |
## HELPER FUNCTIONS | |
def wordsToZeroes(round_to): | |
#returns number of zeroes and direction | |
words = round_to.split(' ') | |
direction = "right" if words[-1].endswith('th') else "left" | |
if words[-1].endswith('th'): | |
direction = "right" | |
words[-1] = words[-1][:-2] | |
else: | |
direction = "left" | |
total_zeroes = 0 | |
for word in words: | |
total_zeroes += name_to_zeroes[word] | |
return total_zeroes, direction | |
def createNumber(number_size, decimal_size): | |
number = str(randrange(1,10)) | |
for _ in range(number_size - 1): | |
#higher chance for number to be 5 or higher | |
number += str(randrange(3,10)) | |
if not decimal_size: | |
return number | |
number += '.' | |
for _ in range(decimal_size): | |
number += str(randrange(3,10)) | |
return number | |
def roundNumber(number, num_zeroes, direction): | |
#Returns answer as decimal | |
n = Decimal(number) | |
if direction == "right": | |
return round(n, num_zeroes) | |
m = 10**num_zeroes | |
return Decimal(round(n / m) * m) | |
## ARGUMENTS PARSER | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-c', '--count', type=int, default=10, | |
help='Number of questions to ask in this session') | |
parser.add_argument('-f', '--force-decimal', help="Force numbers to have decimal part", | |
action="store_true") | |
parser.add_argument('-r', '--round-to', help='Fix "round to" value', choices=rounding_choices) | |
parser.add_argument('-n', '--num-size', type=int, help="Fix number of digits to left") | |
parser.add_argument('-d', '--dec-size', type=int, help="Fix number of digits in decimal part") | |
parser.add_argument('--debug', action='store_true') | |
args = parser.parse_args() | |
#Quiz number properties | |
force_decimal = args.force_decimal | |
g_round_to = args.round_to | |
g_number_size = args.num_size | |
g_decimal_size = args.dec_size | |
question_count = args.count | |
wrong_answers = defaultdict(int) | |
right_ans_count = 0 | |
quit = None | |
debug = args.debug | |
##MAIN | |
for qno in range(1, question_count + 1): | |
if quit == "exit": break | |
#generate initial values | |
round_to = g_round_to or choice(rounding_choices) | |
number_size = g_number_size or randrange(10) | |
decimal_size = g_decimal_size | |
number = None | |
#get number metadata | |
num_zeroes, direction = wordsToZeroes(round_to) | |
#Fix number and decimal sizes | |
if direction == "left" and (not number_size or number_size <= num_zeroes): | |
number_size = num_zeroes + randrange(2,5) | |
if force_decimal or (direction == "right" and (not decimal_size or decimal_size <= num_zeroes)): | |
decimal_size = num_zeroes + randrange(2,5) | |
#Create number | |
number = createNumber(number_size, decimal_size) | |
#Get answer | |
answer = roundNumber(number, num_zeroes, direction) | |
#Keep asking the same question until the right answer is given | |
while right_ans_count != qno: | |
if quit == "exit": break | |
if qno != 1: | |
print('\n' * 10) | |
print("QUESTION #{} OF {}".format(qno, question_count)) | |
question_statement = "What is {} rounded to {}?".format(number, round_to) | |
print(question_statement) | |
user_answer = Decimal(input("Your answer: ")) | |
if debug: | |
print("Answer is {}".format(answer)) | |
print(user_answer == answer) | |
print(type(user_answer), type(answer)) | |
print('\n') | |
if user_answer == answer: | |
print("You got it right!") | |
right_ans_count += 1 | |
else: | |
print("Nope.") | |
wrong_answers[question_statement] += 1 | |
print('\n') | |
#don't prompt if exercise has ended already | |
if right_ans_count != question_count: | |
print('Type "exit" to quit exercise') | |
quit = input('Press "Enter" key to continue: ') | |
#give exercise results | |
print('\n') | |
retry_qs_and_counts = sorted(wrong_answers.items(), key=itemgetter(1), reverse=True) | |
wrong_answer_count = len(wrong_answers) | |
if quit == "exit": | |
print("Exercise ended prematurely") | |
elif not retry_qs_and_counts: | |
print("Congratulations! You answered all of the questions correctly!!") | |
sys.exit() | |
else: | |
right_answer_count = question_count - wrong_answer_count | |
print("You scored {}%".format(round((right_answer_count / question_count) * 100, 2))) | |
print("You struggled to answer {} questions.".format(wrong_answer_count)) | |
if wrong_answer_count > 5: | |
input('Press "Enter" key to see them and revise them') | |
for question, retry_count_plus_one in retry_qs_and_counts: | |
print('"{}", Retry count: {}'.format(question, retry_count_plus_one - 1)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment