Skip to content

Issue 138 - Adds functions to calculate the state distribution of a Match #717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions axelrod/interaction_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
interactions.
"""
import csv
from collections import Counter

from .game import Game
from axelrod import Actions
Expand Down Expand Up @@ -87,6 +88,57 @@ def compute_normalised_cooperation(interactions):
return normalised_cooperation


def compute_state_distribution(interactions):
"""
Returns the count of each state for a set of interactions.

Parameters
----------
interactions : list of tuples
A list containing the interactions of the match as shown at the top of
this file.

Returns
----------
Counter(interactions) : Counter Object
Dictionary where the keys are the states and the values are the number
of times that state occurs.
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring needs the full definition of the arguments and return value

if not interactions:
return None
return Counter(interactions)


def compute_normalised_state_distribution(interactions):
"""
Returns the normalized count of each state for a set of interactions.

Parameters
----------
interactions : list of tuples
A list containing the interactions of the match as shown at the top of
this file.

Returns
----------
normalized_count : Counter Object
Dictionary where the keys are the states and the values are a normalized
count of the number of times that state occurs.
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring needs to define arguments and return value

if not interactions:
return None

interactions_count = Counter(interactions)
total = sum(interactions_count.values(), 0.0)
# By starting the sum with 0.0 we make sure total is a floating point value,
# avoiding the Python 2 floor division behaviour of / with integer operands
# (Stack Overflow)

normalized_count = Counter({key: value / total for key, value in
interactions_count.items()})
return normalized_count
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might be a bit more 'pythonic' with a comprehension. I've not tested it, but something like:

interactions_count = Counter(interactions)
total = sum(interactions_count.values(), 0.0)
# By starting the sum with 0.0 we make sure total is a floating point value,
# avoiding the Python 2 floor division behaviour of / with integer operands (Stack Overflow)

return Counter({key: value / total for key, value in interactions_count.items()})



def sparkline(actions, c_symbol=u'█', d_symbol=u' '):
return u''.join([
c_symbol if play == 'C' else d_symbol for play in actions])
Expand Down
12 changes: 12 additions & 0 deletions axelrod/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,18 @@ def normalised_cooperation(self):
"""Returns the count of cooperations by each player per turn"""
return iu.compute_normalised_cooperation(self.result)

def state_distribution(self):
"""
Returns the count of each state for a set of interactions.
"""
return iu.compute_state_distribution(self.result)
Copy link
Member

@drvinceknight drvinceknight Sep 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have a brief docstring for these two methods (similar to the ones in the interactions_utils).


def normalised_state_distribution(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring needed here

"""
Returns the normalized count of each state for a set of interactions.
"""
return iu.compute_normalised_state_distribution(self.result)

def sparklines(self, c_symbol=u'█', d_symbol=u' '):
return iu.compute_sparklines(self.result, c_symbol, d_symbol)

Expand Down
17 changes: 17 additions & 0 deletions axelrod/tests/unit/test_interaction_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import unittest
import tempfile
from collections import Counter
import axelrod
import axelrod.interaction_utils as iu

Expand All @@ -17,6 +18,14 @@ class TestMatch(unittest.TestCase):
winners = [False, 0, 1, None]
cooperations = [(1, 1), (0, 2), (2, 1), None]
normalised_cooperations = [(.5, .5), (0, 1), (1, .5), None]
state_distribution = [Counter({('C', 'D'): 1, ('D', 'C'): 1}),
Counter({('D', 'C'): 2}),
Counter({('C', 'C'): 1, ('C', 'D'): 1}),
None]
normalised_state_distribution = [Counter({('C', 'D'): 0.5, ('D', 'C'): 0.5}),
Counter({('D', 'C'): 1.0}),
Counter({('C', 'C'): 0.5, ('C', 'D'): 0.5}),
None]
sparklines = [ u'█ \n █', u' \n██', u'██\n█ ', None ]


Expand Down Expand Up @@ -46,6 +55,14 @@ def test_compute_normalised_cooperations(self):
for inter, coop in zip(self.interactions, self.normalised_cooperations):
self.assertEqual(coop, iu.compute_normalised_cooperation(inter))

def test_compute_state_distribution(self):
for inter, dist in zip(self.interactions, self.state_distribution):
self.assertEqual(dist, iu.compute_state_distribution(inter))

def test_compute_normalised_state_distribution(self):
for inter, dist in zip(self.interactions, self.normalised_state_distribution):
self.assertEqual(dist, iu.compute_normalised_state_distribution(inter))

def test_compute_sparklines(self):
for inter, spark in zip(self.interactions, self.sparklines):
self.assertEqual(spark, iu.compute_sparklines(inter))
Expand Down