HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

"MathChallenge" game for sums with 4 operators

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withmathchallengegameforsumsoperators

Problem

I am trying to start learning Python using Learn Python the Hard Way. I wrote my first game that works as far as tested. It was done as an exercise for this.

Please give me some constructive criticism on this program on sections and areas where I can improve. I realise that my object-oriented programming specifically, and my programming in general, still needs lots of work:

```
"""
MathChallenge:
A game randomly creating and testing math sums with 4 operators: addition, subtraction, multiplication and division.
Difficulty levels are incremented after each correct answer.
No more than 3 incorrect answers are accepted.
"""

from random import randint, choice

class Math(object):
"""Class to generate different math sums based on operator and difficulty levels"""

def __init__(self):
"""To initialise difficulty on each run"""
self.difficulty = 1

def addition(self, a, b):
"""To return 'addition', '+' sign , and answer of operation"""
return ('addition', '+', a+b)

def subtraction(self, a, b):
"""To return 'subtraction', '-' sign , and answer of operation"""
return ('subtraction', '-', a-b)

def multiplication(self, a, b):
"""To return 'multiplication', '*' sign , and answer of operation"""
return ('multiplication', '', ab)

def division(self, a, b):
"""To return 'division', '/' sign , and answer of operation"""
return ('division', '/', a/b)

def mathsum(self, difficulty):
"""Function that generates random operator and math sum checks against your answer"""

print "Difficulty level %d." % difficulty

#let's initialize some random digits for the sum
a = randint(1,5)*difficulty
b = randint(1,5)*difficulty

#Now let's choose a random operator
op = choice(self.operator)(a, b)

print "Now lets do a %s calculation and see how clever you are." % op[0]
print "So what is %d %s %d?" % (a, op[1], b

Solution

Some notes:

-
You took a OOP approach. I won't say that's wrong (maybe it was even encouraged by that guide), but when learning a language like Python, where OOP is not compulsory, I'd say it preferable to take a non-OOP approach first.

-
return ('addition', '+', a+b). Those 4 operations are pretty uniform, why don't you use a data structure instead? (a list, a dictionary). Use module operator.

-
You code is for version 2.x. Unless you have some good reason, it's better to use Python 3.x, you won't lose a second re-learning things later on.

-
op[0], op[1], op[2]. If I had to highlight one single aspect of good programming practices, this would be: be declarative! If your code does not look as if you are writing pseudocode (specially if you are using a high-level language), then you're doing something wrong. What's op[1]? No idea, we'd have to look at the function. So destructure the result giving meaningful names to the variables: op_name, op_symbol, op_function = choice(self.operator)(a, b).

-
I'd take a more functional approach, try to organize code so there are as few in-place updates of variables as possible (not always feasible or idiomatic in an imperative language like Python).

I'd write:

import operator
import random

operations = {
    "addition": ("+", operator.add),
    "substraction": ("-", operator.sub),
    "multiplication": ("*", operator.mul),
    "division": ("/", operator.floordiv),
}

def ask_operation(difficulty, maxtries=3):
    maxvalue = 5 * difficulty
    x = random.randint(1, maxvalue)
    y = random.randint(1, maxvalue)
    op_name, (op_symbol, op_fun) = random.choice(list(operations.items()))
    result = op_fun(x, y)

    print("Difficulty level %d" % difficulty)
    print("Now lets do a %s calculation and see how clever you are." % op_name)
    print("So what is %d %s %d?" % (x, op_symbol, y))

    for ntry in range(1, 1+maxtries):
        answer = int(input(">"))
        if answer == result:
            print("Correct!")
            return True
        elif ntry == maxtries:
            print("That's %s incorrect answers.  The end." % maxtries)
        else:
            print("That's not right.  Try again.")
    return False

def play(difficulty):
    while ask_operation(difficulty):
        difficulty += 1
    print("Difficulty level achieved: %d" % difficulty)

play(1)

Code Snippets

import operator
import random

operations = {
    "addition": ("+", operator.add),
    "substraction": ("-", operator.sub),
    "multiplication": ("*", operator.mul),
    "division": ("/", operator.floordiv),
}

def ask_operation(difficulty, maxtries=3):
    maxvalue = 5 * difficulty
    x = random.randint(1, maxvalue)
    y = random.randint(1, maxvalue)
    op_name, (op_symbol, op_fun) = random.choice(list(operations.items()))
    result = op_fun(x, y)

    print("Difficulty level %d" % difficulty)
    print("Now lets do a %s calculation and see how clever you are." % op_name)
    print("So what is %d %s %d?" % (x, op_symbol, y))

    for ntry in range(1, 1+maxtries):
        answer = int(input(">"))
        if answer == result:
            print("Correct!")
            return True
        elif ntry == maxtries:
            print("That's %s incorrect answers.  The end." % maxtries)
        else:
            print("That's not right.  Try again.")
    return False

def play(difficulty):
    while ask_operation(difficulty):
        difficulty += 1
    print("Difficulty level achieved: %d" % difficulty)

play(1)

Context

StackExchange Code Review Q#27203, answer score: 4

Revisions (0)

No revisions yet.