Skip to content

Add algebraic __str__ and detailed __repr__ to Python LP API classes#1400

Open
jackthepunished wants to merge 1 commit into
NVIDIA:mainfrom
jackthepunished:feature/str-repr-for-lp-api
Open

Add algebraic __str__ and detailed __repr__ to Python LP API classes#1400
jackthepunished wants to merge 1 commit into
NVIDIA:mainfrom
jackthepunished:feature/str-repr-for-lp-api

Conversation

@jackthepunished
Copy link
Copy Markdown
Contributor

@jackthepunished jackthepunished commented Jun 6, 2026

The Python LP modeling classes (Variable, LinearExpression, QuadraticExpression, Constraint, Problem) currently fall back to <cuopt.linear_programming.problem.X object at 0x...> when printed, which makes model construction hard to verify in notebooks and REPLs. This adds str (algebraic form, e.g. 2.0 * x + 3.0 * y <= 10.0) and repr (detailed summary with bounds, type, and variable/constraint counts and solve status) to all five classes. Purely additive; covered by est_str_and_repr in est_python_API.py.

Adds __str__ and __repr__ to Variable, LinearExpression,

QuadraticExpression, Constraint, and Problem. Printing these objects now

shows their algebraic form (e.g. '2.0 * x + 3.0 * y <= 10.0') and the REPL

shows a detailed summary, improving debuggability in notebooks and

interactive sessions. The change is purely additive.

Signed-off-by: jackthepunished <kosapinarbahadir@gmail.com>
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented Jun 6, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@jackthepunished jackthepunished marked this pull request as ready for review June 6, 2026 00:36
@jackthepunished jackthepunished requested a review from a team as a code owner June 6, 2026 00:36
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Worried about impact? Review this PR in Change Stack to explore blast radius before you approve or request changes.

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds human-readable __str__ and __repr__ methods across the LP API object hierarchy. Internal formatting utilities render algebraic expressions with term elision and coefficient simplification, applied by Variable, LinearExpression, QuadraticExpression, and Problem display methods, with comprehensive test validation.

Changes

Human-readable display support for LP API objects

Layer / File(s) Summary
Internal formatting utilities and expression builder
python/cuopt/cuopt/linear_programming/problem.py
Internal helpers (_SENSE_SYMBOLS, _TYPE_NAMES, _var_display_name, _type_display, _ExprBuilder, _format_linear) construct algebraic string representations with sign handling, zero elision, and ±1 coefficient simplification.
Variable, LinearExpression, and QuadraticExpression display
python/cuopt/cuopt/linear_programming/problem.py
Variable renders name/index/type/bounds/value; LinearExpression uses shared linear format helper; QuadraticExpression renders quadratic matrix terms and linear parts with x^2 notation for same-variable products.
Problem summary display
python/cuopt/cuopt/linear_programming/problem.py
Problem.__repr__ and __str__ produce multi-line summary with objective sense, variable type counts, linear/quadratic constraint counts, nonzero count, and (when solved) status and objective value.
Comprehensive test validation
python/cuopt/cuopt/tests/linear_programming/test_python_API.py
Test test_str_and_repr() asserts __str__ and __repr__ outputs for all display-enabled objects, covering named/unnamed entities, empty/constant expressions, and pre/post-solve behavior.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding algebraic str and detailed repr methods to Python LP API classes.
Description check ✅ Passed The description directly relates to the changeset by explaining why the change was made (readability in notebooks/REPLs) and what functionality was added (str and repr methods).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
python/cuopt/cuopt/tests/linear_programming/test_python_API.py (1)

14-25: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add missing LinearExpression import to prevent NameError in the new test.

LinearExpression is referenced at Line 873, Line 875, and Line 876 but is not imported, so this test will fail at runtime.

Proposed fix
 from cuopt.linear_programming.problem import (
     CONTINUOUS,
     INTEGER,
     MAXIMIZE,
     MINIMIZE,
     SEMI_CONTINUOUS,
     CType,
+    LinearExpression,
     Problem,
     VType,
     sense,
     QuadraticExpression,
 )
As per coding guidelines, “Run pre-commit hooks before committing code to enforce code linters and formatters”; Ruff’s F821 here indicates a correctness break that should be fixed before merge.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cuopt/cuopt/tests/linear_programming/test_python_API.py` around lines
14 - 25, The test imports from cuopt.linear_programming.problem but omits
LinearExpression, causing NameError in tests referencing LinearExpression;
update the import list in test_python_API.py to include LinearExpression (i.e.,
add LinearExpression to the grouped import alongside CONTINUOUS, INTEGER,
MAXIMIZE, MINIMIZE, SEMI_CONTINUOUS, CType, Problem, VType, sense,
QuadraticExpression) so the symbol is available where referenced.

Sources: Coding guidelines, Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/cuopt/cuopt/linear_programming/problem.py`:
- Line 21: The _SENSE_SYMBOLS dictionary is created before the constants LE, GE,
and EQ are defined, causing an import-time NameError; fix by deferring its
construction until after those constants are declared (or by keying it with the
raw numeric/char codes used for LE/GE/EQ instead of the names), i.e., move or
rebuild _SENSE_SYMBOLS after the definitions of LE, GE, EQ (or replace keys with
the literal codes) so references in _SENSE_SYMBOLS resolve correctly.

---

Outside diff comments:
In `@python/cuopt/cuopt/tests/linear_programming/test_python_API.py`:
- Around line 14-25: The test imports from cuopt.linear_programming.problem but
omits LinearExpression, causing NameError in tests referencing LinearExpression;
update the import list in test_python_API.py to include LinearExpression (i.e.,
add LinearExpression to the grouped import alongside CONTINUOUS, INTEGER,
MAXIMIZE, MINIMIZE, SEMI_CONTINUOUS, CType, Problem, VType, sense,
QuadraticExpression) so the symbol is available where referenced.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 84099242-4510-46e2-b7dc-41322ef3afa6

📥 Commits

Reviewing files that changed from the base of the PR and between 2384454 and 3a01e57.

📒 Files selected for processing (2)
  • python/cuopt/cuopt/linear_programming/problem.py
  • python/cuopt/cuopt/tests/linear_programming/test_python_API.py


# ---- Display helpers for __str__/__repr__ ----

_SENSE_SYMBOLS = {LE: "<=", GE: ">=", EQ: "=="}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix import-time NameError in _SENSE_SYMBOLS initialization.

LE, GE, and EQ are referenced before they are defined, so importing this module will fail at Line 21.

Suggested fix
-_SENSE_SYMBOLS = {LE: "<=", GE: ">=", EQ: "=="}
+_SENSE_SYMBOLS = {
+    CType.LE: "<=",
+    CType.GE: ">=",
+    CType.EQ: "==",
+}

If you want to keep helpers at the top of the file, an alternative is to key by raw codes:

-_SENSE_SYMBOLS = {LE: "<=", GE: ">=", EQ: "=="}
+_SENSE_SYMBOLS = {"L": "<=", "G": ">=", "E": "=="}
🧰 Tools
🪛 Ruff (0.15.15)

[error] 21-21: Undefined name LE

(F821)


[error] 21-21: Undefined name GE

(F821)


[error] 21-21: Undefined name EQ

(F821)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cuopt/cuopt/linear_programming/problem.py` at line 21, The
_SENSE_SYMBOLS dictionary is created before the constants LE, GE, and EQ are
defined, causing an import-time NameError; fix by deferring its construction
until after those constants are declared (or by keying it with the raw
numeric/char codes used for LE/GE/EQ instead of the names), i.e., move or
rebuild _SENSE_SYMBOLS after the definitions of LE, GE, EQ (or replace keys with
the literal codes) so references in _SENSE_SYMBOLS resolve correctly.

Source: Linters/SAST tools

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.

1 participant