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?
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Dec 18, 2017 at 20:33
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Isn't this basically the same as your last question? \$\endgroup\$ Commented Dec 18, 2017 at 20:34
  • \$\begingroup\$ @OscarSmith new code though? \$\endgroup\$ Commented Dec 18, 2017 at 20:41
  • 4
    \$\begingroup\$ @OscarSmith different code \$\endgroup\$ Commented Dec 18, 2017 at 20:47

2 Answers 2

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) ...]
answered Dec 19, 2017 at 0:22
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Isn't that a list of tuples? \$\endgroup\$ Commented Dec 19, 2017 at 5:28
  • 1
    \$\begingroup\$ @Mast whoops don't know where my mind went. fixed. \$\endgroup\$ Commented Dec 19, 2017 at 19:54
  • \$\begingroup\$ Good :-) Now I suspect there should be a ( before the second "What as well, correct? \$\endgroup\$ Commented Dec 19, 2017 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\$ Commented Dec 21, 2017 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.

answered Dec 19, 2017 at 20:44
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.