I have a couple of issues with my lab assignment for this week. I was wondering if you guys could help. I will post the assignment and then post my code thus far. Thank you.

)Write a program that will display the menu below until user decide the quit the program.

High Score Keepers
0 - Quit
1 - List Scores
2 - Add a Score

b) For the option Quit- if the user select this option they will be prompted to exit the program

c) List Scores - if user select this option the program should read from a text file and display in a list format the user name and score.
e.g.
High Scores
Mark 4500
Amanda 3400

d) Add a score
If user enter this option the user should enter the player's name and score.
Next your program should sort the information by player's score. Your program should keep only the top 5 scores and write this to a text file.

e) If a player enters a choice other than 0,1 or 2 your program should display an error message to the user.

f) Exactly how you choose to format the file will be left up to you this time. However, you must use a delimiter of some kind to separate the name and score values in the text file.

-My issues are when I select option 2 it gives me an error from the
line = inFile.readline() , I don't understand this since that line is in a totally different if statement.

-My other issue is that I need to loop the menu, but if I put the user input variable (option) in the function I can't call it in my if statements.

-option 0 and 1 all work perfectly fine on their own.
Thank you.

#Lab 9: High Scores Keeper
import sys
mitems = ["0 - Quit",
          "1 - List Scores",
          "2 - Add a Score"]
def menu():
    print ("High Score Keeper")
    print (mitems[0])
    print (mitems[1])
    print (mitems[2])
    option = raw_input("Please choose an option (0-2): ")

menu()
    
if option == "0":
    quit = raw_input("Are you sure you would like to quit? (Y/N): ")
    if quit == "y" or quit == "Y":
        sys.exit(0)
    elif quit == "n" or quit == "N":
        menu()
    else:
        print ("Invalid Response: Reloading Main Menu")
        menu()

if option == "1":
    inFile = open ("highscores.txt", "r")
while True:
    line = inFile.readline()
    if line == "": break   #reached the end of the data file
    line = line.rstrip ('\n') #remove trailing linefeed
    line = line.strip() #remove leading and trailing blanks
    if line.isdigit():
        score = int(line)
        print score
    else:
        name = line
        print name
inFile.close()

menu()

if option == "2":
    eName = raw_input("Enter player's name: ")
    eScore = raw_input("Enter player's score: ")
    add = []
    add.append(eName)
    add.append(eScore)
    print add

Edited 7 Years Ago by hockfan86: Trying to get code tags to work.

High Score Keeper
0 - Quit
1 - List Scores
2 - Add a Score
Please choose an option (0-2): 2
Traceback (most recent call last):
File "/Users/benjaminholcomb/NetBeansProjects/lab9/src/lab9.py", line 34, in <module>
line = inFile.readline()
NameError: name 'inFile' is not defined

Edited 7 Years Ago by hockfan86: n/a

Okay, first of all you need to learn a bit about scope:
http://www.network-theory.co.uk/docs/pytut/PythonScopesandNameSpaces.html
That is basically where a variable lives, so you have the problem that when you call menu() the variable option doesn't stay in memory after that function is completed. But don't fret :) that can be fixed very easily.

def menu():
    print ("High Score Keeper")
    print (mitems[0])
    print (mitems[1])
    print (mitems[2])
    return raw_input("Please choose an option (0-2): ")

option = menu()

See how i added a return? That means that the value is returned to the variable...

Sorry, i would help further, buut its dinner time :P

High Score Keeper
0 - Quit
1 - List Scores
2 - Add a Score
Please choose an option (0-2): 2
Traceback (most recent call last):
File "/Users/benjaminholcomb/NetBeansProjects/lab9/src/lab9.py", line 34, in <module>
line = inFile.readline()
NameError: name 'inFile' is not defined

Your program does not know inFile because it is tucked in under option "1". However your while loop is not part of the statement block. So it tries to execute.

Edited 7 Years Ago by vegaseat: n/a

Thanks to the above helpers, I have solved a few of my issues. To Vegaseat: Yeah, I assumed that was what was happening, but the thing is when I move the infile = open statement it completely messes up my program. So I'm trying to find a way to more efficiently perform those operations. The operations in option 1 definitely do exactly what I want them too, its just it errors the rest of the program lol.

Usually it is good practice to test the data structure and handling of the program you write. Something simple like this with some test prints ...

test_data = """\
Mark 4500
Amanda 3400
Paul 3700
"""

fname = "highscores.txt"

# write the testfile
fout = open(fname, "w")
fout.write(test_data)
fout.close()

# read the testfile
fin = open(fname, "r")
raw_score_list = fin.readlines()
fin.close()

print( raw_score_list )  # test

print( '-'*50 )

# convert the raw score_list to a list of (name, score) tuples
score_list = []
for item in raw_score_list:
    name, score = item.split()
    score_list.append( (name, score) )

print( score_list )  # test

print( '-'*50 )

# display the score list
print( "%-10s %-10s" % ("Name", "Score") )
for name, item in score_list:
    print( "%-10s %-10s" % (name, item) )

# add to the score list
name = "Frank"
score = "4400"
score_list.append( (name, score) )

print( '-'*50 )

# display the modified score list
print( "%-10s %-10s" % ("Name", "Score") )
for name, item in score_list:
    print( "%-10s %-10s" % (name, item) )

"""my output -->
['Mark 4500\n', 'Amanda 3400\n', 'Paul 3700\n']
--------------------------------------------------
[('Mark', '4500'), ('Amanda', '3400'), ('Paul', '3700')]
--------------------------------------------------
Name       Score     
Mark       4500      
Amanda     3400      
Paul       3700      
--------------------------------------------------
Name       Score     
Mark       4500      
Amanda     3400      
Paul       3700      
Frank      4400      
"""

I used the print() function so the code will work in Python2 and Python3.

Now you can design your specific program around it. Remember you have to read your present data file first if you want to list the data or append/add to the data.

Edited 7 Years Ago by vegaseat: n/a

Vegaseat, I like that formatting and also took away a few ways I could make my code more efficient. I still cannot figure out where to put the either the fileInput and/or the line = fileInput.readline() to fix the error while selecting options 0 or 2. I have tried a number of solutions moving the lines in and out of various loops in my program to no avail.

Ok, I got a lot of my issues fixed however I cannot figure out how to add user input added names and scores to the list in the code below, I also can't figure out how to get the whole list to write to the new file highscores.txt. When I select option 2 it only writes one name and score to the text file.

if option == "2":

    while True:
        lines = inFile.readline()
        if lines == "": break   #reached the end of the data file
        lines = lines.rstrip ('\n') #remove trailing linefeed
        lines = lines.strip() #remove leading and trailing blanks
        scoresD = []
        if lines.isdigit():
            scores = lines
            scoresD = [scores]
        else:
            names = lines
            scoresD.append(names)
        outFile = open("topscores.txt", "w")
        outFile.write(str(scoresD))

    inFile.close()
    outFile.close()

I fixed the above issue, thank you. Now to add the sorting to the list, which should be difficult lol.

#Lab 9: High Scores Keeper
#All options work independently, most work in succession
#Option 2 only writes full list if you select it first
#Couldn't figure out sort method on option 2 in time
import sys
#Declare list for menu function
mitems = ["0 - Quit",
          "1 - List Scores",
          "2 - Add a Score"]
#Declare function to print menu and take user's option
def menu():
    print ("High Score Keeper")
    print (mitems[0])
    print (mitems[1])
    print (mitems[2])
    return raw_input("Please choose an option (0-2): ")

option = menu()
#If statements based on user option choice
#Option 0 for quit function
if option == "0":
    quit = raw_input("Are you sure you would like to quit? (Y/N): ")
    if quit == "y" or quit == "Y":
        sys.exit(0)
    elif quit == "n" or quit == "N":
        option = menu()
    else:
        print ("Invalid Response: Reloading Main Menu")
        option = menu()
#Read in list of high scores for use with option 1 and 2
inFile = open ("highscores.txt", "r")
if option == "1":
  
    while True:
        line = inFile.readline()
        if line == "": break   #reached the end of the data file
        line = line.rstrip ('\n') #remove trailing linefeed
        line = line.strip() #remove leading and trailing blanks
        if line.isdigit():
            score = int(line)
            print score
        else:
            name = line
            print name
    option = menu()
#Open new file to write in added scores
outFile = open("topscores.txt", "w")
if option == "2":

    while True:
        lines = inFile.readline()
        if lines == "": break   #reached the end of the data file
        lines = lines.rstrip ('\n') #remove trailing linefeed
        lines = lines.strip() #remove leading and trailing blanks
        scoresD = []
        if lines.isdigit():
            scores = lines
            scoresD = [scores]
        else:
            names = lines
            scoresD.append(names)
        outFile.write(str(scoresD))
    while True:
        eName = raw_input("Enter player's name: ")
        eScore = raw_input("Enter player's score: ")
        scoresE = [eName, eScore]
        outFile.write(str(scoresE))
        finish = raw_input("Would you like to quit? (y/n): ")
        if finish == "n":
            option = menu()
        else:
            break
    inFile.close()
    outFile.close()
This article has been dead for over six months. Start a new discussion instead.