By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,852 Members | 955 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,852 IT Pros & Developers. It's quick & easy.

highscores list

P: n/a
I'm writing a game that uses two functions to check and see if a file
called highScoresList.txt exists in the main dir of the game program.
If it doesn, it creates one. That part is working fine. The problem is
arising when it goes to read in the high scores from the file when I
play again.

This is the error msg python is giving me

Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
main()
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 330, in main
if(hasHighScore(wins) == True):
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 175, in hasHighScore
scores[i],names[i] = string.split(line,"\t")
ValueError: need more than 1 value to unpack

Here's the relavant code:

def hasHighScore(score):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]

#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
names[i]=string.rstrip(names[i])
i += 1
infile.close()

#compares player's score with those in highScoresList.txt
i=0
for i in range(0,len(scores)):
if(score int(scores[i])):
return True
else:
return False

def setHighScores(score,name):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]

#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
scores[i]=int(scores[i])
names[i]=string.rstrip(names[i])
i += 1
infile.close()

#shuffles thru the highScoresList.txt and inserts player's score if
higher then those in file
i=len(scores)
while(score scores[i-1] and i>0):
i -= 1

scores.insert(i,score)
names.insert(i,name)
scores.pop(len(scores)-1)
names.pop(len(names)-1)

#writes new highScoresList.txt
outfile = open("highScoresList.txt","w")

outfile.write (" High Score Name \n")
outfile.write ("-------------------------------------------------\n")

i=0
for i in range(0,len(scores)):
outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
outfile.close()

And here's the call to the functions at the end of my game, included in
the error msg.

#adds player's score to high score list if high enough
if(hasHighScore(wins) == True):
setHighScores(wins,getName(wins))

And this is what the text file looks like when it happens.

High Score Name
-------------------------------------------------
15 SHAWN
0
0

The answer is probably simple, I've just been working on this program so
long that my brain has turned to mush. Any help would be much
appreciated...thanks.
Dec 8 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
On Dec 8, 8:32 pm, Shawn Minisall <trekker...@comcast.netwrote:
I'm writing a game that uses two functions to check and see if a file
called highScoresList.txt exists in the main dir of the game program.
If it doesn, it creates one. That part is working fine. The problem is
arising when it goes to read in the high scores from the file when I
play again.

This is the error msg python is giving me

Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
main()
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 330, in main
if(hasHighScore(wins) == True):
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 175, in hasHighScore
scores[i],names[i] = string.split(line,"\t")
ValueError: need more than 1 value to unpack

Here's the relavant code:

def hasHighScore(score):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]

#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
names[i]=string.rstrip(names[i])
i += 1
infile.close()

#compares player's score with those in highScoresList.txt
i=0
for i in range(0,len(scores)):
if(score int(scores[i])):
return True
else:
return False

def setHighScores(score,name):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]

#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
scores[i]=int(scores[i])
names[i]=string.rstrip(names[i])
i += 1
infile.close()

#shuffles thru the highScoresList.txt and inserts player's score if
higher then those in file
i=len(scores)
while(score scores[i-1] and i>0):
i -= 1

scores.insert(i,score)
names.insert(i,name)
scores.pop(len(scores)-1)
names.pop(len(names)-1)

#writes new highScoresList.txt
outfile = open("highScoresList.txt","w")

outfile.write (" High Score Name \n")
outfile.write ("-------------------------------------------------\n")

i=0
for i in range(0,len(scores)):
outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
outfile.close()

And here's the call to the functions at the end of my game, included in
the error msg.

#adds player's score to high score list if high enough
if(hasHighScore(wins) == True):
setHighScores(wins,getName(wins))

And this is what the text file looks like when it happens.

High Score Name
-------------------------------------------------
15 SHAWN
0
0

The answer is probably simple, I've just been working on this program so
long that my brain has turned to mush. Any help would be much
appreciated...thanks.
Your first two lines in your highscores file has no Tab Characters.
When reading the file you could do:

for (i, line) in file_input:
if i < 2:
continue

# do normal file parsing
There are better ways to structure your code though, but that's for
you.
Dec 8 '07 #2

P: n/a
I'm writing a game that uses two functions to check and see if a file
called highScoresList.txt exists in the main dir of the game program.
If it doesn, it creates one. That part is working fine. The problem is
arising when it goes to read in the high scores from the file when I
play again.

This is the error msg python is giving me

Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
main()
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 330, in main
if(hasHighScore(wins) == True):
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 175, in hasHighScore
scores[i],names[i] = string.split(line,"\t")
ValueError: need more than 1 value to unpack

for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
The error message is straightforward, you are trying to unpack a 1 value
tuple to 2 values

The reason it's a one value tuple is that your first line is this:
outfile.write (" High Score Name \n")
Running split('\t') on this will return a tuple of length one (since there
is no tab in that line)

Your code is also really unpythonic, take a look at this rewrite to see
what you could have done better:

def getHighScoreList():
scores = []
try:
highscore_file = list(open("highScoresList.txt"))
for line in highscore_file[2:]:
score, name = line.split('\t\t\t')
scores.append((int(score), name.rstrip()))
except IOError: # no highscore file yet
pass
return scores

def hasHighScore(score):
scores = [s for (s, n) in getHighScoreList()]
if scores:
return score min(scores)
return True

def setHighScores(newscore, newname):
max_scores = 3
scores = getHighScoreList()

for i, (score, name) in enumerate(scores):
if newscore score:
scores.insert(i, (newscore, newname))
break
else:
scores.append((newscore, newname))

outfile = open("highScoresList.txt","w")
outfile.write (" High Score Name \n")
outfile.write ("-------------------------------------------------\n")
for i in range(max_scores):
try:
score, name = scores[i]
except IndexError:
score, name = 0, ''
outfile.write("\t%s\t\t\t%s\n" % (score, name))
outfile.close()

if hasHighScore(wins):
setHighScores(wins, getName(wins))
Dec 8 '07 #3

P: n/a
On Dec 8, 10:07 pm, Chris <cwi...@gmail.comwrote:
On Dec 8, 8:32 pm, Shawn Minisall <trekker...@comcast.netwrote:
I'm writing a game that uses two functions to check and see if a file
called highScoresList.txt exists in the main dir of the game program.
If it doesn, it creates one. That part is working fine. The problem is
arising when it goes to read in the high scores from the file when I
play again.
This is the error msg python is giving me
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
main()
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 330, in main
if(hasHighScore(wins) == True):
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 175, in hasHighScore
scores[i],names[i] = string.split(line,"\t")
ValueError: need more than 1 value to unpack
Here's the relavant code:
def hasHighScore(score):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]
#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
names[i]=string.rstrip(names[i])
i += 1
infile.close()
#compares player's score with those in highScoresList.txt
i=0
for i in range(0,len(scores)):
if(score int(scores[i])):
return True
else:
return False
def setHighScores(score,name):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]
#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
scores[i]=int(scores[i])
names[i]=string.rstrip(names[i])
i += 1
infile.close()
#shuffles thru the highScoresList.txt and inserts player's score if
higher then those in file
i=len(scores)
while(score scores[i-1] and i>0):
i -= 1
scores.insert(i,score)
names.insert(i,name)
scores.pop(len(scores)-1)
names.pop(len(names)-1)
#writes new highScoresList.txt
outfile = open("highScoresList.txt","w")
outfile.write (" High Score Name \n")
outfile.write ("-------------------------------------------------\n")
i=0
for i in range(0,len(scores)):
outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
outfile.close()
And here's the call to the functions at the end of my game, included in
the error msg.
#adds player's score to high score list if high enough
if(hasHighScore(wins) == True):
setHighScores(wins,getName(wins))
And this is what the text file looks like when it happens.
High Score Name
-------------------------------------------------
15 SHAWN
0
0
The answer is probably simple, I've just been working on this program so
long that my brain has turned to mush. Any help would be much
appreciated...thanks.

Your first two lines in your highscores file has no Tab Characters.
When reading the file you could do:

for (i, line) in file_input:
if i < 2:
continue

# do normal file parsing

There are better ways to structure your code though, but that's for
you.
Apologies, I meant 'in enumerate(file_input)'
Dec 8 '07 #4

P: n/a
On Sat, 08 Dec 2007 13:32:08 -0500, Shawn Minisall wrote:
I'm writing a game that uses two functions to check and see if a file
called highScoresList.txt exists in the main dir of the game program. If
it doesn, it creates one. That part is working fine. The problem is
arising when it goes to read in the high scores from the file when I
play again.
Not your original problem, but you should want to look at this instead of
creating yet another parser:

http://docs.python.org/lib/RawConfigParser-objects.html

-Samuel
Dec 8 '07 #5

P: n/a
Shawn Minisall a écrit :
I'm writing a game that uses two functions to check and see if a file
called highScoresList.txt exists in the main dir of the game program.
If it doesn, it creates one. That part is working fine. The problem is
arising when it goes to read in the high scores from the file when I
play again.

This is the error msg python is giving me

Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
main()
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 330, in main
if(hasHighScore(wins) == True):
File "I:\PYTHON\PROJECT #3\PROJECT3.PYW", line 175, in hasHighScore
scores[i],names[i] = string.split(line,"\t")
ValueError: need more than 1 value to unpack

Here's the relavant code:

def hasHighScore(score):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
hardcoded file names are a bad idea. And FWIW, your file will be looked
for in the current wirking directory - which is not necessarily the
"main dir of the game program".
scores = [0,0,0]
names = ["","",""]

#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
You can iterate directly over the file.
scores[i],names[i] = string.split(line,"\t")
string.split(str, sep) is long time deprecated. Use str methods instead:
s, n = line.split('\t')

Also, this will obviously raise if the line doesn't have exactly one tab
in it. Like, ie, it's an empty line....
names[i]=string.rstrip(names[i])
i += 1
You can use enumerate(iterable) instead of manually counting lines.
Also, what if your file has more than 3 lines ?

infile.close()
#compares player's score with those in highScoresList.txt
i=0
for i in range(0,len(scores)):
You obviously don't know how to use Python's for loop:

for item in scores:
# now use item instead of scores[i]
if(score int(scores[i])):
return True
else:
return False
You have a logic error here. This will only compare the first item in
your score list. You want something like:

for item in score:
if score int(item):
return True
return False
>
def setHighScores(score,name):
#opens highScoresList.txt
infile = open("highScoresList.txt",'r')
scores = [0,0,0]
names = ["","",""]

#reads in scores from highScoresList.txt
i=0
for line in infile.readlines():
scores[i],names[i] = string.split(line,"\t")
scores[i]=int(scores[i])
names[i]=string.rstrip(names[i])
i += 1
infile.close()
hem... don't you see something like a duplication here ? By all mean
extract out this code in a 'read_scores' function.
#shuffles thru the highScoresList.txt and inserts player's score if
higher then those in file
i=len(scores)
while(score scores[i-1] and i>0):
i -= 1

scores.insert(i,score)
names.insert(i,name)
scores.pop(len(scores)-1)
names.pop(len(names)-1)
OMG.

This is ten times more complicated than it needs to be.
#writes new highScoresList.txt
outfile = open("highScoresList.txt","w")

outfile.write (" High Score Name \n")
outfile.write ("-------------------------------------------------\n")

i=0
for i in range(0,len(scores)):
outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
If your file is formated that way, no surprise your code breaks. None of
what you write in it matches the expectations of the code that reads it.
outfile.close()
And here's the call to the functions at the end of my game, included in
the error msg.

#adds player's score to high score list if high enough
if(hasHighScore(wins) == True):
setHighScores(wins,getName(wins))
And you're doing two times the same parsing of the file....
The answer is probably simple,
The answer to your question is indeed quite simple : either rewrite the
code that reads the file to make it matches what you wrote in the file,
or rewrite the code that writes the file to make it match the
expectations of the code that reads it. IOW : make both parts of the
code work on a same file format !-)

Also, learning to make effective use of Python's features would help !-)

Here's a possible reimplementation of your code - not tested, so it may
have bugs, but it should do the trick.

The file format is a very simple 'score:name' per line. Nothing else.
(heck, this file is for storing data, it's not meant to be seen by the
user).

The hiscore file full path must be passed when instantiating the
Hiscores object (that is, when initializing your program - you just need
one Hiscore object for the whole lifetime of your program). You must
also pass the max number of hiscores you want to keep, and an optional
flag telling if an error while reading the hiscore file should raise an
exception or be ignored (ending up using an empty hiscore list).

hiscores = HiScores('/path/to/your/file.ext', 3)

Once done, you just use it:

if hiscores.update(42, 'bibi'):
print "Yay, your a boss"
else:
print "try again..."
# hiscores.py
import sys

def _read_scores(path):
f = open(path)
# we don't expect a huge file so it's simpler to
# read it all in memory
lines = f.readlines()
f.close()

scores = []
for line in filter(None, map(str.strip, lines)):
try:
score, name = line.split(':')
score = int(score)
except ValueError, e:
# either the lines was not score:name or
# score wasn't a proper value for an int
err = "File %s : incorrect file format" \
% path
raise ValueError(err)
else:
scores.append((score, name))

# supposed to be already sorted, but we want to be sure.
# NB : natural sort will do the RightThing(tm) here
scores.sort()
return scores

def _write_scores(path, scores):
scores = "\n".join(["%s:%s" % item for item in scores])
f = open(path, 'w')
f.write(scores)
f.close()

class HiScores(object):
def __init__(self, path, nb_scores, raise_on_error=False):
self._path = path
self._nb_scores = nb_scores
try:
self._scores = _read_scores(path)[0:self.nb_scores - 1]
except (IOError, ValueError), e:
if raise_on_error:
raise
else:
# log the error
err = "Error while reading hiscore file %s : %s" \
% (path, e)
print >sys.stderr, err
# use an empty list instead
self._scores = []

def index(self, score):
for i, s in enumerate(self._scores):
if score s[0]:
return i
return -1

def update(self, score, name):
index = self.index(score)
if index == -1:
return False

self._scores.insert(index, (score, name))
self._scores.pop()
_write_scores(self._path, self._scores)
return True

def is_hi_score(self, score):
return self.index(score) -1

HTH
Dec 8 '07 #6

P: n/a
Bruno Desthuilliers a écrit :
(snip)
# hiscores.py
import sys

def _read_scores(path):
f = open(path)
# we don't expect a huge file so it's simpler to
# read it all in memory
lines = f.readlines()
f.close()

scores = []
for line in filter(None, map(str.strip, lines)):
try:
score, name = line.split(':')
score = int(score)
except ValueError, e:
# either the lines was not score:name or
# score wasn't a proper value for an int
err = "File %s : incorrect file format" \
% path
raise ValueError(err)
else:
scores.append((score, name))

# supposed to be already sorted, but we want to be sure.
# NB : natural sort will do the RightThing(tm) here
scores.sort()
oops ! missing line here:

score.reverse()
return scores
Dec 8 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.