Skip to content

Instantly share code, notes, and snippets.

@pochemuto
Created October 19, 2016 12:35
Show Gist options
  • Save pochemuto/c0fb8e05b003c56a0553a549eb2cba0c to your computer and use it in GitHub Desktop.
Save pochemuto/c0fb8e05b003c56a0553a549eb2cba0c to your computer and use it in GitHub Desktop.
Short arithmetic exercises
#coding=utf
import random
import pickle
from os import path
from datetime import datetime
class Operation(object):
def gen(self):
pass
class Add(Operation):
def gen(self):
left = random.randint(10, 150)
right = random.randint(10, 150)
return Excercise(left, '+', right, left + right)
class Sub(Operation):
def gen(self):
a = random.randint(10, 150)
b = random.randint(10, 150)
return Excercise(max(a, b), '-', abs(a - b), min(a, b))
class Mul(Operation):
def gen(self):
a = random.randint(1, 11)
b = random.randint(0, 11)
return Excercise(a, '×', b, a * b)
class Div(Operation):
def gen(self):
a = random.randint(1, 11)
b = random.randint(0, 11)
return Excercise(a * b, '/', a, b)
class Excercise(object):
def __init__(self, left, op, right, result):
self.left = left
self.op = op
self.right = right
self.result = result
def __str__(self):
return '{0} {1} {2}'.format(self.left, self.op, self.right)
class Result(object):
def __init__(self, excercise, correct, duration = None):
self.excercise = excercise
self.correct = correct
self.duration = duration
class Session(object):
def __init__(self):
self.started = None
self.finished = None
self.results = []
def start(self):
self.started = datetime.now()
def finish(self):
self.finished = datetime.now()
def add(self, result):
self.results.append(result)
def stat(self, last=20):
data = self.results[-last:]
precision = len(filter(lambda r: r.correct, data)) * 1.0 / len(data)
return Stat(len(data), precision)
def __len__(self):
return len(self.results)
class Stat(object):
def __init__(self, count, precision):
self.count = count
self.precision = precision
def score(self):
return int(self.precision * 5)
def __str__(self):
score = self.score()
return '★' * score + '☆' * (5 - score)
def __repr__(self):
return "precision = {}, total = {}".format(self.precision, self.count)
class Test(object):
def __init__(self):
self.ops = [Add(), Sub(), Mul(), Div()]
self.session = Session()
self.history_file = path.expanduser('~/Dropbox/math-test.dat')
self.minimum_to_save = 20
def start(self):
self.session.start()
while True:
result = self.next()
if result is None:
break
self.session.add(result)
print '✅ ' if result.correct else '❎ ', self.stat()
print ''
if len(self.session) > 0:
print self.stat()
if len(self.session) >= self.minimum_to_save:
self.save_session()
else:
print 'Too few exercises done for saving session. {} but no less {} is needed'.format(len(self.session), self.minimum_to_save)
def stat(self, last=20):
return self.session.stat(last)
def save_session(self):
sessions = self.load_sessions()
sessions.append(self.session)
pickle.dump(sessions, open(self.history_file, 'wb'))
def load_sessions(self):
if path.isfile(self.history_file):
return pickle.load(open(self.history_file))
else:
return []
def total_stat(self):
sessions = self.load_sessions()
return 'Total sessions: {}'.format(len(sessions))
def next(self):
excercise = random.choice(self.ops).gen()
while True:
try:
start = datetime.now()
print excercise, '=',
answer = int(raw_input())
end = datetime.now()
break
except ValueError:
pass
except EOFError:
return None
return Result(excercise, answer == excercise.result, end - start)
def main():
test = Test()
print test.total_stat()
test.start()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment