Skip to content

Commit

Permalink
Trac #26429: py3: fix some doctests in game_theory
Browse files Browse the repository at this point in the history
URL: https://trac.sagemath.org/26429
Reported by: chapoton
Ticket author(s): Frédéric Chapoton
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager authored and vbraun committed Oct 21, 2018
2 parents 34502f4 + bb0122e commit 35c6974
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 46 deletions.
6 changes: 5 additions & 1 deletion src/sage/functions/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -1941,10 +1941,14 @@ def __call__(self, l, **kwargs):
TESTS::
sage: cases()
sage: cases() # py2
Traceback (most recent call last):
...
TypeError: __call__() takes exactly 2 arguments (1 given)
sage: cases() # py3
Traceback (most recent call last):
...
TypeError: __call__() missing 1 required positional argument: 'l'
sage: cases(x)
Traceback (most recent call last):
Expand Down
8 changes: 4 additions & 4 deletions src/sage/game_theory/cooperative_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,22 +586,22 @@ def _latex_(self):
v(c) = \begin{cases}
0, & \text{if } c = \emptyset \\
6, & \text{if } c = \{A\} \\
42, & \text{if } c = \{C\} \\
12, & \text{if } c = \{B\} \\
42, & \text{if } c = \{B, C\} \\
42, & \text{if } c = \{C\} \\
12, & \text{if } c = \{A, B\} \\
42, & \text{if } c = \{A, C\} \\
42, & \text{if } c = \{B, C\} \\
42, & \text{if } c = \{A, B, C\} \\
\end{cases}
"""
cf = self.ch_f
output = "v(c) = \\begin{cases}\n"
for key in sorted(cf.keys(), key=lambda key: len(key)):
for key, val in sorted(cf.items(), key=lambda kv: (len(kv[0]), kv[0])):
if not key: # == ()
coalition = "\\emptyset"
else:
coalition = "\\{" + ", ".join(str(player) for player in key) + "\\}"
output += "{}, & \\text{{if }} c = {} \\\\\n".format(cf[key], coalition)
output += "{}, & \\text{{if }} c = {} \\\\\n".format(val, coalition)
output += "\\end{cases}"
return output

Expand Down
119 changes: 81 additions & 38 deletions src/sage/game_theory/normal_form_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
sage: B = matrix([[2, 1], [0, 3]])
sage: battle_of_the_sexes = NormalFormGame([A, B])
sage: battle_of_the_sexes
Normal Form Game with the following utilities: {(0, 1): [1, 1], (1, 0): [0, 0], (0, 0): [3, 2], (1, 1): [2, 3]}
Normal Form Game with the following utilities: {(0, 0): [3, 2], (0, 1): [1, 1], (1, 0): [0, 0], (1, 1): [2, 3]}
To obtain the Nash equilibria we run the ``obtain_nash()`` method. In the
first few examples, we will use the 'support enumeration' algorithm.
Expand Down Expand Up @@ -280,7 +280,7 @@
sage: f[1,1][0] = 4
sage: f[1,1][1] = 4
sage: f
Normal Form Game with the following utilities: {(0, 1): [2, 3], (1, 0): [3, 1], (0, 0): [1, 3], (1, 1): [4, 4]}
Normal Form Game with the following utilities: {(0, 0): [1, 3], (0, 1): [2, 3], (1, 0): [3, 1], (1, 1): [4, 4]}
Once this game is constructed we can view the payoff matrices and solve the
game::
Expand All @@ -297,7 +297,12 @@
sage: f.add_strategy(0)
sage: f
Normal Form Game with the following utilities: {(0, 1): [2, 3], (0, 0): [1, 3], (2, 1): [False, False], (2, 0): [False, False], (1, 0): [3, 1], (1, 1): [4, 4]}
Normal Form Game with the following utilities: {(0, 0): [1, 3],
(0, 1): [2, 3],
(1, 0): [3, 1],
(1, 1): [4, 4],
(2, 0): [False, False],
(2, 1): [False, False]}
If we do this and try and obtain the Nash equilibrium or view the payoff
matrices(without specifying the utilities), an error is returned::
Expand Down Expand Up @@ -356,7 +361,14 @@
sage: threegame[1, 1, 1][1] = 6
sage: threegame[1, 1, 1][2] = 4
sage: threegame
Normal Form Game with the following utilities: {(0, 1, 1): [3, 5, 8], (1, 1, 0): [8, 4, 6], (1, 0, 0): [9, 7, 9], (0, 0, 1): [1, 5, 9], (1, 0, 1): [3, 2, 3], (0, 0, 0): [3, 1, 4], (0, 1, 0): [2, 6, 5], (1, 1, 1): [2, 6, 4]}
Normal Form Game with the following utilities: {(0, 0, 0): [3, 1, 4],
(0, 0, 1): [1, 5, 9],
(0, 1, 0): [2, 6, 5],
(0, 1, 1): [3, 5, 8],
(1, 0, 0): [9, 7, 9],
(1, 0, 1): [3, 2, 3],
(1, 1, 0): [8, 4, 6],
(1, 1, 1): [2, 6, 4]}
The above requires a lot of input that could be simplified if there is
another data structure with our utilities and/or a structure to the
Expand All @@ -373,7 +385,14 @@
....: for p in range(3):
....: threegame[i, j, k][p] = utility([i, j, k], p)
sage: threegame
Normal Form Game with the following utilities: {(0, 1, 1): [0, 2, 4], (1, 1, 0): [0, 2, 4], (1, 0, 0): [0, 1, 2], (0, 0, 1): [0, 1, 2], (1, 0, 1): [0, 2, 4], (0, 0, 0): [0, 0, 0], (0, 1, 0): [0, 1, 2], (1, 1, 1): [0, 3, 6]}
Normal Form Game with the following utilities: {(0, 0, 0): [0, 0, 0],
(0, 0, 1): [0, 1, 2],
(0, 1, 0): [0, 1, 2],
(0, 1, 1): [0, 2, 4],
(1, 0, 0): [0, 1, 2],
(1, 0, 1): [0, 2, 4],
(1, 1, 0): [0, 2, 4],
(1, 1, 1): [0, 3, 6]}
At present no algorithm has been implemented in Sage for games with
more than 2 players::
Expand Down Expand Up @@ -416,7 +435,10 @@
sage: gambitgame[int(1), int(1)][int(1)] = int(5) # optional - gambit
sage: g = NormalFormGame(gambitgame) # optional - gambit
sage: g # optional - gambit
Normal Form Game with the following utilities: {(0, 1): [2.0, 10.0], (1, 0): [10.0, 2.0], (0, 0): [8.0, 8.0], (1, 1): [5.0, 5.0]}
Normal Form Game with the following utilities: {(0, 0): [8.0, 8.0],
(0, 1): [2.0, 10.0],
(1, 0): [10.0, 2.0],
(1, 1): [5.0, 5.0]}
For more information on using Gambit in Sage see: :mod:`Using Gambit in
Sage<sage.game_theory.gambit_docs>`. This includes how to access Gambit
Expand Down Expand Up @@ -597,17 +619,16 @@
"""

#*****************************************************************************
# ****************************************************************************
# Copyright (C) 2014 James Campbell [email protected]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************
from __future__ import print_function
from __future__ import absolute_import
# https://www.gnu.org/licenses/
# ****************************************************************************
from __future__ import print_function, absolute_import

from collections import MutableMapping
from itertools import product
Expand Down Expand Up @@ -698,7 +719,10 @@ def __init__(self, generator=None):
sage: gambitgame[int(1), int(1)][int(1)] = int(5) # optional - gambit
sage: g = NormalFormGame(gambitgame) # optional - gambit
sage: g # optional - gambit
Normal Form Game with the following utilities: {(0, 1): [2.0, 11.0], (1, 0): [10.0, 7.0], (0, 0): [5.0, 8.0], (1, 1): [5.0, 5.0]}
Normal Form Game with the following utilities: {(0, 0): [5.0, 8.0],
(0, 1): [2.0, 11.0],
(1, 0): [10.0, 7.0],
(1, 1): [5.0, 5.0]}
TESTS:
Expand All @@ -715,10 +739,14 @@ def __init__(self, generator=None):
sage: p1 = matrix([[1, 2], [3, 4]])
sage: p2 = matrix([[3, 3], [1, 4], [6, 6]])
sage: error = NormalFormGame(p1, p2)
sage: error = NormalFormGame(p1, p2) # py2
Traceback (most recent call last):
...
TypeError: __init__() takes at most 2 arguments (3 given)
sage: error = NormalFormGame(p1, p2) # py3
Traceback (most recent call last):
...
TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given
When initiating, argument passed must be a list or nothing::
Expand Down Expand Up @@ -764,10 +792,10 @@ def __delitem__(self, key):
sage: B = matrix([[2, 0], [5, 4]])
sage: prisoners_dilemma = NormalFormGame([A, B])
sage: prisoners_dilemma
Normal Form Game with the following utilities: {(0, 1): [5, 0], (1, 0): [0, 5], (0, 0): [2, 2], (1, 1): [4, 4]}
Normal Form Game with the following utilities: {(0, 0): [2, 2], (0, 1): [5, 0], (1, 0): [0, 5], (1, 1): [4, 4]}
sage: del(prisoners_dilemma[(0,1)])
sage: prisoners_dilemma
Normal Form Game with the following utilities: {(1, 0): [0, 5], (0, 0): [2, 2], (1, 1): [4, 4]}
Normal Form Game with the following utilities: {(0, 0): [2, 2], (1, 0): [0, 5], (1, 1): [4, 4]}
"""
self.utilities.pop(key, None)

Expand Down Expand Up @@ -805,11 +833,11 @@ def __iter__(self):
sage: A = matrix([[2, 5], [0, 4]])
sage: B = matrix([[2, 0], [5, 4]])
sage: prisoners_dilemma = NormalFormGame([A, B])
sage: for key in prisoners_dilemma:
....: print("The strategy pair {} gives utilities {}".format(key, prisoners_dilemma[key]))
sage: for key, value in sorted(prisoners_dilemma.items()):
....: print("The strategy pair {} gives utilities {}".format(key, value))
The strategy pair (0, 0) gives utilities [2, 2]
The strategy pair (0, 1) gives utilities [5, 0]
The strategy pair (1, 0) gives utilities [0, 5]
The strategy pair (0, 0) gives utilities [2, 2]
The strategy pair (1, 1) gives utilities [4, 4]
"""
return iter(self.utilities)
Expand Down Expand Up @@ -871,10 +899,11 @@ def _repr_(self):
sage: p2 = matrix([[3, 3], [1, 4]])
sage: g = NormalFormGame([p1, p2])
sage: g
Normal Form Game with the following utilities: {(0, 1): [2, 3], (1, 0): [3, 1], (0, 0): [1, 3], (1, 1): [4, 4]}
Normal Form Game with the following utilities: {(0, 0): [1, 3], (0, 1): [2, 3], (1, 0): [3, 1], (1, 1): [4, 4]}
"""
from pprint import pformat
base_str = "Normal Form Game with the following utilities: {}"
return base_str.format(self.utilities)
return base_str.format(pformat(self.utilities))

def _latex_(self):
r"""
Expand Down Expand Up @@ -903,7 +932,10 @@ def _latex_(self):
sage: g.add_player(2) # Adding second player with 2 strategies
sage: g.add_player(2) # Creating a game with three players
sage: latex(g)
\text{\texttt{Normal{ }Form{ }Game{ }...[False,{ }False,{ }False]{\char`\}}}}
\begin{array}{l}
\text{\texttt{Normal{ }Form{ }Game{ }with{ }the{ }...
...
\end{array}
"""
if len(self.players) == 2:
M1, M2 = self.payoff_matrices()
Expand Down Expand Up @@ -950,9 +982,10 @@ def _gambit_game(self, game):
sage: g = NormalFormGame() # optional - gambit
sage: g._gambit_game(testgame) # optional - gambit
sage: g # optional - gambit
Normal Form Game with the following utilities:
{(0, 1): [2.0, 10.0], (1, 0): [10.0, 2.0],
(0, 0): [8.0, 8.0], (1, 1): [5.0, 5.0]}
Normal Form Game with the following utilities: {(0, 0): [8.0, 8.0],
(0, 1): [2.0, 10.0],
(1, 0): [10.0, 2.0],
(1, 1): [5.0, 5.0]}
"""
self.players = []
self.utilities = {}
Expand Down Expand Up @@ -1243,7 +1276,7 @@ def add_player(self, num_strategies):
sage: g.add_player(1) # Adding second player with 1 strategy
sage: g.add_player(1) # Adding third player with 1 strategy
sage: g
Normal Form Game with the following utilities: {(1, 0, 0): [False, False, False], (0, 0, 0): [False, False, False]}
Normal Form Game with the following utilities: {(0, 0, 0): [False, False, False], (1, 0, 0): [False, False, False]}
"""
self.players.append(_Player(num_strategies))
self._generate_utilities(True)
Expand All @@ -1270,25 +1303,30 @@ def _generate_utilities(self, replacement):
sage: g._generate_utilities(True)
sage: g
Normal Form Game with the following utilities:
{(0, 1): [False, False], (1, 0): [False, False],
(0, 0): [False, False], (1, 1): [False, False]}
Normal Form Game with the following utilities: {(0, 0): [False, False],
(0, 1): [False, False],
(1, 0): [False, False],
(1, 1): [False, False]}
sage: g[(0,1)] = [2, 3]
sage: g.add_strategy(1)
sage: g._generate_utilities(False)
sage: g
Normal Form Game with the following utilities:
{(0, 1): [2, 3], (1, 2): [False, False],
(0, 0): [False, False], (0, 2): [False, False],
(1, 0): [False, False], (1, 1): [False, False]}
Normal Form Game with the following utilities: {(0, 0): [False, False],
(0, 1): [2, 3],
(0, 2): [False, False],
(1, 0): [False, False],
(1, 1): [False, False],
(1, 2): [False, False]}
sage: g._generate_utilities(True)
sage: g
Normal Form Game with the following utilities:
{(0, 1): [False, False], (1, 2): [False, False],
(0, 0): [False, False], (1, 1): [False, False],
(1, 0): [False, False], (0, 2): [False, False]}
Normal Form Game with the following utilities: {(0, 0): [False, False],
(0, 1): [False, False],
(0, 2): [False, False],
(1, 0): [False, False],
(1, 1): [False, False],
(1, 2): [False, False]}
"""
strategy_sizes = [range(p.num_strategies) for p in self.players]
if replacement is True:
Expand All @@ -1314,10 +1352,15 @@ def add_strategy(self, player):
sage: t = matrix([[3, 2], [-1, 0]])
sage: example = NormalFormGame([s, t])
sage: example
Normal Form Game with the following utilities: {(0, 1): [0, 2], (1, 0): [-2, -1], (0, 0): [1, 3], (1, 1): [3, 0]}
Normal Form Game with the following utilities: {(0, 0): [1, 3], (0, 1): [0, 2], (1, 0): [-2, -1], (1, 1): [3, 0]}
sage: example.add_strategy(0)
sage: example
Normal Form Game with the following utilities: {(0, 1): [0, 2], (0, 0): [1, 3], (2, 1): [False, False], (2, 0): [False, False], (1, 0): [-2, -1], (1, 1): [3, 0]}
Normal Form Game with the following utilities: {(0, 0): [1, 3],
(0, 1): [0, 2],
(1, 0): [-2, -1],
(1, 1): [3, 0],
(2, 0): [False, False],
(2, 1): [False, False]}
"""
self.players[player].add_strategy()
Expand Down
12 changes: 10 additions & 2 deletions src/sage/misc/explain_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -2825,10 +2825,14 @@ def append(self):
sage: from sage.misc.explain_pickle import *
sage: v = TestAppendList()
sage: v.append(7)
sage: v.append(7) # py2
Traceback (most recent call last):
...
TypeError: append() takes exactly 1 argument (2 given)
sage: v.append(7) # py3
Traceback (most recent call last):
...
TypeError: append() takes 1 positional argument but 2 were given
We can still append by directly using the list method:
sage: list.append(v, 7)
Expand All @@ -2845,10 +2849,14 @@ def extend(self):
sage: from sage.misc.explain_pickle import *
sage: v = TestAppendList()
sage: v.extend([3,1,4,1,5,9])
sage: v.extend([3,1,4,1,5,9]) # py2
Traceback (most recent call last):
...
TypeError: extend() takes exactly 1 argument (2 given)
sage: v.extend([3,1,4,1,5,9]) # py3
Traceback (most recent call last):
...
TypeError: extend() takes 1 positional argument but 2 were given
We can still extend by directly using the list method:
sage: list.extend(v, (3,1,4,1,5,9))
Expand Down
6 changes: 5 additions & 1 deletion src/sage/modular/cusps_nf.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,14 @@ def __call__(self, x):
sage: k.<a> = NumberField(x^2 + 5)
sage: kCusps = NFCusps(k)
sage: c = kCusps(a,2)
sage: c = kCusps(a,2) # py2
Traceback (most recent call last):
...
TypeError: __call__() takes exactly 2 arguments (3 given)
sage: c = kCusps(a,2) # py3
Traceback (most recent call last):
...
TypeError: __call__() takes 2 positional arguments but 3 were given
::
Expand Down

0 comments on commit 35c6974

Please sign in to comment.