Skip to content

Commit 2990e46

Browse files
authored
Merge branch 'master' into typeHint-loadData
2 parents ae0cc42 + c2dba09 commit 2990e46

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+360
-307
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ install:
1818
- pip install docutils==0.12
1919
- pip install coverage
2020
- pip install coveralls
21+
- pip install mypy
2122
script:
2223
# Build the documentation
2324
- cd docs; make html
@@ -27,6 +28,8 @@ script:
2728
- coverage report -m
2829
# Run the doctests
2930
- python doctests.py
31+
# Run the type checker
32+
- sh ./type_tests.sh
3033
after_success:
3134
- coveralls
3235
notifications:

README.rst

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
Axelrod
1616
=======
1717

18-
A library with the following principles and goals:
18+
A Python library with the following principles and goals:
1919

2020
1. Enabling the reproduction of previous Iterated Prisoner's Dilemma research
2121
as easily as possible.
@@ -26,10 +26,24 @@ A library with the following principles and goals:
2626
4. Emphasizing readability along with an open and welcoming community that
2727
is accommodating for developers and researchers of a variety of skill levels.
2828

29-
Currently the library contains well over 100 strategies and can perform a
29+
Currently the library contains well over 150 strategies including classics such
30+
as Tit-For-Tat (TFT) and Win-Stay-Lose-Shift (WSLS), recent variants including
31+
zero-determinant strategies, and a variety of novel strategies including several
32+
machine-learning based strategies. Many strategies are parameterized, allowing
33+
for infinitely-many variations. We welcome new strategies and additions from the
34+
literature: see `#379 <https://github.com/Axelrod-Python/Axelrod/issues/379>`_
35+
for a list of known strategies and sources.
36+
37+
With these strategies the library and can perform head-to-head Matches, a
3038
variety of tournament types (RoundRobin, Noisy, Spatially-distributed, and
31-
probabilistically ending) and population dynamics while taking advantage
32-
of multi-core processors.
39+
probabilistically ending) and population dynamics including the Moran process
40+
on graphs, while taking advantage of multi-core processors.
41+
42+
The library emphasizes reproducibility and validity. The current test suite
43+
covers more than 99% of all code in the library, with many portions covered many
44+
times over, including `randomly generated tests
45+
<https://github.com/HypothesisWorks/hypothesis-python>`_ that are created and
46+
run regularly.
3347

3448
**Please contribute via pull request (or just get in touch with us).**
3549

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
environment:
22
matrix:
33
- PYTHON: "C:\\Python35"
4+
- PYTHON: "C:\\Python36"
45
install:
56
- "%PYTHON%\\python.exe -m pip install -r requirements.txt"
67
build: off

axelrod/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# The order of imports matters!
66
from .version import __version__
7-
from .load_data_ import load_lookerup_tables, load_pso_tables, load_weights
7+
from .load_data_ import load_pso_tables, load_weights
88
from . import graph
99
from .actions import Actions, flip_action
1010
from .random_ import random_choice, seed

axelrod/_strategy_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import itertools
33
from functools import lru_cache
44

5-
from axelrod import update_history
6-
from axelrod import Actions
5+
from axelrod.player import update_history
6+
from axelrod.actions import Actions
77

88
from axelrod.strategies.cycler import Cycler
99

axelrod/actions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from typing import NewType
21

3-
Action = NewType('Action', str)
2+
# Type alias for actions.
3+
Action = str
44

55

66
class Actions(object):

axelrod/data/lookup_tables.csv

Lines changed: 0 additions & 19 deletions
This file was deleted.

axelrod/deterministic_cache.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
from collections import UserDict
22
import pickle
3+
from typing import List, Tuple
34

4-
from axelrod import Player
5+
from .actions import Action
6+
from .player import Player
7+
8+
9+
CachePlayerKey = Tuple[Player, Player, int]
10+
CacheKey = Tuple[str, str, int]
511

612

713
class DeterministicCache(UserDict):
@@ -29,7 +35,7 @@ class DeterministicCache(UserDict):
2935
methods to save/load the cache to/from a file.
3036
"""
3137

32-
def __init__(self, file_name=None):
38+
def __init__(self, file_name: str=None) -> None:
3339
"""
3440
Parameters
3541
----------
@@ -42,7 +48,7 @@ def __init__(self, file_name=None):
4248
self.load(file_name)
4349

4450
@staticmethod
45-
def _key_transform(key):
51+
def _key_transform(key: CachePlayerKey) -> CacheKey:
4652
"""
4753
Parameters
4854
----------
@@ -51,16 +57,16 @@ def _key_transform(key):
5157
"""
5258
return key[0].name, key[1].name, key[2]
5359

54-
def __delitem__(self, key):
60+
def __delitem__(self, key: CachePlayerKey):
5561
return super().__delitem__(self._key_transform(key))
5662

57-
def __getitem__(self, key):
63+
def __getitem__(self, key: CachePlayerKey) -> List[Tuple[Action, Action]]:
5864
return super().__getitem__(self._key_transform(key))
5965

6066
def __contains__(self, key):
6167
return super().__contains__(self._key_transform(key))
6268

63-
def __setitem__(self, key, value):
69+
def __setitem__(self, key: CachePlayerKey, value):
6470
"""Overrides the UserDict.__setitem__ method in order to validate
6571
the key/value and also to set the turns attribute"""
6672
if not self.mutable:
@@ -78,7 +84,7 @@ def __setitem__(self, key, value):
7884
super().__setitem__(self._key_transform(key), value)
7985

8086
@staticmethod
81-
def _is_valid_key(key):
87+
def _is_valid_key(key: CachePlayerKey) -> bool:
8288
"""Validate a proposed dictionary key.
8389
8490
Parameters
@@ -116,7 +122,7 @@ def _is_valid_key(key):
116122
return True
117123

118124
@staticmethod
119-
def _is_valid_value(value):
125+
def _is_valid_value(value: List) -> bool:
120126
"""Validate a proposed dictionary value.
121127
122128
Parameters
@@ -133,7 +139,7 @@ def _is_valid_value(value):
133139

134140
return True
135141

136-
def save(self, file_name):
142+
def save(self, file_name: str) -> bool:
137143
"""Serialise the cache dictionary to a file.
138144
139145
Parameters
@@ -145,7 +151,7 @@ def save(self, file_name):
145151
pickle.dump(self.data, io)
146152
return True
147153

148-
def load(self, file_name):
154+
def load(self, file_name: str) -> bool:
149155
"""Load a previously saved cache into the dictionary.
150156
151157
Parameters

axelrod/ecosystem.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
from axelrod.result_set import ResultSet
12
import random
2-
3-
3+
from typing import List, Callable
44
class Ecosystem(object):
55
"""Create an ecosystem based on the payoff matrix from an Axelrod
66
tournament."""
77

8-
def __init__(self, results, fitness=None, population=None):
8+
def __init__(self, results: ResultSet, fitness: Callable[[float], float] =None, population: List[int] =None) -> None:
99

1010
self.results = results
1111
self.nplayers = self.results.nplayers
@@ -37,7 +37,7 @@ def __init__(self, results, fitness=None, population=None):
3737
else:
3838
self.fitness = lambda p: p
3939

40-
def reproduce(self, turns):
40+
def reproduce(self, turns: int):
4141

4242
for iturn in range(turns):
4343

@@ -50,7 +50,7 @@ def reproduce(self, turns):
5050
# normal distribution based on the payoff matrix and its standard
5151
# deviations obtained from the iterated PD tournament run
5252
# previously.
53-
payoffs = [0 for ip in plist]
53+
payoffs = [0.0 for ip in plist]
5454
for ip in plist:
5555
for jp in plist:
5656
avg = self.payoff_matrix[ip][jp]

axelrod/game.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
from axelrod import Actions
2-
from typing import Tuple
1+
from .actions import Action, Actions
2+
from typing import Tuple, Union
33

44
C, D = Actions.C, Actions.D
55

6+
Score = Union[int, float]
7+
68

79
class Game(object):
810
"""A class to hold the game matrix and to score a game accordingly."""
911

10-
def __init__(self, r: int =3, s: int=0, t: int=5, p:int=1):
12+
def __init__(self, r: Score=3, s: Score=0, t: Score=5, p: Score=1) -> None:
1113
self.scores = {
1214
(C, C): (r, r),
1315
(D, D): (p, p),
1416
(C, D): (s, t),
1517
(D, C): (t, s),
1618
}
1719

18-
def RPST(self):
20+
def RPST(self) -> Tuple[Score, Score, Score, Score]:
1921
"""Return the values in the game matrix in the Press and Dyson
2022
notation."""
2123
R = self.scores[(C, C)][0]
@@ -24,7 +26,7 @@ def RPST(self):
2426
T = self.scores[(D, C)][0]
2527
return (R, P, S, T)
2628

27-
def score(self, pair) -> Tuple[int, int]:
29+
def score(self, pair: Tuple[Action, Action]) -> Tuple[Score, Score]:
2830
"""Return the appropriate score for decision pair.
2931
3032
Returns the appropriate score (as a tuple) from the scores dictionary
@@ -33,7 +35,8 @@ def score(self, pair) -> Tuple[int, int]:
3335
"""
3436
return self.scores[pair]
3537

36-
def __repr__(self):
38+
def __repr__(self) -> str:
3739
return "Axelrod game: (R,P,S,T) = {}".format(self.RPST())
3840

41+
3942
DefaultGame = Game()

0 commit comments

Comments
 (0)