From ec628abd8cc16ddbf8629c8e11299a808e14faf2 Mon Sep 17 00:00:00 2001 From: drdkad Date: Tue, 16 Jul 2024 19:14:19 +0100 Subject: [PATCH] Resolve comments --- src/pygambit/game.pxi | 34 +++++++++++++++------------------- tests/test_game.py | 18 +++++++++++------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/pygambit/game.pxi b/src/pygambit/game.pxi index 4ede523c2..7af2f8b41 100644 --- a/src/pygambit/game.pxi +++ b/src/pygambit/game.pxi @@ -19,6 +19,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +import fractions import itertools import pathlib @@ -336,36 +337,31 @@ class Game: g.title = title return g - def to_arrays(self) -> typing.List[np.array]: - """Reverse function to from_arrays: - - To_arrays, for a given game, generates players’ payoff tables represented as numpy arrays. - The number of produced arrays is equal to the number of players. + def to_arrays(self, dtype=fractions.Fraction) -> typing.List[np.array]: + """Generate the payoff tables for players represented as numpy arrays. + Parameters + ---------- + dtype : type + The desired datatype of the payoff values Returns ------- - list of np.arrays + list of np.array - Raises - ------ - UndefinedOperationError - If the game does not have a tree representation. + See Also + -------- + from_arrays : Create game from list-like of array-like """ arrays = [] - if self.is_tree: - raise UndefinedOperationError( - "Operation only defined for games with a strategic representation" - ) - - if len(self.players) == 0: - raise RuntimeError("There are no players in the game") + if dtype != fractions.Fraction and dtype != float: + raise NotImplementedError("Unsupported type of payoff") shape = tuple(len(player.strategies) for player in self.players) for player in self.players: - array = np.zeros(shape=shape) + array = np.zeros(shape=shape, dtype=object) for profile in itertools.product(*(range(s) for s in shape)): - array[profile] = self[profile][player] + array[profile] = dtype(self[profile][player]) arrays.append(array) return arrays diff --git a/tests/test_game.py b/tests/test_game.py index 2bd3bcf01..b410fe3c3 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -1,3 +1,5 @@ +from fractions import Fraction + import numpy as np import pygambit as gbt import pytest @@ -13,12 +15,6 @@ def test_from_arrays(): assert len(game.players[1].strategies) == 2 -def test_extensive_form_to_arrays(): - game = gbt.Game.new_tree() - with pytest.raises(ValueError): - _ = game.to_arrays() - - def test_empty_array_to_arrays(): game = gbt.Game.from_arrays([]) a = game.to_arrays() @@ -26,9 +22,17 @@ def test_empty_array_to_arrays(): assert (a[0] == np.array([])).all() -def test_different_num_representations_to_arrays(): +def test_different_num_representations_to_arrays_fraction(): game = gbt.Game.from_arrays([1, 2 / 1, "6/2", 0.25, ".99"]) A = game.to_arrays()[0] + correct_output = [Fraction(1, 1), Fraction(2, 1), Fraction(3, 1), Fraction(1, 4), + Fraction(99, 100)] + assert (correct_output == A).all() + + +def test_different_num_representations_to_arrays_float(): + game = gbt.Game.from_arrays([1, 2 / 1, "6/2", 0.25, ".99"]) + A = game.to_arrays(dtype=float)[0] correct_output = [1.0, 2.0, 3.0, 0.25, 0.99] assert (correct_output == A).all()