[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