Skip to content

Commit ecc5e9c

Browse files
committed
RFC: Refactor GAMReader._parse
Also add `from_gam_string` and `from_gam_url`
1 parent 6db11d8 commit ecc5e9c

1 file changed

Lines changed: 38 additions & 13 deletions

File tree

quantecon/game_theory/game_converters.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -267,22 +267,39 @@ def from_string(cls, string):
267267
@staticmethod
268268
def _parse(string):
269269
tokens = string.split()
270+
if not tokens:
271+
raise ValueError('empty .gam input')
272+
pos = 0
273+
274+
# N
275+
tok = tokens[pos]
276+
try:
277+
N = int(tok)
278+
except ValueError as err:
279+
raise ValueError(f'invalid N token: {tok!r}') from err
280+
pos += 1
281+
282+
if N <= 0:
283+
raise ValueError('N must be a positive integer')
284+
285+
# nums_actions
286+
if len(tokens) < pos + N:
287+
got = max(0, len(tokens) - pos)
288+
raise ValueError(
289+
f'incomplete header: expected {N} action counts, got {got}'
290+
)
270291

271-
N = int(tokens.pop(0))
272-
nums_actions = tuple(int(tokens.pop(0)) for _ in range(N))
273-
payoffs = np.array([_str2num(s) for s in tokens])
292+
try:
293+
nums_actions = tuple(int(tok) for tok in tokens[pos:pos+N])
294+
except ValueError as err:
295+
raise ValueError('invalid action count token in header') from err
296+
pos += N
274297

275-
na = np.prod(nums_actions)
276-
payoffs2d = payoffs.reshape(N, na)
277-
players = [
278-
Player(
279-
payoffs2d[i, :].reshape(nums_actions, order='F').transpose(
280-
(*range(i, N), *range(i))
281-
)
282-
) for i in range(N)
283-
]
298+
# payoffs
299+
payoffs = np.array([_str2num(tok) for tok in tokens[pos:]])
284300

285-
return NormalFormGame(players)
301+
p = GAMPayoffVector(nums_actions, payoffs)
302+
return p.to_nfg()
286303

287304

288305
class GAMWriter:
@@ -376,6 +393,14 @@ def from_gam(filename: str) -> NormalFormGame:
376393
return GAMReader.from_file(filename)
377394

378395

396+
def from_gam_string(string):
397+
return GAMReader.from_string(string)
398+
399+
400+
def from_gam_url(url):
401+
return GAMReader.from_url(url)
402+
403+
379404
def to_gam(g, file_path=None):
380405
"""
381406
Write a NormalFormGame to a file in .gam format.

0 commit comments

Comments
 (0)