From 91be90f7112813928e859cadb48c63e77d6b4ee6 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Sat, 6 Aug 2016 20:13:23 -0700 Subject: [PATCH 01/11] Remove unused imports --- axelrod/ecosystem.py | 1 - axelrod/match.py | 1 - axelrod/result_set.py | 8 -------- axelrod/strategies/adaptive.py | 2 +- axelrod/strategies/apavlov.py | 2 +- axelrod/strategies/averagecopier.py | 2 -- axelrod/strategies/axelrod_first.py | 3 +-- axelrod/strategies/calculator.py | 2 -- axelrod/strategies/finite_state_machines.py | 2 +- axelrod/strategies/gambler.py | 5 ++--- axelrod/strategies/handshake.py | 2 +- axelrod/strategies/memoryone.py | 1 - axelrod/strategies/rand.py | 2 +- axelrod/tests/unit/test_averagecopier.py | 2 -- axelrod/tests/unit/test_calculator.py | 2 -- axelrod/tests/unit/test_gambler.py | 2 -- axelrod/tests/unit/test_grudger.py | 2 -- axelrod/tests/unit/test_punisher.py | 3 --- axelrod/tests/unit/test_resultset.py | 1 - 19 files changed, 8 insertions(+), 37 deletions(-) diff --git a/axelrod/ecosystem.py b/axelrod/ecosystem.py index 16fc32e25..0aa821ce2 100644 --- a/axelrod/ecosystem.py +++ b/axelrod/ecosystem.py @@ -1,4 +1,3 @@ - import random diff --git a/axelrod/match.py b/axelrod/match.py index e399ee88a..745e082c4 100644 --- a/axelrod/match.py +++ b/axelrod/match.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from axelrod import Actions, Game from .deterministic_cache import DeterministicCache diff --git a/axelrod/result_set.py b/axelrod/result_set.py index 4ec6fa1f3..0f94e498e 100644 --- a/axelrod/result_set.py +++ b/axelrod/result_set.py @@ -1,4 +1,3 @@ -from collections import defaultdict import csv import tqdm @@ -8,13 +7,6 @@ from .game import Game import axelrod.interaction_utils as iu -try: - # Python 2 - from StringIO import StringIO -except ImportError: - # Python 3 - from io import StringIO - def update_progress_bar(method): """A decorator to update a progress bar if it exists""" diff --git a/axelrod/strategies/adaptive.py b/axelrod/strategies/adaptive.py index 131cc6d11..774a06711 100644 --- a/axelrod/strategies/adaptive.py +++ b/axelrod/strategies/adaptive.py @@ -1,4 +1,4 @@ -from axelrod import Actions, Player, Game, init_args +from axelrod import Actions, Player, init_args C, D = Actions.C, Actions.D diff --git a/axelrod/strategies/apavlov.py b/axelrod/strategies/apavlov.py index 9bcf3d878..f18b552ba 100644 --- a/axelrod/strategies/apavlov.py +++ b/axelrod/strategies/apavlov.py @@ -1,4 +1,4 @@ -from axelrod import Actions, Player, flip_action +from axelrod import Actions, Player C, D = Actions.C, Actions.D diff --git a/axelrod/strategies/averagecopier.py b/axelrod/strategies/averagecopier.py index 052c08238..30078d771 100644 --- a/axelrod/strategies/averagecopier.py +++ b/axelrod/strategies/averagecopier.py @@ -1,5 +1,3 @@ -import random - from axelrod import Actions, Player, random_choice diff --git a/axelrod/strategies/axelrod_first.py b/axelrod/strategies/axelrod_first.py index 83414137b..392cde9be 100644 --- a/axelrod/strategies/axelrod_first.py +++ b/axelrod/strategies/axelrod_first.py @@ -2,10 +2,9 @@ Additional strategies from Axelrod's first tournament. """ -from math import sqrt import random -from axelrod import Actions, Game, Player, init_args, flip_action, random_choice +from axelrod import Actions, Player, init_args, flip_action, random_choice from.memoryone import MemoryOnePlayer diff --git a/axelrod/strategies/calculator.py b/axelrod/strategies/calculator.py index 80d0cf0d3..e5e339070 100644 --- a/axelrod/strategies/calculator.py +++ b/axelrod/strategies/calculator.py @@ -1,5 +1,3 @@ -import itertools - from axelrod import Actions, Player from .axelrod_first import Joss from axelrod._strategy_utils import detect_cycle diff --git a/axelrod/strategies/finite_state_machines.py b/axelrod/strategies/finite_state_machines.py index 1c231d43e..2bd8fcd3d 100644 --- a/axelrod/strategies/finite_state_machines.py +++ b/axelrod/strategies/finite_state_machines.py @@ -1,4 +1,4 @@ -from axelrod import Actions, Player, Game, init_args +from axelrod import Actions, Player, init_args C, D = Actions.C, Actions.D diff --git a/axelrod/strategies/gambler.py b/axelrod/strategies/gambler.py index d4af8ed1f..e74ac891a 100644 --- a/axelrod/strategies/gambler.py +++ b/axelrod/strategies/gambler.py @@ -1,5 +1,3 @@ -from itertools import product - from axelrod import Actions, Player, init_args, random_choice from axelrod.strategy_transformers import FinalTransformer from .lookerup import LookerUp, create_lookup_table_keys @@ -8,7 +6,8 @@ C, D = Actions.C, Actions.D -@FinalTransformer((D, D), name_prefix=None) # End with two defections if tournament length is known +# End with two defections if tournament length is known +@FinalTransformer((D, D), name_prefix=None) class Gambler(LookerUp): """ A LookerUp class player which will select randomly an action in some cases. diff --git a/axelrod/strategies/handshake.py b/axelrod/strategies/handshake.py index e11bfc98a..b1314eff6 100644 --- a/axelrod/strategies/handshake.py +++ b/axelrod/strategies/handshake.py @@ -1,4 +1,4 @@ -from axelrod import Actions, Player, Game, init_args +from axelrod import Actions, Player, init_args C, D = Actions.C, Actions.D diff --git a/axelrod/strategies/memoryone.py b/axelrod/strategies/memoryone.py index 42fe8c379..2ef48fa5f 100644 --- a/axelrod/strategies/memoryone.py +++ b/axelrod/strategies/memoryone.py @@ -1,5 +1,4 @@ from axelrod import Actions, Player, init_args, random_choice -import copy """IPD Strategies: http://www.prisoners-dilemma.com/strategies.html""" diff --git a/axelrod/strategies/rand.py b/axelrod/strategies/rand.py index 9b6a733a0..c612741bb 100644 --- a/axelrod/strategies/rand.py +++ b/axelrod/strategies/rand.py @@ -1,4 +1,4 @@ -from axelrod import Actions, Player, init_args, random_choice +from axelrod import Player, init_args, random_choice class Random(Player): diff --git a/axelrod/tests/unit/test_averagecopier.py b/axelrod/tests/unit/test_averagecopier.py index 1b676356b..0796585b6 100644 --- a/axelrod/tests/unit/test_averagecopier.py +++ b/axelrod/tests/unit/test_averagecopier.py @@ -1,7 +1,5 @@ """Test for the average_copier strategy.""" -import random - import axelrod from .test_player import TestPlayer diff --git a/axelrod/tests/unit/test_calculator.py b/axelrod/tests/unit/test_calculator.py index 6c7684d7a..204627a2a 100644 --- a/axelrod/tests/unit/test_calculator.py +++ b/axelrod/tests/unit/test_calculator.py @@ -1,7 +1,5 @@ """Tests for calculator strategies.""" -import random - import axelrod from .test_player import TestPlayer diff --git a/axelrod/tests/unit/test_gambler.py b/axelrod/tests/unit/test_gambler.py index c59bb8d3d..81b96eda1 100755 --- a/axelrod/tests/unit/test_gambler.py +++ b/axelrod/tests/unit/test_gambler.py @@ -4,9 +4,7 @@ """ import axelrod -import random from .test_player import TestPlayer, TestHeadsUp -from axelrod import random_choice, Actions import copy diff --git a/axelrod/tests/unit/test_grudger.py b/axelrod/tests/unit/test_grudger.py index 2bf536ae4..7f661e4ef 100644 --- a/axelrod/tests/unit/test_grudger.py +++ b/axelrod/tests/unit/test_grudger.py @@ -1,7 +1,5 @@ """Tests for grudger strategies.""" -import random - import axelrod from .test_player import TestPlayer diff --git a/axelrod/tests/unit/test_punisher.py b/axelrod/tests/unit/test_punisher.py index 7aabf2950..291f90288 100644 --- a/axelrod/tests/unit/test_punisher.py +++ b/axelrod/tests/unit/test_punisher.py @@ -1,7 +1,5 @@ """Test for the punisher strategy.""" -import random - import axelrod from .test_player import TestPlayer @@ -116,4 +114,3 @@ def test_reset_method(self): self.assertEqual(P1.history, []) self.assertEqual(P1.grudged, False) self.assertEqual(P1.grudge_memory, 0) - \ No newline at end of file diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index cfbec1429..c0e8427f6 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -5,7 +5,6 @@ from numpy import mean, std import tempfile -import os from hypothesis import given, settings from axelrod.tests.property import tournaments, prob_end_tournaments From 1325f80c1918d68e47253438d42d05bce754e596 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Sat, 6 Aug 2016 20:43:03 -0700 Subject: [PATCH 02/11] Spacing and whitespacing --- axelrod/strategies/apavlov.py | 8 +-- axelrod/strategies/backstabber.py | 2 +- axelrod/strategies/calculator.py | 1 + axelrod/strategies/cooperator.py | 1 + axelrod/strategies/darwin.py | 1 + axelrod/strategies/gambler.py | 8 +-- axelrod/strategies/inverse.py | 1 + axelrod/strategies/lookerup.py | 28 +++++----- axelrod/strategies/mathematicalconstants.py | 9 ++-- axelrod/strategies/memoryone.py | 4 +- axelrod/strategies/meta.py | 51 ++++++++++--------- axelrod/strategies/mindcontrol.py | 1 + axelrod/strategies/oncebitten.py | 2 +- axelrod/strategies/punisher.py | 2 +- axelrod/strategies/qlearner.py | 1 + axelrod/strategies/titfortat.py | 21 ++++---- axelrod/tests/unit/test_axelrod_second.py | 3 +- axelrod/tests/unit/test_backstabber.py | 8 +-- axelrod/tests/unit/test_cooperator.py | 4 +- .../tests/unit/test_deterministic_cache.py | 1 - axelrod/tests/unit/test_gambler.py | 15 +++--- axelrod/tests/unit/test_grumpy.py | 8 +-- axelrod/tests/unit/test_handshake.py | 2 +- axelrod/tests/unit/test_hunter.py | 22 ++++---- axelrod/tests/unit/test_inverse.py | 6 +-- axelrod/tests/unit/test_lookerup.py | 41 ++++++++------- axelrod/tests/unit/test_memoryone.py | 1 - axelrod/tests/unit/test_meta.py | 27 +++++----- axelrod/tests/unit/test_plot.py | 10 ++-- axelrod/tests/unit/test_prober.py | 8 +-- axelrod/tests/unit/test_punisher.py | 5 +- .../tests/unit/test_strategy_transformers.py | 1 - doctests.py | 5 +- 33 files changed, 150 insertions(+), 158 deletions(-) diff --git a/axelrod/strategies/apavlov.py b/axelrod/strategies/apavlov.py index f18b552ba..9fb462da5 100644 --- a/axelrod/strategies/apavlov.py +++ b/axelrod/strategies/apavlov.py @@ -51,7 +51,7 @@ def strategy(self, opponent): if self.opponent_class == "STFT": if len(self.history) % 6 in [0, 1]: return C - #TFT + # TFT if opponent.history[-1:] == [D]: return D if self.opponent_class == "PavlovD": @@ -59,7 +59,7 @@ def strategy(self, opponent): if len(self.history) % 6 == 0: return D if self.opponent_class == "Cooperative": - #TFT + # TFT if opponent.history[-1:] == [D]: return D return C @@ -112,10 +112,10 @@ def strategy(self, opponent): if self.opponent_class in ["Random", "ALLD"]: return D if self.opponent_class == "STFT": - #TFTT + # TFTT return D if opponent.history[-2:] == [D, D] else C if self.opponent_class == "Cooperative": - #TFT + # TFT return D if opponent.history[-1:] == [D] else C def reset(self): diff --git a/axelrod/strategies/backstabber.py b/axelrod/strategies/backstabber.py index 2ad17a504..52c938f09 100644 --- a/axelrod/strategies/backstabber.py +++ b/axelrod/strategies/backstabber.py @@ -4,7 +4,7 @@ C, D = Actions.C, Actions.D -@FinalTransformer((D, D), name_prefix=None) # End with two defections +@FinalTransformer((D, D), name_prefix=None) # End with two defections class BackStabber(Player): """ Forgives the first 3 defections but on the fourth diff --git a/axelrod/strategies/calculator.py b/axelrod/strategies/calculator.py index e5e339070..cad559ba8 100644 --- a/axelrod/strategies/calculator.py +++ b/axelrod/strategies/calculator.py @@ -2,6 +2,7 @@ from .axelrod_first import Joss from axelrod._strategy_utils import detect_cycle + class Calculator(Player): """ Plays like (Hard) Joss for the first 20 rounds. If periodic behavior is diff --git a/axelrod/strategies/cooperator.py b/axelrod/strategies/cooperator.py index 5bbdf3325..c09567cd3 100644 --- a/axelrod/strategies/cooperator.py +++ b/axelrod/strategies/cooperator.py @@ -2,6 +2,7 @@ C, D = Actions.C, Actions.D + class Cooperator(Player): """A player who only ever cooperates.""" diff --git a/axelrod/strategies/darwin.py b/axelrod/strategies/darwin.py index 1c74cbd65..addc46a4b 100644 --- a/axelrod/strategies/darwin.py +++ b/axelrod/strategies/darwin.py @@ -3,6 +3,7 @@ C, D = Actions.C, Actions.D + class Darwin(Player): """ A strategy which accumulates a record (the 'genome') of what the most favourable response in the previous round should have been, and naively diff --git a/axelrod/strategies/gambler.py b/axelrod/strategies/gambler.py index e74ac891a..5dbff1ad5 100644 --- a/axelrod/strategies/gambler.py +++ b/axelrod/strategies/gambler.py @@ -31,10 +31,10 @@ def __init__(self, lookup_table=None): """ if not lookup_table: lookup_table = { - ('', 'C', 'D') : 0, - ('', 'D', 'D') : 0, - ('', 'C', 'C') : 1, - ('', 'D', 'C') : 1, + ('', 'C', 'D'): 0, + ('', 'D', 'D'): 0, + ('', 'C', 'C'): 1, + ('', 'D', 'C'): 1, } LookerUp.__init__(self, lookup_table=lookup_table, value_length=None) diff --git a/axelrod/strategies/inverse.py b/axelrod/strategies/inverse.py index 33bdf5785..f73bc41c8 100644 --- a/axelrod/strategies/inverse.py +++ b/axelrod/strategies/inverse.py @@ -2,6 +2,7 @@ C, D = Actions.C, Actions.D + class Inverse(Player): """A player who defects with a probability that diminishes relative to how long ago the opponent defected.""" diff --git a/axelrod/strategies/lookerup.py b/axelrod/strategies/lookerup.py index bf8ee4ac6..8518cde73 100644 --- a/axelrod/strategies/lookerup.py +++ b/axelrod/strategies/lookerup.py @@ -32,10 +32,10 @@ class LookerUp(Player): where m and n are both zero. Tit-For-Tat is given by: { - ('', 'C', 'D') : D, - ('', 'D', 'D') : D, - ('', 'C', 'C') : C, - ('', 'D', 'C') : C, + ('', 'C', 'D'): D, + ('', 'D', 'D'): D, + ('', 'C', 'C'): C, + ('', 'D', 'C'): C, } where m=1 and n=0. @@ -45,12 +45,10 @@ class LookerUp(Player): tuple. For example, this fragment of a dict: { - ... - ('C', 'C', 'C') : C. - ('D', 'C', 'C') : D, + ('C', 'C', 'C'): C. + ('D', 'C', 'C'): D, ... - } states that if self and opponent both cooperated on the previous turn, we @@ -62,12 +60,10 @@ class LookerUp(Player): Below is an incomplete example where m=3 and n=2. { - ... - ('CC', 'CDD', 'CCC') : C. - ('CD', 'CCD', 'CCC') : D, + ('CC', 'CDD', 'CCC'): C. + ('CD', 'CCD', 'CCC'): D, ... - } """ @@ -90,10 +86,10 @@ def __init__(self, lookup_table=None, value_length=1): if not lookup_table: lookup_table = { - ('', 'C', 'D') : D, - ('', 'D', 'D') : D, - ('', 'C', 'C') : C, - ('', 'D', 'C') : C, + ('', 'C', 'D'): D, + ('', 'D', 'D'): D, + ('', 'C', 'C'): C, + ('', 'D', 'C'): C, } self.lookup_table = lookup_table diff --git a/axelrod/strategies/mathematicalconstants.py b/axelrod/strategies/mathematicalconstants.py index 77aabd327..3926855b0 100644 --- a/axelrod/strategies/mathematicalconstants.py +++ b/axelrod/strategies/mathematicalconstants.py @@ -32,21 +32,24 @@ def strategy(self, opponent): class Golden(CotoDeRatio): - """The player will always aim to bring the ratio of co-operations to defections closer to the golden mean""" + """The player will always aim to bring the ratio of co-operations to + defections closer to the golden mean""" name = '$\phi$' ratio = (1 + sqrt(5)) / 2 class Pi(CotoDeRatio): - """The player will always aim to bring the ratio of co-operations to defections closer to the pi""" + """The player will always aim to bring the ratio of co-operations to + defections closer to the pi""" name = '$\pi$' ratio = pi class e(CotoDeRatio): - """The player will always aim to bring the ratio of co-operations to defections closer to the e""" + """The player will always aim to bring the ratio of co-operations to + defections closer to the e""" name = '$e$' ratio = e diff --git a/axelrod/strategies/memoryone.py b/axelrod/strategies/memoryone.py index 2ef48fa5f..82673116a 100644 --- a/axelrod/strategies/memoryone.py +++ b/axelrod/strategies/memoryone.py @@ -63,7 +63,7 @@ def strategy(self, opponent): return self._initial # Determine which probability to use p = self._four_vector[(self.history[-1], opponent.history[-1])] - # Draw a random number in [0,1] to decide + # Draw a random number in [0, 1] to decide return random_choice(p) @@ -83,7 +83,7 @@ class WinStayLoseShift(MemoryOnePlayer): @init_args def __init__(self, initial=C): Player.__init__(self) - self.set_four_vector([1,0,0,1]) + self.set_four_vector([1, 0, 0, 1]) self._initial = initial diff --git a/axelrod/strategies/meta.py b/axelrod/strategies/meta.py index 1e8372b9d..f4bb40ebc 100644 --- a/axelrod/strategies/meta.py +++ b/axelrod/strategies/meta.py @@ -1,6 +1,8 @@ from axelrod import Actions, Player, obey_axelrod from ._strategies import all_strategies -from .hunter import DefectorHunter, AlternatorHunter, RandomHunter, MathConstantHunter, CycleHunter, EventualCycleHunter +from .hunter import ( + DefectorHunter, AlternatorHunter, RandomHunter, MathConstantHunter, + CycleHunter, EventualCycleHunter) from .cooperator import Cooperator from numpy.random import choice @@ -8,11 +10,11 @@ ordinary_strategies = [s for s in all_strategies if obey_axelrod(s)] C, D = Actions.C, Actions.D + class MetaPlayer(Player): """A generic player that has its own team of players.""" name = "Meta Player" - team = [Cooperator] classifier = { 'memory_depth': float('inf'), # Long memory @@ -24,7 +26,6 @@ class MetaPlayer(Player): } def __init__(self): - super(MetaPlayer, self).__init__() # Make sure we don't use any meta players to avoid infinite recursion. @@ -45,7 +46,6 @@ def __init__(self): self.classifier['makes_use_of'].update(t.classifier['makes_use_of']) def strategy(self, opponent): - # Make sure the history of all hunters is current. for ih in range(len(self.team)): self.team[ih].history = self.history @@ -117,9 +117,9 @@ class MetaWinner(MetaPlayer): name = "Meta Winner" def __init__(self, team=None): - - # The default is to use all strategies available, but we need to import the list - # at runtime, since _strategies import also _this_ module before defining the list. + # The default is to use all strategies available, but we need to import + # the list at runtime, since _strategies import also _this_ module + # before defining the list. if team: self.team = team else: @@ -136,7 +136,6 @@ def __init__(self, team=None): t.score = 0 def strategy(self, opponent): - # Update the running score for each player, before determining the next move. if len(self.history): for player in self.team: @@ -147,15 +146,15 @@ def strategy(self, opponent): return super(MetaWinner, self).strategy(opponent) def meta_strategy(self, results, opponent): - scores = [pl.score for pl in self.team] bestscore = max(scores) beststrategies = [i for i, pl in enumerate(self.team) if pl.score == bestscore] bestproposals = [results[i] for i in beststrategies] bestresult = C if C in bestproposals else D - # Update each player's proposed history with his proposed result, but always after - # the new result has been settled based on scores accumulated until now. + # Update each player's proposed history with his proposed result, but + # always after the new result has been settled based on scores + # accumulated until now. for r, t in zip(results, self.team): t.proposed_history.append(r) @@ -180,25 +179,27 @@ class MetaHunter(MetaPlayer): } def __init__(self): - # Notice that we don't include the cooperator hunter, because it leads to excessive - # defection and therefore bad performance against unforgiving strategies. We will stick - # to hunters that use defections as cues. However, a really tangible benefit comes from - # combining Random Hunter and Math Constant Hunter, since together they catch strategies - # that are lightly randomized but still quite constant (the tricky/suspecious ones). + # Notice that we don't include the cooperator hunter, because it leads + # to excessive defection and therefore bad performance against + # unforgiving strategies. We will stick to hunters that use defections + # as cues. However, a really tangible benefit comes from combining + # Random Hunter and Math Constant Hunter, since together they catch + # strategies that are lightly randomized but still quite constant + # (the tricky/suspicious ones). self.team = [DefectorHunter, AlternatorHunter, RandomHunter, MathConstantHunter, CycleHunter, EventualCycleHunter] super(MetaHunter, self).__init__() @staticmethod def meta_strategy(results, opponent): - # If any of the hunters smells prey, then defect! if D in results: return D - # Tit-for-tat might seem like a better default choice, but in many cases it complicates - # the heuristics of hunting and creates fale-positives. So go ahead and use it, but only - # for longer histories. + # Tit-for-tat might seem like a better default choice, but in many + # cases it complicates the heuristics of hunting and creates + # false-positives. So go ahead and use it, but only for longer + # histories. if len(opponent.history) > 100: return D if opponent.history[-1:] == [D] else C else: @@ -231,6 +232,7 @@ class MetaMajorityFiniteMemory(MetaMajority): """MetaMajority with the team of Finite Memory Players""" name = "Meta Majority Finite Memory" + def __init__(self): team = [s for s in ordinary_strategies if s().classifier['memory_depth'] < float('inf')] @@ -242,6 +244,7 @@ class MetaWinnerFiniteMemory(MetaWinner): """MetaWinner with the team of Finite Memory Players""" name = "Meta Winner Finite Memory" + def __init__(self): team = [s for s in ordinary_strategies if s().classifier['memory_depth'] < float('inf')] @@ -253,6 +256,7 @@ class MetaMajorityLongMemory(MetaMajority): """MetaMajority with the team of Long (infinite) Memory Players""" name = "Meta Majority Long Memory" + def __init__(self): team = [s for s in ordinary_strategies if s().classifier['memory_depth'] == float('inf')] @@ -264,6 +268,7 @@ class MetaWinnerLongMemory(MetaWinner): """MetaWinner with the team of Long (infinite) Memory Players""" name = "Meta Winner Long Memory" + def __init__(self): team = [s for s in ordinary_strategies if s().classifier['memory_depth'] == float('inf')] @@ -299,9 +304,9 @@ class MetaMixer(MetaPlayer): } def __init__(self, team=None, distribution=None): - - # The default is to use all strategies available, but we need to import the list - # at runtime, since _strategies import also _this_ module before defining the list. + # The default is to use all strategies available, but we need to import + # the list at runtime, since _strategies import also _this_ module + # before defining the list. if team: self.team = team else: diff --git a/axelrod/strategies/mindcontrol.py b/axelrod/strategies/mindcontrol.py index 380425f14..99e1d1b19 100644 --- a/axelrod/strategies/mindcontrol.py +++ b/axelrod/strategies/mindcontrol.py @@ -2,6 +2,7 @@ C, D = Actions.C, Actions.D + class MindController(Player): """A player that changes the opponents strategy to cooperate.""" diff --git a/axelrod/strategies/oncebitten.py b/axelrod/strategies/oncebitten.py index 39f392b1b..4cdc422f2 100644 --- a/axelrod/strategies/oncebitten.py +++ b/axelrod/strategies/oncebitten.py @@ -93,7 +93,7 @@ class ForgetfulFoolMeOnce(Player): } @init_args - def __init__(self, forget_probability = 0.05): + def __init__(self, forget_probability=0.05): """ Parameters ---------- diff --git a/axelrod/strategies/punisher.py b/axelrod/strategies/punisher.py index c841fd41c..9b586b6c4 100644 --- a/axelrod/strategies/punisher.py +++ b/axelrod/strategies/punisher.py @@ -13,7 +13,7 @@ class Punisher(Player): name = 'Punisher' classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, diff --git a/axelrod/strategies/qlearner.py b/axelrod/strategies/qlearner.py index 0bf980203..f16f28f48 100644 --- a/axelrod/strategies/qlearner.py +++ b/axelrod/strategies/qlearner.py @@ -5,6 +5,7 @@ C, D = Actions.C, Actions.D + class RiskyQLearner(Player): """A player who learns the best strategies through the q-learning algorithm. diff --git a/axelrod/strategies/titfortat.py b/axelrod/strategies/titfortat.py index 24cd4ec30..517197b41 100644 --- a/axelrod/strategies/titfortat.py +++ b/axelrod/strategies/titfortat.py @@ -385,13 +385,13 @@ def reset(self): class SlowTitForTwoTats(Player): """ - A player plays C twice, then if the opponent plays the same move twice, - plays that move + A player plays C twice, then if the opponent plays the same move twice, + plays that move """ name = 'Slow Tit For Two Tats' classifier = { - 'memory_depth': 2, + 'memory_depth': 2, 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, @@ -400,17 +400,14 @@ class SlowTitForTwoTats(Player): } def strategy(self, opponent): - - #Start with two cooperations + + # Start with two cooperations if len(self.history) < 2: return C - - #Mimic if opponent plays the same move twice + + # Mimic if opponent plays the same move twice if opponent.history[-2] == opponent.history[-1]: return opponent.history[-1] - - #Otherwise cooperate - return C - - + # Otherwise cooperate + return C diff --git a/axelrod/tests/unit/test_axelrod_second.py b/axelrod/tests/unit/test_axelrod_second.py index f863b4115..6c609c281 100644 --- a/axelrod/tests/unit/test_axelrod_second.py +++ b/axelrod/tests/unit/test_axelrod_second.py @@ -21,7 +21,6 @@ class TestChampion(TestPlayer): 'manipulates_state': False } - def test_strategy(self): # Initially cooperates self.first_play_test(C) @@ -38,7 +37,7 @@ def test_strategy(self): self.responses_test(my_responses, random_sample, [random_sample[-1]]) my_responses.append(random_sample[-1]) - random_sample.append(random.choice([C,D])) + random_sample.append(random.choice([C, D])) # Cooperate unless the opponent defected, has defected at least 40% of # the time, and with a random choice diff --git a/axelrod/tests/unit/test_backstabber.py b/axelrod/tests/unit/test_backstabber.py index c0aa37119..f755457ff 100644 --- a/axelrod/tests/unit/test_backstabber.py +++ b/axelrod/tests/unit/test_backstabber.py @@ -33,13 +33,13 @@ def test_strategy(self): tournament_length=200) # Defects on rounds 199, and 200 no matter what - self.responses_test([C] * 197 , [C] * 197, [C, D, D], + self.responses_test([C] * 197, [C] * 197, [C, D, D], tournament_length=200) # Test that exceeds tournament length - self.responses_test([C] * 198 , [C] * 198, [D, D, C], + self.responses_test([C] * 198, [C] * 198, [D, D, C], tournament_length=200) # But only if the tournament is known - self.responses_test([C] * 198 , [C] * 198, [C, C, C], + self.responses_test([C] * 198, [C] * 198, [C, C, C], tournament_length=-1) @@ -80,5 +80,5 @@ def test_strategy(self): tournament_length=200) # Defects on rounds 199, and 200 no matter what - self.responses_test([C] * 197 , [C] * 197, [C, D, D], + self.responses_test([C] * 197, [C] * 197, [C, D, D], tournament_length=200) diff --git a/axelrod/tests/unit/test_cooperator.py b/axelrod/tests/unit/test_cooperator.py index 61fe0e6cc..a45c291c7 100644 --- a/axelrod/tests/unit/test_cooperator.py +++ b/axelrod/tests/unit/test_cooperator.py @@ -51,5 +51,5 @@ def test_effect_of_strategy(self): self.responses_test([C, C, C], [C, C, C], [D]) self.responses_test([C, C, C, D, D], [C, C, C, C, D], [C]) history = [C, C, C, D, D] + [C] * 11 - opponent_histroy = [C, C, C, C, D] + [D] + [C] * 10 - self.responses_test(history, opponent_histroy,[D]) + opponent_history = [C, C, C, C, D] + [D] + [C] * 10 + self.responses_test(history, opponent_history, [D]) diff --git a/axelrod/tests/unit/test_deterministic_cache.py b/axelrod/tests/unit/test_deterministic_cache.py index c10564a91..184d0e755 100644 --- a/axelrod/tests/unit/test_deterministic_cache.py +++ b/axelrod/tests/unit/test_deterministic_cache.py @@ -103,4 +103,3 @@ def test_load_error_for_inccorect_format(self): with self.assertRaises(ValueError): cache = DeterministicCache() cache.load(tmp_file.name) - diff --git a/axelrod/tests/unit/test_gambler.py b/axelrod/tests/unit/test_gambler.py index 81b96eda1..2577778d2 100755 --- a/axelrod/tests/unit/test_gambler.py +++ b/axelrod/tests/unit/test_gambler.py @@ -17,7 +17,7 @@ class TestGambler(TestPlayer): player = axelrod.Gambler expected_classifier = { - 'memory_depth': 1, # Default TFT table + 'memory_depth': 1, # Default TFT table 'stochastic': True, 'makes_use_of': set(['length']), 'inspects_source': False, @@ -36,10 +36,10 @@ def test_init(self): # Test default table player = self.player() expected_lookup_table = { - ('', 'C', 'D') : 0, - ('', 'D', 'D') : 0, - ('', 'C', 'C') : 1, - ('', 'D', 'C') : 1, + ('', 'C', 'D'): 0, + ('', 'D', 'D'): 0, + ('', 'C', 'C'): 1, + ('', 'D', 'C'): 1, } self.assertEqual(player.lookup_table, expected_lookup_table) # Test malformed tables @@ -88,7 +88,7 @@ class TestPSOGambler(TestPlayer): def test_init(self): # Check for a few known keys - known_pairs = { ('CD', 'DD', 'DD'): 0.48, ('CD', 'CC', 'DD'): 0.67} + known_pairs = {('CD', 'DD', 'DD'): 0.48, ('CD', 'CC', 'DD'): 0.67} player = self.player() for k, v in known_pairs.items(): self.assertEqual(player.lookup_table[k], v) @@ -97,7 +97,7 @@ def test_strategy(self): """Starts by cooperating.""" self.first_play_test(C) # Defects on the last two rounds - self.responses_test([C] * 197 , [C] * 197, [C, D, D], + self.responses_test([C] * 197, [C] * 197, [C, D, D], tournament_length=200) @@ -116,7 +116,6 @@ def test_vs(self): class PSOGamblervsTFT(TestHeadsUp): def test_vs(self): - outcomes = zip() self.versus_test(axelrod.PSOGambler(), axelrod.TitForTat(), [C, C, C, C], [C, C, C, C]) diff --git a/axelrod/tests/unit/test_grumpy.py b/axelrod/tests/unit/test_grumpy.py index f61776ae0..c21974802 100644 --- a/axelrod/tests/unit/test_grumpy.py +++ b/axelrod/tests/unit/test_grumpy.py @@ -38,20 +38,20 @@ def test_strategy(self): Tests that grumpy will play c until threshold is ht at which point it will become grumpy. Player will then not become nice until lower nice threshold is hit. """ - P1 = axelrod.Grumpy(grumpy_threshold = 3, nice_threshold=0) + P1 = axelrod.Grumpy(grumpy_threshold=3, nice_threshold=0) P2 = TestOpponent() test_responses(self, P1, P2, [C, D, D, D], [C, C, C, C], [C]) - P1 = axelrod.Grumpy(grumpy_threshold = 3, nice_threshold=0) + P1 = axelrod.Grumpy(grumpy_threshold=3, nice_threshold=0) P2 = TestOpponent() test_responses(self, P1, P2, [C, C, D, D, D], [D, D, D, D, D], [D]) - P1 = axelrod.Grumpy(grumpy_threshold = 3, nice_threshold=0) + P1 = axelrod.Grumpy(grumpy_threshold=3, nice_threshold=0) P2 = TestOpponent() test_responses(self, P1, P2, [C, C, D, D, D, D, D, D], [D, D, D, D, D, C, C, C], [D]) - P1 = axelrod.Grumpy(grumpy_threshold = 3, nice_threshold=0) + P1 = axelrod.Grumpy(grumpy_threshold=3, nice_threshold=0) P2 = TestOpponent() test_responses(self, P1, P2, [C, C, D, D, D, D, D, D, D, D, D], [D, D, D, D, D, C, C, C, C, C, C], [C]) diff --git a/axelrod/tests/unit/test_handshake.py b/axelrod/tests/unit/test_handshake.py index dab6c4abd..0b02725c0 100644 --- a/axelrod/tests/unit/test_handshake.py +++ b/axelrod/tests/unit/test_handshake.py @@ -30,4 +30,4 @@ def test_strategy(self): self.responses_test([C, D], [D, D], [D] * 20) self.responses_test([C, D] * 2, [D, C] * 2, [D]) - self.responses_test([C, D] * 2, [C, D] * 2, [C]) \ No newline at end of file + self.responses_test([C, D] * 2, [C, D] * 2, [C]) diff --git a/axelrod/tests/unit/test_hunter.py b/axelrod/tests/unit/test_hunter.py index 03fc75db2..3d39835a3 100644 --- a/axelrod/tests/unit/test_hunter.py +++ b/axelrod/tests/unit/test_hunter.py @@ -37,7 +37,7 @@ class TestDefectorHunter(TestPlayer): player = axelrod.DefectorHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -57,7 +57,7 @@ class TestCooperatorHunter(TestPlayer): player = axelrod.CooperatorHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -77,7 +77,7 @@ class TestAlternatorHunter(TestPlayer): player = axelrod.AlternatorHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'inspects_source': False, 'makes_use_of': set(), 'manipulates_source': False, @@ -100,7 +100,7 @@ class TestCycleHunter(TestPlayer): player = axelrod.CycleHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -132,7 +132,7 @@ class TestEventualCycleHunter(TestPlayer): player = axelrod.CycleHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -150,7 +150,8 @@ def test_strategy(self): player.play(opponent) self.assertEqual(player.history[-1], D) # Test against non-cyclers and cooperators - for opponent in [axelrod.Random(), axelrod.AntiCycler(), axelrod.DoubleCrosser(), axelrod.Cooperator()]: + for opponent in [axelrod.Random(), axelrod.AntiCycler(), + axelrod.DoubleCrosser(), axelrod.Cooperator()]: player.reset() for i in range(50): player.play(opponent) @@ -163,7 +164,7 @@ class TestMathConstantHunter(TestPlayer): player = axelrod.MathConstantHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -180,7 +181,7 @@ class TestRandomHunter(TestPlayer): player = axelrod.RandomHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -189,10 +190,7 @@ class TestRandomHunter(TestPlayer): def test_strategy(self): - P1 = axelrod.RandomHunter() - P2 = axelrod.Player() - - # We should also catch the alternator here. + # We should catch the alternator here. self.responses_test([C] * 12, [C, D] * 6, [D]) # It is still possible for this test to fail, but very unlikely. diff --git a/axelrod/tests/unit/test_inverse.py b/axelrod/tests/unit/test_inverse.py index fccdb66d2..632c903f2 100644 --- a/axelrod/tests/unit/test_inverse.py +++ b/axelrod/tests/unit/test_inverse.py @@ -30,7 +30,8 @@ def test_strategy(self): def test_that_cooperate_if_opponent_has_not_defected(self): """ - Test that as long as the opponent has not defected the player will cooperate. + Test that as long as the opponent has not defected the player will + cooperate. """ self.responses_test([C] * 4, [C] * 4, [C]) self.responses_test([C] * 5, [C] * 5, [C]) @@ -48,9 +49,6 @@ def test_when_opponent_som_Ds(self): Tests that if opponent has played all D then player chooses D """ random.seed(5) - P1 = axelrod.Inverse() - P2 = axelrod.Player() - self.responses_test([C] * 4, [C, D, C, D], [C], random_seed=6) self.responses_test([C] * 6, [C, C, C, C, D, D], [C]) self.responses_test([C] * 9, [D] * 8 + [C], [D]) diff --git a/axelrod/tests/unit/test_lookerup.py b/axelrod/tests/unit/test_lookerup.py index ce447ae18..7bcbfcb76 100755 --- a/axelrod/tests/unit/test_lookerup.py +++ b/axelrod/tests/unit/test_lookerup.py @@ -34,10 +34,10 @@ def test_init(self): # Test default table player = self.player() expected_lookup_table = { - ('', 'C', 'D') : D, - ('', 'D', 'D') : D, - ('', 'C', 'C') : C, - ('', 'D', 'C') : C, + ('', 'C', 'D'): D, + ('', 'D', 'D'): D, + ('', 'C', 'C'): C, + ('', 'D', 'C'): C, } self.assertEqual(player.lookup_table, expected_lookup_table) # Test malformed tables @@ -62,10 +62,10 @@ def test_defector_table(self): constructor with the lookup table we want. """ defector_table = { - ('', C, D) : D, - ('', D, D) : D, - ('', C, C) : D, - ('', D, C) : D, + ('', C, D): D, + ('', D, D): D, + ('', C, C): D, + ('', D, C): D, } self.player = lambda : axelrod.LookerUp(defector_table) self.responses_test([C, C], [C, C], [D]) @@ -91,19 +91,19 @@ def test_starting_move(self): """A lookup table that always repeats the opponent's first move.""" first_move_table = { - # If oppponent starts by cooperating: - (C, C, D) : C, - (C, D, D) : C, - (C, C, C) : C, - (C, D, C) : C, + # If opponent starts by cooperating: + (C, C, D): C, + (C, D, D): C, + (C, C, C): C, + (C, D, C): C, # If opponent starts by defecting: - (D, C, D) : D, - (D, D, D) : D, - (D, C, C) : D, - (D, D, C) : D, + (D, C, D): D, + (D, D, D): D, + (D, C, C): D, + (D, D, C): D, } - self.player = lambda : axelrod.LookerUp(first_move_table) + self.player = lambda: axelrod.LookerUp(first_move_table) # if the opponent started by cooperating, we should always cooperate self.responses_test([C, C, C], [C, C, C], [C]) @@ -118,7 +118,6 @@ def test_starting_move(self): self.responses_test([C, C, D], [D, D, C], [D]) - class TestEvolvedLookerUp(TestPlayer): name = "EvolvedLookerUp" @@ -136,8 +135,8 @@ class TestEvolvedLookerUp(TestPlayer): def test_init(self): # Check for a few known keys known_pairs = {('DD', 'CC', 'CD'): 'D', ('DC', 'CD', 'CD'): 'C', - ('DD', 'CD', 'CD'): 'D', ('DC', 'DC', 'DC'): 'C', - ('DD', 'DD', 'CC'): 'D', ('CD', 'CC', 'DC'): 'C'} + ('DD', 'CD', 'CD'): 'D', ('DC', 'DC', 'DC'): 'C', + ('DD', 'DD', 'CC'): 'D', ('CD', 'CC', 'DC'): 'C'} player = self.player() for k, v in known_pairs.items(): self.assertEqual(player.lookup_table[k], v) diff --git a/axelrod/tests/unit/test_memoryone.py b/axelrod/tests/unit/test_memoryone.py index 107a61a02..67d0b5df6 100644 --- a/axelrod/tests/unit/test_memoryone.py +++ b/axelrod/tests/unit/test_memoryone.py @@ -75,7 +75,6 @@ def test_strategy(self): self.first_play_test(C) def test_four_vector(self): - player = self.player() (R, P, S, T) = Game().RPST() p = min(1 - float(T - R) / (R - S), float(R - P) / (T - P)) expected_dictionary = {(C, C): 1., (C, D): p, (D, C): 1., (D, D): p} diff --git a/axelrod/tests/unit/test_meta.py b/axelrod/tests/unit/test_meta.py index 258104833..20a817fc6 100644 --- a/axelrod/tests/unit/test_meta.py +++ b/axelrod/tests/unit/test_meta.py @@ -146,8 +146,7 @@ class TestMetaWinner(TestMetaPlayer): expected_class_classifier['makes_use_of'] = set([]) def test_strategy(self): - - P1 = axelrod.MetaWinner(team = [axelrod.Cooperator, axelrod.Defector]) + P1 = axelrod.MetaWinner(team=[axelrod.Cooperator, axelrod.Defector]) P2 = axelrod.Player() # This meta player will simply choose the strategy with the highest current score. @@ -164,19 +163,19 @@ def test_strategy(self): self.assertEqual(P1.strategy(P2), C) opponent = axelrod.Cooperator() - player = axelrod.MetaWinner(team = [axelrod.Cooperator, axelrod.Defector]) + player = axelrod.MetaWinner(team=[axelrod.Cooperator, axelrod.Defector]) for _ in range(5): player.play(opponent) self.assertEqual(player.history[-1], C) opponent = axelrod.Defector() - player = axelrod.MetaWinner(team = [axelrod.Defector]) + player = axelrod.MetaWinner(team=[axelrod.Defector]) for _ in range(20): player.play(opponent) self.assertEqual(player.history[-1], D) opponent = axelrod.Defector() - player = axelrod.MetaWinner(team = [axelrod.Cooperator, axelrod.Defector]) + player = axelrod.MetaWinner(team=[axelrod.Cooperator, axelrod.Defector]) for _ in range(20): player.play(opponent) self.assertEqual(player.history[-1], D) @@ -188,7 +187,7 @@ class TestMetaHunter(TestMetaPlayer): player = axelrod.MetaHunter expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False @@ -207,7 +206,8 @@ def test_strategy(self): self.responses_test([C] * 4, [D] * 4, [D]) self.responses_test([C] * 6, [C, D] * 3, [D]) self.responses_test([C] * 8, [C, C, C, D, C, C, C, D], [D]) - self.responses_test([C] * 100, [random.choice([C, D]) for i in range(100)],[D]) + self.responses_test([C] * 100, + [random.choice([C, D]) for i in range(100)], [D]) # Test post 100 rounds responses self.responses_test([C] * 101, [C] * 101, [C]) self.responses_test([C] * 101, [C] * 100 + [D], [D]) @@ -218,7 +218,7 @@ class TestMetaMajorityMemoryOne(TestMetaPlayer): player = axelrod.MetaMajorityMemoryOne expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : True, + 'stochastic': True, 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False @@ -257,7 +257,7 @@ class TestMetaMajorityFiniteMemory(TestMetaPlayer): player = axelrod.MetaMajorityFiniteMemory expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : True, + 'stochastic': True, 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False @@ -267,7 +267,6 @@ class TestMetaMajorityFiniteMemory(TestMetaPlayer): expected_class_classifier['stochastic'] = False expected_class_classifier['makes_use_of'] = set([]) - def test_strategy(self): self.first_play_test(C) @@ -277,7 +276,7 @@ class TestMetaWinnerFiniteMemory(TestMetaPlayer): player = axelrod.MetaWinnerFiniteMemory expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : True, + 'stochastic': True, 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False @@ -287,7 +286,6 @@ class TestMetaWinnerFiniteMemory(TestMetaPlayer): expected_class_classifier['stochastic'] = False expected_class_classifier['makes_use_of'] = set([]) - def test_strategy(self): self.first_play_test(C) @@ -297,7 +295,7 @@ class TestMetaMajorityLongMemory(TestMetaPlayer): player = axelrod.MetaMajorityLongMemory expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : True, + 'stochastic': True, 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False @@ -307,7 +305,6 @@ class TestMetaMajorityLongMemory(TestMetaPlayer): expected_class_classifier['stochastic'] = False expected_class_classifier['makes_use_of'] = set([]) - def test_strategy(self): self.first_play_test(C) @@ -317,7 +314,7 @@ class TestMetaWinnerLongMemory(TestMetaPlayer): player = axelrod.MetaWinnerLongMemory expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : True, + 'stochastic': True, 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False diff --git a/axelrod/tests/unit/test_plot.py b/axelrod/tests/unit/test_plot.py index 9f936627a..266bc1c6c 100644 --- a/axelrod/tests/unit/test_plot.py +++ b/axelrod/tests/unit/test_plot.py @@ -18,14 +18,14 @@ def setUpClass(cls): cls.players = (axelrod.Alternator(), axelrod.TitForTat(), axelrod.Defector()) cls.turns = 5 cls.matches = { - (0,1): [axelrod.Match((cls.players[0], cls.players[1]), + (0, 1): [axelrod.Match((cls.players[0], cls.players[1]), turns=cls.turns) for _ in range(3)], - (0,2): [axelrod.Match((cls.players[0], cls.players[2]), + (0, 2): [axelrod.Match((cls.players[0], cls.players[2]), turns=cls.turns) for _ in range(3)], - (1,2): [axelrod.Match((cls.players[1], cls.players[2]), + (1, 2): [axelrod.Match((cls.players[1], cls.players[2]), turns=cls.turns) for _ in range(3)]} - # This would not actually be a round robin tournament - # (no cloned matches) + # This would not actually be a round robin tournament + # (no cloned matches) cls.interactions = {} for index_pair, matches in cls.matches.items(): diff --git a/axelrod/tests/unit/test_prober.py b/axelrod/tests/unit/test_prober.py index 66667237c..10f777c1c 100644 --- a/axelrod/tests/unit/test_prober.py +++ b/axelrod/tests/unit/test_prober.py @@ -14,7 +14,7 @@ class TestProber(TestPlayer): player = axelrod.Prober expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -43,7 +43,7 @@ class TestProber2(TestPlayer): player = axelrod.Prober2 expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -72,7 +72,7 @@ class TestProber3(TestPlayer): player = axelrod.Prober3 expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -102,7 +102,7 @@ class TestHardProber(TestPlayer): player = axelrod.HardProber expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, diff --git a/axelrod/tests/unit/test_punisher.py b/axelrod/tests/unit/test_punisher.py index 291f90288..d7a3c65f5 100644 --- a/axelrod/tests/unit/test_punisher.py +++ b/axelrod/tests/unit/test_punisher.py @@ -12,7 +12,7 @@ class TestPunisher(TestPlayer): player = axelrod.Punisher expected_classifier = { 'memory_depth': float('inf'), # Long memory - 'stochastic' : False, + 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, @@ -103,9 +103,6 @@ def test_strategy(self): "mem_length": 16}) def test_reset_method(self): - """ - tests the reset method - """ P1 = axelrod.InversePunisher() P1.history = [C, D, D, D] P1.grudged = True diff --git a/axelrod/tests/unit/test_strategy_transformers.py b/axelrod/tests/unit/test_strategy_transformers.py index 4da71535d..852b02c44 100644 --- a/axelrod/tests/unit/test_strategy_transformers.py +++ b/axelrod/tests/unit/test_strategy_transformers.py @@ -237,7 +237,6 @@ def test_mixed(self): self.assertEqual(p1.history, [D, D, D, D, D]) # Decorating with list and distribution - # Decorate a cooperator putting all weight on other strategies that are # 'nice' probability = [.3, .2, 0] diff --git a/doctests.py b/doctests.py index 0143ba1f9..ebac3677e 100644 --- a/doctests.py +++ b/doctests.py @@ -7,8 +7,9 @@ def load_tests(loader, tests, ignore): for root, dirs, files in os.walk("./docs"): for f in files: if f.endswith(".rst"): - tests.addTests(doctest.DocFileSuite(os.path.join(root, f), - optionflags=doctest.ELLIPSIS)) + tests.addTests( + doctest.DocFileSuite(os.path.join(root, f), + optionflags=doctest.ELLIPSIS)) return tests From 54beea07ecc7d95424520cbaa4d57f739ecd3b8b Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Sat, 6 Aug 2016 20:58:46 -0700 Subject: [PATCH 03/11] Lookerup docstring --- axelrod/strategies/lookerup.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/axelrod/strategies/lookerup.py b/axelrod/strategies/lookerup.py index 8518cde73..c34cbfa6e 100644 --- a/axelrod/strategies/lookerup.py +++ b/axelrod/strategies/lookerup.py @@ -31,11 +31,10 @@ class LookerUp(Player): where m and n are both zero. Tit-For-Tat is given by: - { - ('', 'C', 'D'): D, - ('', 'D', 'D'): D, - ('', 'C', 'C'): C, - ('', 'D', 'C'): C, + {('', 'C', 'D'): D, + ('', 'D', 'D'): D, + ('', 'C', 'C'): C, + ('', 'D', 'C'): C, } where m=1 and n=0. @@ -44,11 +43,8 @@ class LookerUp(Player): opposed to most recent actions) will have a non-empty first string in the tuple. For example, this fragment of a dict: - { - ... - ('C', 'C', 'C'): C. - ('D', 'C', 'C'): D, - ... + {('C', 'C', 'C'): C, + ('D', 'C', 'C'): D, } states that if self and opponent both cooperated on the previous turn, we @@ -59,11 +55,8 @@ class LookerUp(Player): (so m or n are greater than 1), simply concatenate the strings together. Below is an incomplete example where m=3 and n=2. - { - ... - ('CC', 'CDD', 'CCC'): C. - ('CD', 'CCD', 'CCC'): D, - ... + {('CC', 'CDD', 'CCC'): C, + ('CD', 'CCD', 'CCC'): D, } """ From 88c037cc8715de06cbfad0ff6c9cc26c7d1b62e2 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Sat, 6 Aug 2016 21:09:42 -0700 Subject: [PATCH 04/11] Fix tempfile closing in tournament --- axelrod/tournament.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/axelrod/tournament.py b/axelrod/tournament.py index 5680e2315..2e9e5541f 100644 --- a/axelrod/tournament.py +++ b/axelrod/tournament.py @@ -111,6 +111,8 @@ def play(self, build_results=True, filename=None, if build_results: return self._build_result_set(progress_bar=progress_bar, keep_interactions=keep_interactions) + else: + self.outputfile.close() def _build_result_set(self, progress_bar=True, keep_interactions=False): """ From a195a4deec095441f0608115c196f84e609a113f Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Sat, 6 Aug 2016 22:08:49 -0700 Subject: [PATCH 05/11] Lookerup docstring modification to make travis happy --- axelrod/strategies/lookerup.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/axelrod/strategies/lookerup.py b/axelrod/strategies/lookerup.py index c34cbfa6e..ac44cc51e 100644 --- a/axelrod/strategies/lookerup.py +++ b/axelrod/strategies/lookerup.py @@ -15,9 +15,11 @@ class LookerUp(Player): opponents first n actions, self's last m actions, and opponents last m actions, all as strings. The values are the actions to play on this round. For example, in the case of m=n=1, if - - the opponent started by playing C - - my last action was a C the opponents - - last action was a D + + * the opponent started by playing C + * my last action was a C the opponents + * last action was a D + then the corresponding key would be ('C', 'C', 'D') From 27128eaf10d2d6588c4604a9be921ff4511c9e54 Mon Sep 17 00:00:00 2001 From: Vince Knight Date: Sun, 7 Aug 2016 10:03:33 +0100 Subject: [PATCH 06/11] Fix sphinx build warning/error. --- axelrod/strategies/lookerup.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/axelrod/strategies/lookerup.py b/axelrod/strategies/lookerup.py index ac44cc51e..0b4e7d388 100644 --- a/axelrod/strategies/lookerup.py +++ b/axelrod/strategies/lookerup.py @@ -33,11 +33,10 @@ class LookerUp(Player): where m and n are both zero. Tit-For-Tat is given by: - {('', 'C', 'D'): D, - ('', 'D', 'D'): D, - ('', 'C', 'C'): C, - ('', 'D', 'C'): C, - } + {('', 'C', 'D'): D, + ('', 'D', 'D'): D, + ('', 'C', 'C'): C, + ('', 'D', 'C'): C} where m=1 and n=0. @@ -45,9 +44,8 @@ class LookerUp(Player): opposed to most recent actions) will have a non-empty first string in the tuple. For example, this fragment of a dict: - {('C', 'C', 'C'): C, - ('D', 'C', 'C'): D, - } + {('C', 'C', 'C'): C, + ('D', 'C', 'C'): D} states that if self and opponent both cooperated on the previous turn, we should cooperate this turn unless the opponent started by defecting, in @@ -57,9 +55,9 @@ class LookerUp(Player): (so m or n are greater than 1), simply concatenate the strings together. Below is an incomplete example where m=3 and n=2. - {('CC', 'CDD', 'CCC'): C, - ('CD', 'CCD', 'CCC'): D, - } + {('CC', 'CDD', 'CCC'): C, + ('CD', 'CCD', 'CCC'): D} + """ name = 'LookerUp' From 865b083e6d6ab42ee1c228311227fc67e9c235e7 Mon Sep 17 00:00:00 2001 From: Vince Knight Date: Sun, 7 Aug 2016 10:06:15 +0100 Subject: [PATCH 07/11] Improve formatting of the docstring when sphinx'd This is what it looks like on master: https://www.dropbox.com/s/9vsr067ag67c445/Screenshot%202016-08-07%2010.07.15.png?dl=0 This is what it looks like with this commit: https://www.dropbox.com/s/xr9ilbp6xeg0t7u/Screenshot%202016-08-07%2010.05.56.png?dl=0 --- axelrod/strategies/lookerup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/axelrod/strategies/lookerup.py b/axelrod/strategies/lookerup.py index 0b4e7d388..97bebd1bd 100644 --- a/axelrod/strategies/lookerup.py +++ b/axelrod/strategies/lookerup.py @@ -20,18 +20,18 @@ class LookerUp(Player): * my last action was a C the opponents * last action was a D - then the corresponding key would be + then the corresponding key would be:: ('C', 'C', 'D') and the value would contain the action to play on this turn. Some well-known strategies can be expressed as special cases; for example - Cooperator is given by the dict: + Cooperator is given by the dict:: {('', '', '') : C} - where m and n are both zero. Tit-For-Tat is given by: + where m and n are both zero. Tit-For-Tat is given by:: {('', 'C', 'D'): D, ('', 'D', 'D'): D, @@ -42,7 +42,7 @@ class LookerUp(Player): Lookup tables where the action depends on the opponent's first actions (as opposed to most recent actions) will have a non-empty first string in the - tuple. For example, this fragment of a dict: + tuple. For example, this fragment of a dict:: {('C', 'C', 'C'): C, ('D', 'C', 'C'): D} @@ -53,7 +53,7 @@ class LookerUp(Player): To denote lookup tables where the action depends on sequences of actions (so m or n are greater than 1), simply concatenate the strings together. - Below is an incomplete example where m=3 and n=2. + Below is an incomplete example where m=3 and n=2:: {('CC', 'CDD', 'CCC'): C, ('CD', 'CCD', 'CCC'): D} From a45b306925783a9c3c61e58bd82013d47214ec4e Mon Sep 17 00:00:00 2001 From: Vince Knight Date: Sun, 7 Aug 2016 10:28:43 +0100 Subject: [PATCH 08/11] Add encoding needed for py2 sphinx build. Got this error without it: Configuration error: There is a syntax error in your configuration file: Non-ASCII character '\xe2' in file /home/travis/build/drvinceknight/Axelrod/axelrod/match.py on line 161, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details (match.py, line 161) make: *** [html] Error 1 --- axelrod/match.py | 1 + 1 file changed, 1 insertion(+) diff --git a/axelrod/match.py b/axelrod/match.py index 745e082c4..e399ee88a 100644 --- a/axelrod/match.py +++ b/axelrod/match.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from axelrod import Actions, Game from .deterministic_cache import DeterministicCache From f887b01f857a2c1269ebad8df1ecd90a0c239aa0 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 8 Aug 2016 15:16:23 -0700 Subject: [PATCH 09/11] Clean up tournament arguments and docstrings --- axelrod/tournament.py | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/axelrod/tournament.py b/axelrod/tournament.py index 2e9e5541f..faaedbe9d 100644 --- a/axelrod/tournament.py +++ b/axelrod/tournament.py @@ -35,8 +35,6 @@ def __init__(self, players, match_generator=RoundRobinMatches, The number of turns per match repetitions : integer The number of times the round robin should be repeated - processes : integer - The number of processes to be used for parallel processing noise : float The probability that a player's intended action should be flipped with_morality : boolean @@ -80,9 +78,11 @@ def play(self, build_results=True, filename=None, whether or not to build a results st filename : string name of output file + processes : integer + The number of processes to be used for parallel processing progress_bar : bool Whether or not to create a progress bar which will be updated - interactions : bool + keep_interactions : bool Whether or not to load the interactions in to memory Returns @@ -237,8 +237,6 @@ def _process_done_queue(self, workers, done_queue, progress_bar=False): The number of sub-processes in existence done_queue : multiprocessing.Queue A queue containing the output dictionaries from each round robin - interactions : list - The list of interactions per repetition to update with results progress_bar : bool Whether or not to update the tournament progress bar """ @@ -312,8 +310,7 @@ class ProbEndTournament(Tournament): def __init__(self, players, match_generator=ProbEndRoundRobinMatches, name='axelrod', game=None, prob_end=.5, repetitions=10, - noise=0, - with_morality=True): + noise=0, with_morality=True): """ Parameters ---------- @@ -329,8 +326,6 @@ def __init__(self, players, match_generator=ProbEndRoundRobinMatches, The probability of a given match ending repetitions : integer The number of times the round robin should be repeated - processes : integer - The number of processes to be used for parallel processing noise : float The probability that a player's intended action should be flipped with_morality : boolean @@ -350,17 +345,13 @@ class SpatialTournament(Tournament): A tournament in which the players are allocated in a graph as nodes and they players only play the others that are connected to with an edge. """ - def __init__(self, players, edges, match_generator=SpatialMatches, - name='axelrod', game=None, turns=200, repetitions=10, - noise=0, - with_morality=True): + def __init__(self, players, edges, name='axelrod', game=None, turns=200, + repetitions=10, noise=0, with_morality=True): """ Parameters ---------- players : list A list of axelrod.Player objects - match_generator : class - A class that must be descended from axelrod.MatchGenerator name : string A name for the tournament game : axelrod.Game @@ -369,8 +360,6 @@ def __init__(self, players, edges, match_generator=SpatialMatches, A list of tuples containing the existing edges repetitions : integer The number of times the round robin should be repeated - processes : integer - The number of processes to be used for parallel processing noise : float The probability that a player's intended action should be flipped with_morality : boolean @@ -391,17 +380,13 @@ class ProbEndSpatialTournament(ProbEndTournament): and they players only play the others that are connected to with an edge. Players do not know the length of a given match (it is randomly sampled). """ - def __init__(self, players, edges, match_generator=SpatialMatches, - name='axelrod', game=None, prob_end=.5, repetitions=10, - noise=0, - with_morality=True): + def __init__(self, players, edges, name='axelrod', game=None, prob_end=.5, + repetitions=10, noise=0, with_morality=True): """ Parameters ---------- players : list A list of axelrod.Player objects - match_generator : class - A class that must be descended from axelrod.MatchGenerator name : string A name for the tournament game : axelrod.Game @@ -412,8 +397,6 @@ def __init__(self, players, edges, match_generator=SpatialMatches, A list of tuples containing the existing edges repetitions : integer The number of times the round robin should be repeated - processes : integer - The number of processes to be used for parallel processing noise : float The probability that a player's intended action should be flipped with_morality : boolean From 93ad96644d5d37318d926fbc03a3149d3d7c477b Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 8 Aug 2016 15:20:41 -0700 Subject: [PATCH 10/11] A few more style and param corrections --- axelrod/_strategy_utils.py | 3 +-- axelrod/match_generator.py | 2 +- axelrod/player.py | 7 +++---- axelrod/plot.py | 11 ++--------- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/axelrod/_strategy_utils.py b/axelrod/_strategy_utils.py index 24a855c8f..ca8eb953d 100644 --- a/axelrod/_strategy_utils.py +++ b/axelrod/_strategy_utils.py @@ -112,8 +112,7 @@ def __repr__(self): @Memoized def recursive_thue_morse(n): """The recursive definition of the Thue-Morse sequence. The first few terms - of the Thue-Morse sequence are: - 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 . . .""" + of the Thue-Morse sequence are: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 . . .""" if n == 0: return 0 diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index 0192d035e..0fb9a0bec 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -126,7 +126,7 @@ def build_single_match_params(self): self.sample_length(self.prob_end), self.game, None, self.noise, {'length': float('inf'), 'game': self.game, 'noise': self.noise}) - def sample_length(self, prob_end): + def sample_length(self): """ Sample length of a game. diff --git a/axelrod/player.py b/axelrod/player.py index 1d1a25856..ead32303e 100644 --- a/axelrod/player.py +++ b/axelrod/player.py @@ -149,10 +149,9 @@ def clone(self): def reset(self): """Resets history. - - When creating strategies that create new attributes then this method should be - re-written (in the inherited class) and should not only reset history but also - rest all other attributes. + When creating strategies that create new attributes then this method + should be re-written (in the inherited class) and should not only reset + history but also rest all other attributes. """ self.history = [] self.cooperations = 0 diff --git a/axelrod/plot.py b/axelrod/plot.py index fa6205b2c..e8598a551 100644 --- a/axelrod/plot.py +++ b/axelrod/plot.py @@ -103,14 +103,6 @@ def winplot(self, title=None): def _sd_ordering(self): return self.result_set.ranking - # Sort by median then max - # from operator import itemgetter - # diffs = self.result_set.score_diffs - # to_sort = [(median(d), max(d), i) for (i, d) in enumerate(diffs)] - # to_sort.sort(reverse=True, key=itemgetter(0, 1)) - # ordering = [x[-1] for x in to_sort] - # return ordering - @property def _sdv_plot_dataset(self): ordering = self._sd_ordering @@ -231,7 +223,8 @@ def stackplot(self, eco, title=None, logscale=True): for i, n in enumerate(self.result_set.ranked_names): x = -0.01 y = (i + 0.5) * 1.0 / self.result_set.nplayers - ax.annotate(n, xy=(x, y), xycoords=trans, clip_on=False, va='center', ha='right', fontsize=5) + ax.annotate(n, xy=(x, y), xycoords=trans, clip_on=False, + va='center', ha='right', fontsize=5) ticks.append(y) ax.set_yticks(ticks) ax.tick_params(direction='out') From eebde3e326e1e151664175ed1bedd3ef4fea3acb Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 8 Aug 2016 15:43:15 -0700 Subject: [PATCH 11/11] Fix probabilistic ending tournament tests --- axelrod/match_generator.py | 2 +- axelrod/tests/unit/test_match_generator.py | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index 0fb9a0bec..22f94b4f4 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -123,7 +123,7 @@ def build_single_match_params(self): Creates a single set of match parameters. """ return ( - self.sample_length(self.prob_end), self.game, None, self.noise, + self.sample_length(), self.game, None, self.noise, {'length': float('inf'), 'game': self.game, 'noise': self.noise}) def sample_length(self): diff --git a/axelrod/tests/unit/test_match_generator.py b/axelrod/tests/unit/test_match_generator.py index bd2f10319..11dd454b8 100644 --- a/axelrod/tests/unit/test_match_generator.py +++ b/axelrod/tests/unit/test_match_generator.py @@ -153,12 +153,13 @@ def test_build_matches_different_length(self, prob_end): @given(prob_end=floats(min_value=0, max_value=1)) def test_sample_length(self, prob_end): rr = axelrod.ProbEndRoundRobinMatches( - self.players, prob_end, test_game, test_repetitions) - self.assertGreaterEqual(rr.sample_length(prob_end), 1) + self.players, prob_end, test_game, test_repetitions, + ) + self.assertGreaterEqual(rr.sample_length(), 1) try: - self.assertIsInstance(rr.sample_length(prob_end), int) + self.assertIsInstance(rr.sample_length(), int) except AssertionError: - self.assertEqual(rr.sample_length(prob_end), float("inf")) + self.assertEqual(rr.sample_length(), float("inf")) @given(prob_end=floats(min_value=.1, max_value=1)) def test_build_single_match_params(self, prob_end): @@ -300,11 +301,11 @@ def test_sample_length(self, prob_end): noise = 0 pesp = axelrod.ProbEndSpatialMatches( self.players, prob_end, test_game, test_repetitions, noise, edges) - self.assertGreaterEqual(pesp.sample_length(prob_end), 1) + self.assertGreaterEqual(pesp.sample_length(), 1) try: - self.assertIsInstance(pesp.sample_length(prob_end), int) + self.assertIsInstance(pesp.sample_length(), int) except AssertionError: - self.assertEqual(pesp.sample_length(prob_end), float("inf")) + self.assertEqual(pesp.sample_length(), float("inf")) @given(prob_end=floats(min_value=0.005, max_value=0.01)) def test_build_matches_different_length(self, prob_end):