Skip to content

Correct and update how numbers are parsed from a file - #21

Open
nataliemes wants to merge 6 commits into
gambitproject:mainfrom
nataliemes:refactor/update-utils
Open

Correct and update how numbers are parsed from a file#21
nataliemes wants to merge 6 commits into
gambitproject:mainfrom
nataliemes:refactor/update-utils

Conversation

@nataliemes

Copy link
Copy Markdown
Collaborator

Changes

1. decimals is now a function argument (instead of a global variable)

2. Added --decimals CLI option to lemke.py

3. Fixed rounding/precision bugs

Since floats in python do not represent decimal numbers exactly, tofraction() converting a string input to a float and then rounding it didn't always produce the expected result:

Input from file decimals Result after parsing Expected
0.00015 4 1/10000 (0.0001) 1/5000 (0.0002)
0.145 2 7/50 (0.14) 3/20 (0.15)
9999999999999991.1 0 9999999999999992 9999999999999991
9999999999999999.1 4 10000000000000000 99999999999999991/10 (9999999999999999.1)

To fix this, tofraction() now accepts only strings, and uses Decimal to parse and round the input half away from zero (with ROUND_HALF_UP).

Also, a new test was added which checks if the numbers above are now parsed and rounded correctly.

4. payoffmatrix object can only be created with Fractions

Other arbitrary numerics (which were silently converted via tofraction()) are no longer accepted. So, tofraction() is only used when parsing files, in other cases (like in payoffmatrix initialization), inputs should already be Fractions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new “Fraction-only” invariant for payoffmatrix is not consistently enforced across mutation paths (e.g., addrow/addcolumn) and currently conflicts with existing unit tests.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR refactors numeric parsing so file inputs are converted to Fraction values more reliably and deterministically, with configurable decimal rounding, and tightens invariants so payoffmatrix is constructed from Fraction values only.

Changes:

  • Replaces float-based rounding in utils.tofraction() with Decimal-based parsing + ROUND_HALF_UP, and threads decimals through parsing helpers.
  • Adds --decimals CLI support (and defaults) for LCP and bimatrix file parsing.
  • Updates/extends unit tests to cover previously failing rounding/precision cases and adjusts bimatrix initialization expectations.
File summaries
File Description
tests/test_lcp_units.py Adds regression tests for decimal rounding edge cases when parsing LCP files.
tests/test_bimatrix_units.py Updates payoff matrix fixture to use Fraction values and removes reliance on global decimals.
src/lemke/utils.py Introduces DEFAULT_DECIMALS, validate_decimals(), and Decimal-based tofraction(); threads decimals through parsing helpers.
src/lemke/lemke.py Updates LCP parsing to accept decimals and adds a --decimals CLI option.
src/lemke/bimatrix.py Enforces Fraction-only payoffmatrix construction; threads decimals through bimatrix file parsing and CLI plumbing.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/lemke/bimatrix.py
Comment on lines +47 to 50
AA = np.array(A, dtype=object)
if not all(isinstance(x, fractions.Fraction) for x in AA.flat):
raise TypeError("matrix must contain only Fraction values")
m, n = AA.shape
Comment thread src/lemke/utils.py
Comment on lines +64 to +67
if not isinstance(s, str):
raise TypeError(
f"to_fraction expects a string, got {type(s).__name__}: {s!r}"
)
@rahulsavani

Copy link
Copy Markdown
Member

@nataliemes At first glance, these copilot comments looks sensible, please check them out and either fix or respond. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants