Skip to content

Commit c8b5755

Browse files
committed
Add summarise and write_summary to resultset
Addresses one part of #701 At the moment I've just included the following tournament results: - Rank - Name - Score - Cooperation rating - Wins Easy enough to add more.
1 parent ffb0574 commit c8b5755

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ Axelrod.egg-info
1111
basic_strategies.csv
1212
cache.txt
1313
test.csv
14+
summary.csv
1415
basic_tournament.csv

axelrod/result_set.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import csv
22
import tqdm
33

4+
from collections import namedtuple
45
from numpy import mean, nanmedian, std
56

67
from . import eigen
@@ -696,6 +697,53 @@ def __eq__(self, other):
696697
def __ne__(self, other):
697698
return not self.__eq__(other)
698699

700+
def summarise(self):
701+
"""
702+
Obtain summary of performance of each strategy:
703+
ordered by rank, including median normalised score and cooperation
704+
rating.
705+
706+
Output
707+
------
708+
709+
A list of the form:
710+
711+
[[player name, median score, cooperation_rating],...]
712+
713+
"""
714+
715+
median_scores = map(nanmedian, self.normalised_scores)
716+
median_wins = map(nanmedian, self.wins)
717+
718+
self.player = namedtuple("Player", ["Rank", "Name", "Median_score",
719+
"Cooperation_rating", "Wins"])
720+
721+
summary_data = [perf for perf in zip(self.players,
722+
median_scores,
723+
self.cooperating_rating,
724+
median_wins)]
725+
summary_data = [self.player(rank, *summary_data[i]) for
726+
rank, i in enumerate(self.ranking)]
727+
728+
return summary_data
729+
730+
def write_summary(self, filename):
731+
"""
732+
Write a csv file containing summary data of the results of the form:
733+
734+
"Rank", "Name", "Median-score-per-turn", "Cooperation-rating"
735+
736+
Parameters
737+
----------
738+
filename : a filepath to which to write the data
739+
"""
740+
summary_data = self.summarise()
741+
with open(filename, 'w') as csvfile:
742+
writer = csv.writer(csvfile)
743+
writer.writerow(self.player._fields)
744+
for player in summary_data:
745+
writer.writerow(player)
746+
699747

700748
class ResultSetFromFile(ResultSet):
701749
"""

axelrod/tests/unit/test_resultset.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import axelrod
33
import axelrod.interaction_utils as iu
44

5-
from numpy import mean, std
5+
from numpy import mean, std, nanmedian
66

77
import tempfile
8+
import csv
89

910
from hypothesis import given, settings
1011
from axelrod.tests.property import tournaments, prob_end_tournaments
@@ -384,6 +385,46 @@ def test_equality(self):
384385
results = tournament.play()
385386
self.assertNotEqual(results, rs_sets[0])
386387

388+
def test_summarise(self):
389+
rs = axelrod.ResultSet(self.players, self.interactions,
390+
progress_bar=False)
391+
sd = rs.summarise()
392+
393+
self.assertEqual(len(sd), len(rs.players))
394+
self.assertEqual([str(player.Name) for player in sd], rs.ranked_names)
395+
self.assertEqual([int(player.Rank) for player in sd],
396+
list(range(len(self.players))))
397+
398+
ranked_median_scores = [list(map(nanmedian, rs.normalised_scores))[i]
399+
for i in rs.ranking]
400+
self.assertEqual([float(player.Median_score) for player in sd],
401+
ranked_median_scores)
402+
403+
ranked_cooperation_rating = [rs.cooperating_rating[i]
404+
for i in rs.ranking]
405+
self.assertEqual([float(player.Cooperation_rating) for player in sd],
406+
ranked_cooperation_rating)
407+
408+
ranked_median_wins = [nanmedian(rs.wins[i]) for i in rs.ranking]
409+
self.assertEqual([float(player.Wins) for player in sd],
410+
ranked_median_wins)
411+
412+
def test_write_summary(self):
413+
tmp_file = tempfile.NamedTemporaryFile()
414+
rs = axelrod.ResultSet(self.players, self.interactions,
415+
progress_bar=False)
416+
rs.write_summary(filename=tmp_file.name)
417+
with open(tmp_file.name, "r") as csvfile:
418+
ranked_names = []
419+
csvreader = csv.reader(csvfile)
420+
for row in csvreader:
421+
ranked_names.append(row[1])
422+
self.assertEqual(len(row), 5)
423+
self.assertEqual(ranked_names[0], "Name")
424+
self.assertEqual(ranked_names[1:], rs.ranked_names)
425+
426+
427+
387428

388429
class TestResultSetFromFile(unittest.TestCase):
389430
tmp_file = tempfile.NamedTemporaryFile(mode='w', delete=False)

docs/tutorials/getting_started/tournament_results.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,29 @@ of the cooperation rating::
233233
[0.57..., 0.0, 0.57..., 0.57...]
234234

235235
For more information about these see :ref:`morality-metrics`.
236+
237+
Summarising a tournament
238+
------------------------
239+
240+
The results set can also return a list of named tuples, ordered by strategy rank
241+
that summarises the results of the tournament::
242+
243+
>>> summary = results.summarise()
244+
>>> pprint.pprint(summary)
245+
[Player(Rank=0, Name='Defector', Median_score=2.6..., Cooperation_rating=0.0, Wins=3.0),
246+
Player(Rank=1, Name='Tit For Tat', Median_score=2.3..., Cooperation_rating=0.7, Wins=0.0),
247+
Player(Rank=2, Name='Grudger', Median_score=2.3..., Cooperation_rating=0.7, Wins=0.0),
248+
Player(Rank=3, Name='Cooperator', Median_score=2.0..., Cooperation_rating=1.0, Wins=0.0)]
249+
250+
It is also possible to write this data directly to a csv file using the
251+
`write_summary` method::
252+
253+
>>> results.write_summary('summary.csv')
254+
>>> with open('summary.csv', 'r') as outfile:
255+
... out = outfile.read()
256+
>>> pprint.pprint(out)
257+
('Rank,Name,Median_score,Cooperation_rating,Wins\n'
258+
'0,Defector,2.6,0.0,3.0\n'
259+
'1,Tit For Tat,2.3,0.7,0.0\n'
260+
'2,Grudger,2.3,0.7,0.0\n'
261+
'3,Cooperator,2.0,1.0,0.0\n')

0 commit comments

Comments
 (0)