Created
October 19, 2016 12:35
-
-
Save pochemuto/c0fb8e05b003c56a0553a549eb2cba0c to your computer and use it in GitHub Desktop.
Short arithmetic exercises
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
#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