From afcd5dc80bae9ba2b5495fb6d0ba6c4ca6845110 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 | 37 +++++++++++++++++-------------------- tests/test_game.py | 16 +++++++++------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/pygambit/game.pxi b/src/pygambit/game.pxi index 4ede523c2..d57ad279a 100644 --- a/src/pygambit/game.pxi +++ b/src/pygambit/game.pxi @@ -323,6 +323,7 @@ class Game: See Also -------- from_dict : Create strategic game and set player labels + to_array: Generate the payoff tables for players represented as numpy arrays """ g = cython.declare(Game) arrays = [np.array(a) for a in arrays] @@ -336,36 +337,32 @@ 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: typing.Type = Rational) -> typing.List[np.array]: + """Generate the payoff tables for players represented as numpy arrays. + Parameters + ---------- + dtype : type + The type to which payoff values will be converted and + the resulting arrays will be of that dtype 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") - 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] + try: + array[profile] = dtype(self[profile][player]) + except ValueError: + print("Unsupported type of payoff") arrays.append(array) return arrays diff --git a/tests/test_game.py b/tests/test_game.py index 2bd3bcf01..a6cbd93aa 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -13,12 +13,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 +20,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 = [gbt.Rational(1, 1), gbt.Rational(2, 1), gbt.Rational(3, 1), + gbt.Rational(1, 4), gbt.Rational(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()