1
\$\begingroup\$

I've written this code but it's really long. I really need it to be shorter so can someone please help me! Any suggestions will be helpful.

choice=raw_input("What type of quiz do you want to do: maths or science? ") 
topic=open("topic.txt", "a+") 
topic.write(choice + '\n') 
topic.close() 
difficulty=raw_input("What difficulty do you want to play on: easy, medium or hard? ") 
diff=open("difficulty.txt", "a+") 
diff.write(difficulty + '\n') 
diff.close()

score = 0

def answercheck(score, str_answer, int_answer):
    user_answer=raw_input("Select your answer. ")
    if user_answer.upper() == str(str_answer) or user_answer.upper() == str(int_answer):
        print("Well done, that's correct")
        score+=1
        print("Your score is " +str(score))
    else:
        print ("Wrong, it was "+str(int_answer))
        print("Your score is " +str(score))
    raw_input("Press enter to continue")
    return score

def report(score):
    print("Your final score is "+str(score))
    per=str(score)*(100/5)
    print("You achieved "+per+"%")
    if score==5:
        print("You achieved an A*")
    elif score==4:
        print("You acieved a grade B")
    elif score==3:
        print("You achieved a grade C")
    elif score==2:
        print("You achieved a grade D")
    elif score<=1:
        print("You failed")

if choice.lower() == "maths" and difficulty.lower() == "easy": 
    easym=open("mathseasy.txt" , "r") 
    lines = easym.readlines() 
    print lines[0]
    print lines[1]
    print("A. 4"+'\n'+"B. 6") 
    str_answer_one="A"
    int_answer_one=4
    first_score=answercheck(score, str_answer_one, int_answer_one)

    print lines[2]
    print("A. 5"+'\n'+"B. 6") 
    str_answer_two="A"
    int_answer_two=5
    second_score=answercheck(first_score, str_answer_two, int_answer_two)

    print lines[3]
    print("A. 15"+'\n'+"B. 20") 
    str_answer_three="B"
    int_answer_three=20
    third_score=answercheck(second_score, str_answer_three, int_answer_three)

    print lines[4]
    print("A. 13"+'\n'+"B. 15") 
    str_answer_four="A"
    int_answer_four=13
    fourth_score=answercheck(third_score, str_answer_four, int_answer_four)

    print lines[5]
    print("A. 100"+'\n'+"B. 110") 
    str_answer_five="B"
    int_answer_five=110
    fifth_score=answercheck(fourth_score, str_answer_five, int_answer_five)
    report(fifth_score)


if choice.lower() == "maths" and difficulty.lower() == "medium": 
    mediumm=open("mathsmedium.txt" , "r") 
    lines = mediumm.readlines() 
    print lines[0]
    print lines[1]
    print("A. 30"+'\n'+"B. 35") 
    str_answer_one="A"
    int_answer_one=30
    first_score=answercheck(score, str_answer_one, int_answer_one)

    print lines[2]
    print("A. 100"+'\n'+"B. 110") 
    str_answer_two="B"
    int_answer_two=110
    second_score=answercheck(first_score, str_answer_two, int_answer_two)

    print lines[3]
    print("A. 13"+'\n'+"B. 15") 
    str_answer_three="A"
    int_answer_three=13
    third_score=answercheck(second_score, str_answer_three, int_answer_three)

    print lines[4]
    print("A. 30"+'\n'+"B. 32") 
    str_answer_four="B"
    int_answer_four=32
    fourth_score=answercheck(third_score, str_answer_four, int_answer_four)

    print lines[5]
    print("A. 21"+'\n'+"B. 29") 
    str_answer_five="B"
    int_answer_five=29
    fifth_score=answercheck(fourth_score, str_answer_five, int_answer_five)
    report(fifth_score)

Here is the data in mathseasy.txt:

Welcome to the easy maths quiz.
What's 2+2?
What's 11-6?
What's 5*4?
What's 26/2?
What's 11*10?

Here is the data in mathsmedium.txt:

Welcome to the medium maths quiz.
What's 5*6?
What's 79+31?
What's 26/2?
What's 4*8?
What's 50-21?
\$\endgroup\$
  • 1
    \$\begingroup\$ Isn't this basically the same as your last question? \$\endgroup\$ – Oscar Smith Dec 18 '17 at 20:34
  • \$\begingroup\$ @OscarSmith new code though? \$\endgroup\$ – Riker Dec 18 '17 at 20:41
  • 4
    \$\begingroup\$ @OscarSmith different code \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Dec 18 '17 at 20:47
3
\$\begingroup\$

You could try making the questions/answers declarative and then the logic surrounding the questions/answers could then be factored out. An easy way would be to store the questions/answers in a list of tuples:

data = [("What is 5+5?", 10), ("What is 10+10?", 20) ...]
\$\endgroup\$
  • 1
    \$\begingroup\$ Isn't that a list of tuples? \$\endgroup\$ – Mast Dec 19 '17 at 5:28
  • 1
    \$\begingroup\$ @Mast whoops don't know where my mind went. fixed. \$\endgroup\$ – trinth Dec 19 '17 at 19:54
  • \$\begingroup\$ Good :-) Now I suspect there should be a ( before the second "What as well, correct? \$\endgroup\$ – Mast Dec 19 '17 at 19:58
  • \$\begingroup\$ how would i then check that the useranswer is correct or not? can you do an example of the code for like the first question please \$\endgroup\$ – Ibibat Dec 21 '17 at 20:39
1
\$\begingroup\$

When you have a great deal of if statements that assign a second value based on a first one you can use a dictionary (look-up hash table) to summarize the associations and use just that:

def report(score):
    print("Your final score is "+str(score))
    per=str(score)*(100/5)
    print("You achieved "+per+"%")
    if score==5:
        print("You achieved an A*")
    elif score==4:
        print("You acieved a grade B")
    elif score==3:
        print("You achieved a grade C")
    elif score==2:
        print("You achieved a grade D")
    elif score<=1:
        print("You failed")

Can become:

NUMBER_TO_LETTER = {
  '5' : 'A',
  '4' : 'B',
  '3' : 'C',
  '2' : 'D'
}

def report(score):
    print("Your final score is "+str(score))
    percentage = str(score)*(100/5)
    print("You achieved "+percentage+"%")
    if 2 <= score <= 5:
        print("You achieved an " + NUMBER_TO_LETTER[score])
    else:  # Score must be less than 1 because 5 is the max.
        print("You failed.")

So you can see the data is neatly organized in a table and you can avoid repeating the same message over and over again, that can cause spelling errors (elif score==4: print("You acieved a grade B")) and makes code unnecessarily long.

Also you could note that there is an inverse relation between the letter position in the alphabet and the score so:

def report(score):
    print("Your final score is "+str(score))
    percentage = str(score)*(100/5)
    print("You achieved "+percentage+"%")
    if 2 <= score <= 5:
        print("You achieved an " + "ABCDE"[5 - score] )
    else:  # Score must be less than 1 because 5 is the max.
        print("You failed.")

That is the final and simplest way to code this.

\$\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.