Search code examples
pythonfilesentinel

Python Sentinel Loop to create a Text File


I am trying to figure out how to create a sentinel code to allow the user to input a name and test score that will be listed in a text file. I just need the names to be in column one and scores in column two of the text file. I tried having the name and grade as a single input but was given errors. I am still getting an error for the code below.

Enter the students’ name and test score. Store entered data in a text file named Class.txt, and close the file. Use an empty string as a sentinel to stop the data entry. Make sure that program will accept only correct data for the student’s test scores.

def main():
    outfile = open("Class.txt", 'w')

    count = 0
    student = input("Please enter a student's last name (<Enter> to quit): ")
    grade = eval(input("Please enter the student's grade (<Enter> to quit): "))
    while student != "" and grade != "":
        count = count + 1
        student = input("Please enter a student's last name (<Enter> to quit): ")
        grade = eval(input("Please enter the student's grade (<Enter> to quit): "))
        print(student, grade, file = outfile)

    outfile.close()

main()

error:

  grade = eval(input("Please enter the student's grade (<Enter> to quit): "))
  File "<string>", line 0

    ^
SyntaxError: unexpected EOF while parsing

Solution

  • You are sending an un-sanitized user input to eval - this is a very unsafe practice, and it is also what's causing an error when you try to use the sentinel (empty input for grade). You should not really be asking for grade if the name is empty.

    To avoid repetition, you should place you should place your input calls in a function:

    def get_data():
        student = input("Please enter a student's last name (<Enter> to quit): ")
        if student:
            grade = input("Please enter the student's grade (<Enter> to quit): ")
            if grade.isdigit():
                return (student, int(grade))
        return (None, None)
    

    I added an implicit sentinel - if grade is not an natural number, then the loop will stop, too.

    Then, you loop would look like this:

    (student, grade) = get_data()
    while student:
        print(student, grade, file = outfile)
        (student, grade) = get_data()
    

    Note that I swapped the order of the input and output in the main loop, since in your original code the first input would have not been processed.