Created
March 12, 2016 02:50
-
-
Save zackmdavis/f0e436c0665a8460d4af to your computer and use it in GitHub Desktop.
This file contains hidden or 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/env python3 | |
from enum import Enum | |
from random import choice, randint | |
from datetime import datetime | |
from operator import add, sub, mul # binary operations as functions! | |
# Enums were introduced in 3.4! | |
Operation = Enum('Operation', ('add', 'subtract', 'multiply')) | |
class Expression: | |
operations = {Operation.add: ('+', add), | |
Operation.subtract: ('-', sub), | |
Operation.multiply: ('*', mul)} | |
def __init__(self, operation, first_operand, second_operand): | |
self.operation = operation | |
self.first_operand = first_operand | |
self.second_operand = second_operand | |
@classmethod # class methods! | |
# the convention is to say `cls` instead of `self` for these | |
def arbitrary_expression(cls, maximum_figure): | |
return cls(choice(list(Operation)), | |
# gratuitously splatting a list comprehension because <3 | |
*[randint(0, maximum_figure) for _ in range(2)]) | |
def evaluate(self): | |
_symbol, action = self.operations[self.operation] | |
return action(self.first_operand, self.second_operand) | |
def __str__(self): # pretty end-user string form of class | |
# (contrast to __repr__, for the developer debugging string form) | |
symbol, _action = self.operations[self.operation] | |
return "{} {} {}".format( | |
self.first_operand, symbol, self.second_operand) | |
def play(maximum_figure=12): | |
start_time = datetime.now() | |
wins = tries = 0 # multiple assignment targets! | |
should_continue = True | |
while should_continue: | |
expression = Expression.arbitrary_expression(maximum_figure) | |
try: | |
user_says = input("{}\n".format(expression)) | |
except KeyboardInterrupt: # catch ^C | |
break | |
if "done" in user_says: | |
should_continue = False | |
else: | |
tries += 1 | |
try: | |
user_answer = int(user_says) | |
if user_answer == expression.evaluate(): | |
wins += 1 | |
print("Correct!") | |
continue | |
except ValueError: # they typed a non-number | |
pass # fallthrough to ... | |
print("Wrong. Answer was {}".format(expression.evaluate())) | |
end_time = datetime.now() | |
total_time = (end_time - start_time).total_seconds() | |
print( | |
"{} wins / {} tries in {} sec {}".format( | |
wins, tries, total_time, | |
"({} sec/try)".format( | |
# can't divide by zero, which is falsey | |
round(total_time / tries, 2)) if tries else '' | |
) | |
) | |
# only if we're running as a script, not if imported as module | |
if __name__ == "__main__": | |
play(maximum_figure=12) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment