-1
\$\begingroup\$

Like my previous question about my Mental Maths game , I have written a script for a ten questions Maths game and again it seems like there is a more simple method, can anyone take me out of the dark on this one?

def tenquestions():
    mode=input("(E)asy, (M)edium, (H)ard")
    questions=0
    rightqs=0
    while questions != 10:
        if operations == "A":
            if mode == "E":
                num1 = randint(5,1000)
                num2 = randint(5,1000)
                answer = num1+num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "+"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "M":
                num1 = randint(1000,10000)
                num2 = randint(1000,10000)
                answer = num1+num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "+"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "H":
                num1 = randint(10000,1000000)
                num2 = randint(10000,1000000)
                answer = num1+num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "+"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            else:
                print("Invalid Input")
        elif operations == "S":
            if mode == "E":
                num1 = randint(50,100)
                num2 = randint(5,49)
                answer = num1-num2
                answer=int(answer)
                useranswer=int(input(str(num1)+ "-"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "M":
                num1 = randint(5000,10000)
                num2 = randint(100,5000)
                answer = num1-num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "-"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "H":
                num1 = randint(50000,1000000)
                num2 = randint(10000,50000)
                answer = num1-num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "-"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            else:
                print("Invalid Input")
        elif operations == "M":
            if mode == "E":
                num1 = randint(5,25)
                num2 = randint(1,10)
                answer = num1*num2
                answer=int(answer)
                useranswer=int(input(str(num1)+ "×"+ str(num2) +"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "M":
                num1 = randint(25,100)
                num2 = randint(10,100)
                answer = num1*num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "×"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "H":
                num1 = randint(100,2500)
                num2 = randint(100,1000)
                answer = num1*num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "×"+ str(num2)+"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            else:
                print("Invalid Input")
        elif operations == "D":
            if mode == "E":
                possnums1 = [30,40,60,70,80,90,100]
                possnums2 = [5,10,2]
                num1 = possnums1[randint(0,6)]
                num2 = possnums2[randint(0,2)]
                answer = num1/num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "÷"+ str(num2) +"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "M":
                possnums1 = [100,120,240,330,540,390,510]
                possnums2 = [5,10,2,6]
                num1 = possnums1[randint(0,6)]
                num2 = possnums2[randint(0,3)]
                answer = num1/num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "÷"+ str(num2) +"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            elif mode == "H":
                possnums1 = [280,3080,1680,308,196,5628,12588]
                possnums2 = [28,14,7]
                num1 = possnums1[randint(0,6)]
                num2 = possnums2[randint(0,2)]
                answer = num1/num2
                answer=int(answer)
                useranswer=int(input(str(num1) + "÷"+ str(num2) +"="))
                if useranswer == answer:
                    print("Correct!")
                    rightqs=rightqs+1
                else:
                    print("Wrong, the answer was ", answer)
                questions=questions+1
            else:
                print("Invalid Input")
        else:
            print("Invalid Input")
        print(str(rightqs) + " out of " +str(questions) + " correct")
    again=input("Again? Type 'Y' for yes and 'N' for no")
from random import randint
print("TEN QUICK QUESTIONS")
again = "Y"
while again=="Y":
    operations = input("(A)ddition, (S)ubtraction, (M)ultiplication, (D)ivision")
    tenquestions()
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm not the downvoter, but you were likely downvoted because of the two questions in a row with the same problems. If you had just posted the first one, you could have improved this one before you posted it. \$\endgroup\$ – Hosch250 Dec 12 '15 at 16:23
  • 2
    \$\begingroup\$ I don't see a sign of learning from the answer of Hosch250 on the previous question. This question was posted too soon after the first, while I was also writing an answer, from which you could have learned enough to make this question substantially better. A large portion of my answer on the previous question could be copy-pasted here. It's not ideal for the site to have such content. So I suggest to 1. try to learn from the answers you receive, and 2. leave enough time to receive answers before posting a follow-up \$\endgroup\$ – janos Dec 12 '15 at 17:02
  • \$\begingroup\$ will do in future, sorry guys \$\endgroup\$ – Joe Dec 12 '15 at 17:26
  • \$\begingroup\$ In the answer by Janos, he is mentioning the use of operator.add & co, does that sound familiar somehow? This is one of the lesson we hope for you to have picked up from earlier answers, and implement if possible in new code. \$\endgroup\$ – holroy Dec 12 '15 at 21:25
4
\$\begingroup\$

As mentioned in my previous answer, you can use a function to remove this duplication:

num1 = randint(5,1000)
num2 = randint(5,1000)
answer = num1+num2
answer=int(answer)
useranswer=int(input(str(num1) + "+"+ str(num2)+"="))
if useranswer == answer:
    print("Correct!")
    rightqs=rightqs+1
else:
    print("Wrong, the answer was ", answer)
questions=questions+1

Becomes:

def addition(min, max):
    num1 = randint(min, max)
    num2 = randint(min, max)
    answer = num1+num2
    answer=int(answer)
    useranswer=int(input(str(num1) + "+"+ str(num2)+"="))
    if useranswer == answer:
        print("Correct!")
        rightqs=rightqs+1
    else:
        print("Wrong, the answer was ", answer)
    questions=questions+1

Again, this will result in heavy duplication between the addition/subtraction, etc. methods than can be removed in a similar manner. You will also be left with a messy chain of if/elifs that can likely be cleaned up as well.


You can simplify the statement questions=questions+1 into questions += 1


This is an unnecessary cast:

num1 = randint(min, max)
num2 = randint(min, max)
answer = num1+num2
answer=int(answer)

Last, but not least, you should put your starting code in an if __name__ == "__main__": function. This will prevent problems when you start working with code in multiple files.

\$\endgroup\$
2
\$\begingroup\$

The tenquestions function is 170 lines long. Try to aim for the smallest possible functions that do one thing and do it well.

When you have similar code with segments of code implementing identical logic but with different values in certain positions, that's a prime candidate for method extraction: the logic should be moved to its own function, and the changing values should be replaced with function parameters.

@Hosch250 started to explain that same point, let's take that a step further and transform your code. Following the first tip, and a few other tips in my previous answer to your previous question, your code becomes:

def play_add(minvalue, maxvalue):
    num1 = randint(minvalue, maxvalue)
    num2 = randint(minvalue, maxvalue)
    answer = num1 + num2
    prompt = '{} + {} = '.format(num1, num2)
    useranswer = int(input(prompt))
    if useranswer == answer:
        print("Correct!")
        return True
    print("Wrong, the answer was", answer)
    return False


def play_sub(num1min, num1max, num2min, num2max):
    num1 = randint(num1min, num1max)
    num2 = randint(num2min, num2max)
    answer = num1 - num2
    prompt = '{} - {} = '.format(num1, num2)
    useranswer = int(input(prompt))
    if useranswer == answer:
        print("Correct!")
        return True
    print("Wrong, the answer was", answer)
    return False


def tenquestions():
    mode = input("(E)asy, (M)edium, (H)ard")
    questions = 0
    rightqs = 0
    while questions != 10:
        if operations == "A":
            if mode == "E":
                if play_add(5, 1000):
                    rightqs += 1
                questions += 1
            elif mode == "M":
                if play_add(1000, 10000):
                    rightqs += 1
                questions += 1
            elif mode == "H":
                if play_add(10000, 1000000):
                    rightqs += 1
                questions += 1
            else:
                print("Invalid Input")
        elif operations == "S":
            if mode == "E":
                if play_sub(50, 100, 5, 49):
                    rightqs += 1
                questions += 1
            elif mode == "M":
                if play_sub(5000, 10000, 100, 5000):
                    rightqs += 1
                questions += 1
            elif mode == "H":
                if play_sub(50000, 1000000, 10000, 50000):
                    rightqs += 1
                questions += 1
            else:
                print("Invalid Input")
        elif operations == "M":
            # ... and so on ...

And so on. You can do similar for multiplication and division too.

Ok so this eliminated a lot of duplication from tenquestions, but there is still a lot of duplication in play_add and play_sub. So follow the same logic, extract the common part to a new function, let's call it play_operation, and let's implement play_add and play_sub in terms of that:

def play_operation(op, symbol, num1min, num1max, num2min, num2max):
    num1 = randint(num1min, num1max)
    num2 = randint(num2min, num2max)
    answer = op(num1, num2)
    prompt = '{} {} {} = '.format(num1, symbol, num2)
    useranswer = int(input(prompt))
    if useranswer == answer:
        print("Correct!")
        return True
    print("Wrong, the answer was", answer)
    return False


def play_add(minvalue, maxvalue):
    return play_operation(operator.add, '+', minvalue, maxvalue, minvalue, maxvalue)


def play_sub(num1min, num1max, num2min, num2max):
    return play_operation(operator.sub, '-', num1min, num1max, num2min, num2max)

Follow this logic iteratively, in the entire program, and strive to eliminate all duplicated blocks of code.

Note that division is a tad more complicated than the others. That's fine, in fact it's important to know where to stop with generalization. In case of division, you should extract the common logic to a play_div function, and you can stop there, no need to bend over backwards to alter play_operation to work in this case too.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.