[Tutor] files - strings - lists (continued)
Andrzej Kolinski
AKolinski at nriindustries.com
Mon Dec 5 15:26:37 CET 2005
I used Kent's hints and suggestions but now I'm facing a problem of how
to calculate final results from the retrieved data. My script, at this
stage, opens _all_ game results files, gets an individual player's name,
calculates his score and keeps the number of boards played. It does it per
_each_ _game_ _individually_. What I would like to do is to calculate his
ranking as a: (sum of all scores)/(sum of all boards).
I have no clue how to combine results from, let's say, 3 games and use it
for the above calculations. Below are: the copy of the script (under
construction) and the sample of the data available:
#################################
import glob, string
resultsFileName = 'butler.txt'
resultsFile = open(resultsFileName,"w")
resultsFile.write('----------------------------------\nImie i
Nazwisko\t\tBUTLER\n---------------------------------\n')
for f in glob.glob("*.sbk"): # Get all text files and loop over them
try:
filecontents = open(f,'r')
filecontents.next()
filecontents.next()
header = filecontents.next().split()
hands = int(header[2])
rounds = int(header[3])
boards = hands*rounds
filecontents.next()
except IOError:
# If something went wrong, ignore this file
continue
allScores = {}
try: # you don't say how you know the end of the names, I just run
to the end of data
while True:
names = filecontents.next().strip().split()
player1 = names[0]
player2 = names[2]
filecontents.next() # skip line after name
scores = [ int(filecontents.next().split()[2]) for i in
range(rounds) ]
tScores = 0
for i in scores:
iScore = float(i)
tScores = float(sum(scores))
allScores.setdefault(player1, []).append((tScores, boards))
allScores.setdefault(player2, []).append((tScores, boards))
except: # no more lines
if filecontents.next() == '1,1':
pass
for player1, tScores in allScores.items():
print player1, tScores
score = tScores[0][0]
played = tScores[0][1]
butler = score/played
#print ("%1.4f") %butler
line = "%s\t\t%1.4f" %(player1, butler)
#print line
resultsFile.write(line + '\n')
filecontents.close()
resultsFile.close()
####################################################
Chrabalowski [(21.0, 24)]
Kowalski [(-8.0, 24)]
Kolinski [(31.0, 24)]
.........................
Chrabalowski [(45.0, 25)]
Orlicka [(-27.0, 25)]
KempaM [(5.0, 25)]
........................
Chrabalowski [(-23.0, 25)]
Lukasik [(-24.0, 25)]
Szczerbowski [(31.0, 25)]
As you can see Chrabalowski played in all three games. His current score
should be calculated like this:
finalButler = (21.0 + 45.0 -23.0)/(24 + 25 + 25), which is 0.5811 by the
way.
Is the individual db appropriate for this or I should be looking for a
dictionary type format. I am lost.
_/_/ _/ _/
_/ _/ _/ _/
_/_/_/_/ _/ _/
_/ _/ _/ _/
_/ _/ _/ _/
Andrzej Kolinski
Kent Johnson <kent37 at tds.net>
Sent by: tutor-bounces at python.org
24/11/2005 08:40 PM
To
cc
tutor at python.org
Subject
Re: [Tutor] files - strings - lists
Andrzej Kolinski wrote:
>
> OK, I made some progress I think. I added a few lines to Kent's script
> to get closer what I really am after:
Congratulations! See some notes below.
>
> ==========================================
> lines = open('liga050926.sbk') # to get the data from a real file
>
> #lines = iter(data) # getting data from a string, you don't need this
> when reading a file
>
> lines.next() # skip two headers
> lines.next()
>
> header = lines.next().split()
> hands = int(header[2])
> rounds = int(header[3])
> boards = hands*rounds
>
> lines.next()
>
>
> allScores = {} # accumulate scores into a dictionary whose key is the
name
>
> # Now we can process the names and scores in a loop
> try: # you don't say how you know the end of the names, I just run to
> the end of data
> while True:
> names = lines.next().strip()
> player1 = names.split()[0]
> player2 = names.split()[2]
This could be
names = lines.next().strip().split()
player1 = names[0]
player2 = names[2]
or even
player1, player2 = lines.next().strip().split(' - ')
>
> lines.next() # skip line after name
> scores = [ int(lines.next().split()[2]) for i in range(rounds) ]
> tScores = 0
> for i in scores:
> iScore = float(i)
> tScores = tScores + iScore
This could be
tScores = float(sum(scores))
>
> allScores[player1] = tScores/boards
> allScores[player2] = tScores/boards
>
> except: # no more lines
> if lines.next() == '1,1':
> pass
I'm not sure what the two lines above are doing? It looks like you don't
have a good way to detect the end of the data and you just catch some
exception...you should figure out a clean way to exit the loop. Maybe when
you read the names line you can look for '1,1' and break out of the loop,
if that is what always follows the data you care about.
>
> for player1, tScores in allScores.items():
> print player1, tScores
> =============================================
> 1. I singled out the players names.
> 2. I added the players scores and divided by the number of boards
> played.
> 3. The output contents is what I wanted:
>
> Chrabalowski 0.875
> Kowalski -0.333333333333
> Kolinski 1.29166666667
> Bohossian 1.29166666667
> Stankiewicz -1.16666666667
> Cwir -0.708333333333 ...
>
> 4. The next step for me would be to read the data from more,
> similar files (from 2 to 10) representing different games and generate
> an average score for each participating player (a player does not
> necessary plays each game and I would eventually like to calculate
> averages of best six out of maximum ten games). Tough! How should I
> start this next step? (I would like to keep both options open:
> final ranking = (all tScores)/all boards), or
> final ranking = average(RScores/boards, RScores/boards,
> RScores/boards, ...)
> game1
> game2 game3)
I would save more data for each player. Instead of just keeping the
average for the player, I would keep a list of pairs of (tScore, boards)
for each game. Instead of
allScores[player1] = tScores/boards
you could say
playerScores = allScores.get(player1, [])
playerScores.append( (tScores, boards) )
allScores[player1] = playerScores
all of which can be written more tersely (and obscurely) as
allScores.setdefault(player1, []).append( (tScores, boards) )
Of course you need a loop to read all the files and you will initialize
allScores before the loop. Then when you finish with the files you can
retrieve the players' stats and process them either way you want.
BTW what game is this? It seems odd that both players get the same score.
>
> Thanks Kent, Chris and Danny. After many, many months of using or
> modifying (and using) existing scripts, with your invaluable help I feel
> I can write script that is original and extremely useful to me!
Glad to hear it!
Kent
_______________________________________________
Tutor maillist - Tutor at python.org
http://mail.python.org/mailman/listinfo/tutor
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20051205/1387f949/attachment.html
More information about the Tutor
mailing list