1
\$\begingroup\$

Could this code possibly be shortened, or even better be rewritten in the fewest lines of code possible?

import csv

import random
import math
import operator as op



name=input("What is your name: ")
print("Hello there",name,"Welcome to the math quiz, you will be asked 10 random questions on Addition, Multiplication and Subtraction")





choice = random.choice(['x','-','+'])
finish = False
questionnumber = 0
correctquestions = 0
Class = "" 


while finish == False:
       choice = random.choice(['x','-','+'])
       if questionnumber < 10 | questionnumber >= 0:
           number1 = random.randrange(1,10)
           number2 = random.randrange(1,10)
           print((number1),(choice),(number2))
           answer=int(input("What is the answer?"))
           questionnumber = questionnumber + 1

        if choice==("+"):
            realanswer = number1+number2
            if answer==realanswer:
                print("Well done that's the correct answer")
                correctquestions = correctquestions + 1
            else:
                print("Unlucky wrong answer")

        if choice==("x"):
            realanswer = number1*number2
            if answer==realanswer:
                print("That's the correct answer")
                correctquestions = correctquestions + 1
            else:
                print("That was not correct")

        elif choice==("-"):
            realanswer = number1-number2
            if answer==realanswer:
                print("That's the correct answer")
                correctquestions = correctquestions + 1
            else:
                print("Unlucky not the corret")

    else:
        finish = True
        print("Well done You have completed the math quiz, Your score was " + str(correctquestions) + "/10 questions.")

while Class not in ("1" , "2" , "3"):
    Class = input("whish class are you in?")

ScoresList = []

if Class == "1":
    with open("class1.csv","r") as class1:
        reader = csv.reader(class1)
        for row in reader:
            ScoresList.append(row)
elif Class == "2":
    with open("class2.csv" , "r") as class2:
        reader = csv.reader(class2)
        for row in reader:
            ScoresList.append(row)

elif Class == "3":
    with open("class3.csv","r") as class3:
        reader = csv.reader(class3)
        for row in reader:
            ScoresList.append(row)
else:
    print("Please enter a valid class")


position = 0 
match = 0


for row in ScoresList:

    if len(row) > 0 and row[0] == name: 
        match = 1
        break
    else:
        position += 1


print(position , match)
if match == 0:
    ScoresList.append([name,str(correctquestions)])
else:

    row = ScoresList[position] 
    if len(row) == 4:  
        del row[1]  
    row.append(str(correctquestions))  

for row in ScoresList:
    print(row)

if Class == "1":
    with open ("class1.csv" , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row)

if Class == "2":
    with open ("class2.csv" , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row)


if Class == "3":
    with open ("class3.csv" , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row) `  
\$\endgroup\$

closed as off-topic by SuperBiasedMan, Mathias Ettinger, Pimgd, Ethan Bierlein, Quill Feb 5 '16 at 10:29

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." – SuperBiasedMan, Mathias Ettinger, Pimgd, Ethan Bierlein, Quill
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ I surely am happy that you fell that my answer helped you, but I suggest waiting at least a day before accepting my question to give others a chance to give their suggestion. \$\endgroup\$ – Caridorc Feb 2 '16 at 19:05
  • \$\begingroup\$ Typo there, "whish class are you in?" :) \$\endgroup\$ – Keith M Feb 3 '16 at 8:26
  • \$\begingroup\$ Your indentation is still off. Inside your while loop, your else block doesn't match with any other block of code. Please do try to get it exactly right since it matters so much in Python. \$\endgroup\$ – SuperBiasedMan Feb 3 '16 at 11:24
2
\$\begingroup\$

You surely can shorten it by also improving readability

For example:

if Class == "1":
    with open ("class1.csv" , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row)

if Class == "2":
    with open ("class2.csv" , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row)


if Class == "3":
    with open ("class3.csv" , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row) `  

Becomes:

if Class in ("1", "2", "3"):
    with open ("class{}.csv".format(Class) , "w", newline='') as file:
        writer = csv.writer(file)
        for row in ScoresList:
            writer.writerow(row) `  

And, as you do that twice, you can extract it into a function to further avoid duplication.


You can also extract common code out of conditional branches

        if answer==realanswer:
            print("That's the correct answer")
            correctquestions = correctquestions + 1
        else:
            print("Unlucky not the corret")

is repeated in all of the ifs so you can write it just once at the bottom.

\$\endgroup\$
1
\$\begingroup\$

1.

while finish == False:

could better be stated:

while not finish:

though I'd also suggest renaming the variable to finished.

2. lines like

           questionnumber = questionnumber + 1

are better stated as:

           questionnumber += 1

3. if questionnumber < 10 | questionnumber >= 0:

...is almost certainly just plain Wrong. Do you really want bitwise-or there? If you meant logical-or, python spells it or.

4. position and match are redundant; use a sentry value of -1 as the default for position and then check against position < 0 to see if a match wasn't found. (if it was, it should be a row number... which is always 0 or higher)

5. Don't use reserved words or capitalized words like Class as variable names. Your Class is just as appropriately named class_number.

6. Factor out common filenames. You read and write to the same filename, but have two copies of the string, which could lead to trouble if you later change one and not the other. Instead store the name in a variable or constant that you can then pass to the various open invocations.

7. Add some comments. This breaks the code up into sections, and describes, at least briefly, what each section does.

import csv

import random
import math
import operator as op

# Welcome
name = input("What is your name: ")
print("Hello there", name, "Welcome to the math quiz, you will be asked 10 random questions on Addition, Multiplication and Subtraction")

choice = random.choice(['x','-','+'])
correctquestions = 0

# give the quiz
for questionnumber in range(1,11):

    choice = random.choice(['x','-','+'])
    number1 = random.randrange(1,10)
    number2 = random.randrange(1,10)
    print((number1),(choice),(number2))
    answer = int(input("What is the answer?"))

    if choice == "+":
        realanswer = number1 + number2
    elif choice == "x":
        realanswer = number1 * number2
    elif choice == "-":
        realanswer = number1 - number2


    if answer == realanswer:
        print("Well done that's the correct answer")
        correctquestions +=  1
    else:
        print("Unlucky wrong answer")

else:
    print("Well done You have completed the math quiz, Your score was " + str(correctquestions) + "/10 questions.")

# save their score
class_number = None
while class_number not in ("1" , "2" , "3"):
    class_number = input("which class are you in?")

classfilename = "class{}.csv".format(class_number)
ScoresList = []
position = -1

with open(classfilename, "r") as classfile:
    reader = csv.reader(classfile)
    for row in reader:
        if row and row[0] == name:
            player_row = len(ScoresList)
        ScoresList.append(row)

print(position)

if position < 0: # not found in the class
    ScoresList.append([name, str(correctquestions)])
else:
    row = ScoresList[position] 
    if len(row) == 4:  
        del row[1]
    row.append(str(correctquestions))  

for row in ScoresList:
    print(row)

with open (classfilename, "w", newline='') as file:
    writer = csv.writer(file)
    for row in ScoresList:
        writer.writerow(row)
\$\endgroup\$
  • \$\begingroup\$ For some reason when I try the code, it comes up with "name not defined" i cannot see why it is doing this \$\endgroup\$ – Richard Fletcher Feb 2 '16 at 22:38
  • \$\begingroup\$ name = int(input("What is your name: ")) File "<string>", line 1, in <module> NameError: name 't' is not defined \$\endgroup\$ – Richard Fletcher Feb 2 '16 at 22:56
  • \$\begingroup\$ @RichardFletcher You're probably using Python 2 where you should use raw_input, not input. Are you running Python from a different place than before, your original script did use input. \$\endgroup\$ – SuperBiasedMan Feb 3 '16 at 11:14
  • \$\begingroup\$ @pjz Just saying the bitwise operator is wrong is only half the advice. Why not also explain how Python uses or as its logical operator? \$\endgroup\$ – SuperBiasedMan Feb 3 '16 at 11:15

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