Skip to content

Commit ef9125d

Browse files
get description from catalog
1 parent 8d29139 commit ef9125d

File tree

5 files changed

+36
-56
lines changed

5 files changed

+36
-56
lines changed

doc/tutorials/01_quickstart.ipynb

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -438,11 +438,7 @@
438438
{
439439
"data": {
440440
"text/plain": [
441-
"['Game2x2',\n",
442-
" 'Game2x2a',\n",
443-
" 'Game2x2const',\n",
444-
" 'Game8x8',\n",
445-
" 'Cent2NFG',\n",
441+
"['Cent2NFG',\n",
446442
" 'Coord2NFG',\n",
447443
" 'Coord3NFG',\n",
448444
" 'Coord4NFG',\n",
@@ -455,14 +451,18 @@
455451
" 'E02NFG',\n",
456452
" 'E04NFG',\n",
457453
" 'E07NFG',\n",
454+
" 'Game2x2',\n",
455+
" 'Game2x2a',\n",
456+
" 'Game2x2const',\n",
457+
" 'Game8x8',\n",
458458
" 'Loopback',\n",
459459
" 'Mixdom',\n",
460460
" 'Mixdom2',\n",
461461
" 'Oneill',\n",
462-
" 'PrisonersDilemma',\n",
463462
" 'Perfect1',\n",
464463
" 'Perfect2',\n",
465464
" 'PokerNFG',\n",
465+
" 'PrisonersDilemma',\n",
466466
" 'Sh3NFG',\n",
467467
" 'Stengel',\n",
468468
" 'Sww1NFG',\n",
@@ -485,27 +485,6 @@
485485
"gbt.catalog.games(game_type=\"nfg\", num_players=2)"
486486
]
487487
},
488-
{
489-
"cell_type": "code",
490-
"execution_count": 15,
491-
"id": "ff307b74-16bc-4889-b57c-fef3124ce5ca",
492-
"metadata": {},
493-
"outputs": [
494-
{
495-
"data": {
496-
"text/plain": [
497-
"\"A simple implementation of a two person Prisoner's Dilemma game.\""
498-
]
499-
},
500-
"execution_count": 15,
501-
"metadata": {},
502-
"output_type": "execute_result"
503-
}
504-
],
505-
"source": [
506-
"gbt.catalog.PrisonersDilemma.description"
507-
]
508-
},
509488
{
510489
"cell_type": "markdown",
511490
"id": "a919ddf7",
@@ -516,7 +495,7 @@
516495
},
517496
{
518497
"cell_type": "code",
519-
"execution_count": 16,
498+
"execution_count": 14,
520499
"id": "6db7a29a",
521500
"metadata": {},
522501
"outputs": [
@@ -530,7 +509,7 @@
530509
"Game(title='Two person Prisoner's Dilemma game')"
531510
]
532511
},
533-
"execution_count": 16,
512+
"execution_count": 14,
534513
"metadata": {},
535514
"output_type": "execute_result"
536515
}
@@ -556,7 +535,7 @@
556535
},
557536
{
558537
"cell_type": "code",
559-
"execution_count": 17,
538+
"execution_count": 15,
560539
"id": "f58eaa77",
561540
"metadata": {},
562541
"outputs": [],
@@ -574,7 +553,7 @@
574553
},
575554
{
576555
"cell_type": "code",
577-
"execution_count": 18,
556+
"execution_count": 16,
578557
"id": "4119a2ac",
579558
"metadata": {},
580559
"outputs": [],

doc/tutorials/02_extensive_form.ipynb

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,9 +1114,7 @@
11141114
{
11151115
"data": {
11161116
"text/plain": [
1117-
"['Game2smp',\n",
1118-
" 'Game4cards',\n",
1119-
" 'Artist1',\n",
1117+
"['Artist1',\n",
11201118
" 'Artist2',\n",
11211119
" 'Badgame1',\n",
11221120
" 'Badgame2',\n",
@@ -1152,6 +1150,8 @@
11521150
" 'E16',\n",
11531151
" 'E17',\n",
11541152
" 'E18',\n",
1153+
" 'Game2smp',\n",
1154+
" 'Game4cards',\n",
11551155
" 'Holdout',\n",
11561156
" 'Hs1',\n",
11571157
" 'Km1',\n",
@@ -1170,6 +1170,7 @@
11701170
" 'Myerson_fig_4_2',\n",
11711171
" 'Nim',\n",
11721172
" 'Nim7',\n",
1173+
" 'OneShotTrust',\n",
11731174
" 'Palf',\n",
11741175
" 'Palf2',\n",
11751176
" 'Palf3',\n",
@@ -1191,8 +1192,7 @@
11911192
" 'Wilson1',\n",
11921193
" 'Work1',\n",
11931194
" 'Work2',\n",
1194-
" 'Work3',\n",
1195-
" 'OneShotTrust']"
1195+
" 'Work3']"
11961196
]
11971197
},
11981198
"execution_count": 14,
@@ -1232,7 +1232,8 @@
12321232
}
12331233
],
12341234
"source": [
1235-
"print(gbt.catalog.OneShotTrust.description)"
1235+
"g_variant = gbt.catalog.OneShotTrust(unique_NE_variant=True)\n",
1236+
"print(g_variant.description)"
12361237
]
12371238
},
12381239
{
@@ -1419,7 +1420,7 @@
14191420
}
14201421
],
14211422
"source": [
1422-
"draw_tree(gbt.catalog.OneShotTrust(unique_NE_variant=True))"
1423+
"draw_tree(g_variant)"
14231424
]
14241425
},
14251426
{

src/pygambit/catalog/catalog.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class CatalogGame:
1717
Calling any subclass will return an instance of the corresponding game.
1818
"""
1919

20-
description: str
2120
game: Game | None = None
2221

2322
def __new__(cls, *args, **kwargs) -> Game:
@@ -32,12 +31,13 @@ def _game() -> Game:
3231
raise NotImplementedError("Subclasses must implement _game() method")
3332

3433
@classmethod
35-
def _extract_metadata_from_game(cls, game: Game) -> None:
36-
"""Extract metadata from the game and set as class attributes."""
34+
def _extract_description(cls, game: Game) -> None:
35+
"""Extract game description from docstring and apply to game."""
36+
cleaned_docstring = ""
3737
if cls.__doc__:
38-
cls.description = inspect.cleandoc(cls.__doc__)
39-
else:
40-
cls.description = game.description
38+
cleaned_docstring = inspect.cleandoc(cls.__doc__)
39+
if len(cleaned_docstring) > 0:
40+
game.description = cleaned_docstring
4141

4242
def __init_subclass__(cls, **kwargs):
4343
"""Extract metadata when subclass is defined (if not a file-based game)."""
@@ -49,7 +49,7 @@ def __init_subclass__(cls, **kwargs):
4949

5050
# Load game and extract metadata immediately when class is defined
5151
cls.game = cls._game()
52-
cls._extract_metadata_from_game(cls.game)
52+
cls._extract_description(cls.game)
5353

5454

5555
class CatalogGameFromContrib(CatalogGame):
@@ -88,7 +88,7 @@ def __init_subclass__(cls, **kwargs):
8888

8989
# Load game and extract metadata immediately when class is defined
9090
cls.game = cls._load_game()
91-
cls._extract_metadata_from_game(cls.game)
91+
cls._extract_description(cls.game)
9292

9393

9494
def games(

src/pygambit/catalog/coded_games.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44

55

66
class OneShotTrust(CatalogGame):
7+
"""
8+
The unique_NE_variant makes Trust a dominant strategy, replacing the
9+
non-singleton equilibrium component from the standard version of the game
10+
where the Buyer plays "Not Trust" and the seller can play any mixture with
11+
< 0.5 probability on Honor with a unique NE where the Buyer plays Trust and
12+
the Seller plays Abuse.
13+
"""
714

815
@staticmethod
916
def _game(unique_NE_variant: bool = False):
10-
"""
11-
The unique_NE_variant makes Trust a dominant strategy, replacing the
12-
non-singleton equilibrium component from the standard version of the game
13-
where the Buyer plays "Not Trust" and the seller can play any mixture with
14-
< 0.5 probability on Honor with a unique NE where the Buyer plays Trust and
15-
the Seller plays Abuse.
16-
"""
1717
g = Game.new_tree(
1818
players=["Buyer", "Seller"], title="One-shot trust game, after Kreps (1990)"
1919
)

tests/test_catalog.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ def test_catalog_game_not_instantiable(self):
3636

3737
def test_custom_game_subclass_extracts_metadata(self):
3838
"""Custom CatalogGame subclasses should extract metadata from _game()."""
39-
assert ExampleGame.description == "Test game description."
39+
assert ExampleGame().description == "Test game description."
4040

4141
def test_can_get_game_description_from_docstring(self):
4242
"""CatalogGame should get description from docstring over game description."""
43-
assert ExampleGameWithDocstring.description == "Alternative test game description."
43+
assert ExampleGameWithDocstring().description == "Alternative test game description."
4444

4545
def test_catalog_py_game_with_parameters(self):
4646
"""
@@ -57,7 +57,7 @@ def test_catalog_yml_game_instantiation(self):
5757
def test_catalog_yml_game_description(self):
5858
"""Custom CatalogGame subclasses reading from catalog.yml should return Game instances."""
5959
assert (
60-
PrisonersDilemma.description
60+
PrisonersDilemma().description
6161
== "A simple implementation of a two person Prisoner's Dilemma game."
6262
)
6363

0 commit comments

Comments
 (0)