简体   繁体   中英

Python 3.3 - Multiple choice reading from list and .txt then grade

I have tried this program in three different ways I know I got close several times but after failing so many times I have given up and need an extra set of eyes. The program is "simple" I know but I know I am over thinking it.

Program should store correct answers in a list. Using that list to grade the 20 question test. Then read that student.txt file to determine how the student answered. After reading the .txt file it should grade then display pass or fail (passing = 15 or greater) It finally displays the total number or correct, incorrect answers with a list of the questions missed by the student.

Below are all three attempts. Any help is greatly appreciated.


answerKey = [ B, D, A, A, C, A, B, A, C, D, B, C, D, A, D, C, C, B, D, A,]

studentExam = [ B, D, A, D, C, A, B, A, C, A, B, C, D, A, D, C, C, B, D, A,]

index = 0 

numCorrect = 0

for answerLine, studentLine in zip (answerKey, studentExam):
    answer = answerLine.split()
    studentAnswer = studentLine.split()

    if studentAnswer != answer:
        print( 'You got that question number', index + 1, 'wrong\n the correct,\
        answer was' ,answer, 'but you answered' , studentAnswer)
        index += 1
    else:
        numCorrect += 1
        index += 1

    grade = int((numCorrect / 20) * 100)

    print (' The number of correctly answered questions: ', numCorrect)

    print (' The number of incorrectly answered questions: ', 20 - numCorrect)

    print (' Your grade is', grade, '%')

    if grade <= 75:
        print (' You have not passed ')
    else:
        print (' Congrats you have passed ')

answerKey.close()
studentExam.close()

# This program stores the correct answer for a test
# then reads students answers from .txt file
# after reading determines and dislpays pass or fail (15 correct to pass)
# Displays number of correct and incorrect answers for student
# then displays the number for the missed question/s

#Creat the answer list
def main ( ): 
    # Create the answer key list
    key = [ B, D, A, A, C, A, B, A, C, D, B, C, D, A, D, C, C, B, D, A,]

    print (key)

# Read the contents of the student_answers.txt and insert them into a list
def read_student( ):
    # Open file for reading
    infile = open ( 'student_answers.txt', 'r' )

    # Read the contents of the file into a list
    student = infile.readlines ( )

    # Close file
    infile.close ( )

    # Strip the \n from each element
    index = 0
    while index < len(student):
        student[index] = student[index].rstrip ( '\n' )

    # Print the contents of the list
    print (student)

# Determine pass or fail and display all results 
def pass_fail(answers, student):

    # Lists to be used to compile amount correct, 
    # amount wrong, and questions number missed
    correct_list = []
    wrong_list = []
    missed_list = []

    # For statement to compile lists
    for ai,bi in zip (key,student):
        if ai == bi:
            correct_list.append(ai)
        else:
            wrong_list.append(ai)
            missed_list.append(ai)

    # Printing results for user
    print(correct_list,' were answered correctly')

    print(wrong_list,' questions were missed')

    # If statement to determine pass or fail
    if len(correct_list) >=15:
        print('Congrats you have passed')
    else: 
        print('Sorry you have faild please study and try, \
         again in 90 days')
        print('Any attempt to retake test before 90 days, \
        will result in suspension of any licenses')

    # Displaying the question number for the incorrect answer
    print ( 'You missed questions number ', missed_list)


main()

a = (1, 'A'),(2,'C'),(3,'B')
b = (1,'A'), (2,'A'),(3,'C')

correct_list = []

wrong_list = []

missed_list = []

for ai, bi in zip (a, b):
    if ai == bi:
        correct_list.append(ai)
    else:
        wrong_list.append(ai)
        missed_list.append(ai)
index(ai)+1


print(correct_list,'answered correct')

print(wrong_list, 'answered wrong')

if len(correct_list) >=2:
    print ('Congrats you have passed')
else:
    print ('Sorry you have faild please study and try again in 90 days')
    print('Any attempt to retake test before 90 days will result in suspension of any     lisences')


print ('Question number missed', missed_list)

So, I decided to work off of your second example, since it was the easiest for me to follow.

Here is a modified file, with explanations, which does what I think you want. I assumed the student answers were in a text file called student_answers.txt and had one answer per line.

#!/usr/bin/env python

def read_student(path):
    with open(path, 'r') as infile:
        contents = infile.read()

    # Automatically gets rid of the newlines.
    return contents.split('\n') 

def pass_fail(answers, student):
    correct_list = []
    wrong_list = []

    # Use the 'enumerate' function to return the index.
    for index, (ai, bi) in enumerate(zip(answers, student)):
        # since problems start with 1, not 0
        problem_number = index + 1 

        if ai == bi:
            correct_list.append(problem_number)
        else:
            wrong_list.append(problem_number)

    # Print the length of the list, not the list itself.
    print(len(correct_list), 'were answered correctly')
    print(len(wrong_list), 'questions were missed')

    if len(correct_list) >= 15:
        print('Congrats, you have passed')
    else: 
        print('Sorry, you have failed. Please study and try again in 90 days')
        print('Any attempt to retake test before 90 days will result in suspension of any licenses')

    # Display each missed number on a separate line
    print ('You missed questions numbers:')
    for num in wrong_list:
        print('    ' + str(num))



def main( ): 
    key = ['B', 'D', 'A', 'A', 'C', 'A', 'B', 'A', 'C', 'D', 'B', 'C', 
        'D', 'A', 'D', 'C', 'C', 'B', 'D', 'A']
    student_answers = read_student('student_answers.txt')
    pass_fail(key, student_answers)

if __name__ == '__main__':
    main()

Some general comments:

  • In your main function, you created a key, printed it, and tried to access it inside the pass_fail function. That won't work -- when you create a variable inside a function, it is not automatically accessible outside of the function. There were several solutions you could have done:
    • Made key a global variable. This is an undesirable solution
    • Pass the key variable into the pass_fail function. This is what I did.
  • Your code to read the student's file was a bit too complex. You could use the with statement, which automatically opens and closes the file object ( infile ) for you. Similarly, Python comes with built-in ways to help split the string in your textfile up and remove the newline character. In addition, for the future, you can also iterate over each line in a file like the below instead of manually looping through it:

     with open('file.txt') as my_file: for line in my_file: print(line) # The newline is still a part of the string! 
  • I'm not sure why you had both the wrong_list and missed_list variables inside pass_fail . I deleted missed_list .

  • The problem with your for loop was that you were storing the correct answers, not the problem numbers. To solve that, I used the built-in enumerate function which is quite useful for this sort of thing. Alternatively, you could have used a variable and incremented it once per loop.
  • Your print statements were a little malformed, so I cleaned that up
  • When printing the results for the user, you don't want to print the list. Rather, you want to print the length of the list.
  • I don't know if this was intentional or not, but your key didn't have strings in it, and instead had just the letter names.

Your first answer is rather close except that Python is interpreting the A,B,C and D as variables and not characters. You left the grading logic in your for loop. After changing the array to be characters instead of variables I got the following result:

 The number of correctly answered questions:  1
 The number of incorrectly answered questions:  19
 Your grade is 5 %
 You have not passed 
 The number of correctly answered questions:  2
 The number of incorrectly answered questions:  18
 Your grade is 10 %
 You have not passed 
 The number of correctly answered questions:  3
 The number of incorrectly answered questions:  17
 Your grade is 15 %
 You have not passed 
You got that question number 4 wrong
 the correct,        answer was ['A'] but you answered ['D']
 The number of correctly answered questions:  3
 The number of incorrectly answered questions:  17
 Your grade is 15 %
 You have not passed 
 The number of correctly answered questions:  4
 The number of incorrectly answered questions:  16
 Your grade is 20 %
 You have not passed 
 The number of correctly answered questions:  5
 The number of incorrectly answered questions:  15
 Your grade is 25 %
 You have not passed 
 The number of correctly answered questions:  6
 The number of incorrectly answered questions:  14
 Your grade is 30 %
 You have not passed 
 The number of correctly answered questions:  7
 The number of incorrectly answered questions:  13
 Your grade is 35 %
 You have not passed 
 The number of correctly answered questions:  8
 The number of incorrectly answered questions:  12
 Your grade is 40 %
 You have not passed 
You got that question number 10 wrong
 the correct,        answer was ['D'] but you answered ['A']
 The number of correctly answered questions:  8
 The number of incorrectly answered questions:  12
 Your grade is 40 %
 You have not passed 
 The number of correctly answered questions:  9
 The number of incorrectly answered questions:  11
 Your grade is 45 %
 You have not passed 
 The number of correctly answered questions:  10
 The number of incorrectly answered questions:  10
 Your grade is 50 %
 You have not passed 
 The number of correctly answered questions:  11
 The number of incorrectly answered questions:  9
 Your grade is 55 %
 You have not passed 
 The number of correctly answered questions:  12
 The number of incorrectly answered questions:  8
 Your grade is 60 %
 You have not passed 
 The number of correctly answered questions:  13
 The number of incorrectly answered questions:  7
 Your grade is 65 %
 You have not passed 
 The number of correctly answered questions:  14
 The number of incorrectly answered questions:  6
 Your grade is 70 %
 You have not passed 
 The number of correctly answered questions:  15
 The number of incorrectly answered questions:  5
 Your grade is 75 %
 You have not passed 
 The number of correctly answered questions:  16
 The number of incorrectly answered questions:  4
 Your grade is 80 %
 Congrats you have passed 
 The number of correctly answered questions:  17
 The number of incorrectly answered questions:  3
 Your grade is 85 %
 Congrats you have passed 
 The number of correctly answered questions:  18
 The number of incorrectly answered questions:  2
 Your grade is 90 %
 Congrats you have passed 
Traceback (most recent call last):
  File "a1.py", line 39, in <module>
    answerKey.close()
AttributeError: 'list' object has no attribute 'close'

The last error was because you had closed the array which was probably a file object at one point but you are pretty close. Just a small syntax error.

Short version, but does the job.

correct = ['B', 'D', 'A', 'A', 'C', 'A', 'B', 'A', 'C', 'D', 'B', 'C', 'D', 'A', 'D', 'C', 'C', 'B', 'D', 'A']
file_handler = open('student_answers.txt','r')
answers = file_handler.readlines()
valid = 0
for element in enumerate(correct):
    if answers[element[0]].rstrip("\n") == element[1]:
        valid += 1
if valid >= 15:
    print("Congrats, you passed with " + str((valid/20)*100) + "%")
else:
    print("Sorry, you failed with " + str((valid/20)*100) + "%")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM