Conversation
* Support custom group capacities in UI and solver Replace fixed/balanced group sizing with explicit per-group capacity support. Updated solver and solver_interface to accept group_capacities: list[int], validate that capacities sum to participants, and use capacities in capacity and scoring constraints (removed previous balanced-size logic). UI (steps.py) adds per-group capacity inputs, validation/feedback, disables solving when capacities mismatch, and passes capacities via session_state to the solver. Misc: minor code cleanups and header comments. * Switch solver API to group_capacities Migrate solver usage from a num_groups parameter to an explicit group_capacities list so callers can specify unequal group sizes. Compute balanced capacities in the CLI (group_balancer.py) from num_groups input and pass group_capacities to solver; also rename participant count to num_people for clarity. Update UI (src/ui/steps.py) to clean up stale capacity keys when num_groups is reduced and fix capacity column indexing when rendering inputs. Update tests (tests/test_solver.py) to use group_capacities arguments and adjust test descriptions accordingly. * Assert error message for empty group capacities Update tests to expect a specific ValueError message when group_capacities is empty. Added pytest.raises(..., match=...) checks in test_solver_empty_input and test_solver_positive_participants_zero_groups to ensure the exception text mentions the capacity requirement. Also adjusted formatting of a solver.solve_with_ortools call in test_solver_zero_participants_positive_groups for improved readability. Separately, linted files * Enforce non-negative and capacity-limited groups Add validation to reject negative values in group_capacities and update per-group star constraints to respect configured capacities. In run_optimization, compute upper_g and lower_g as the min of calculated bounds and group_capacities[g] so each group's assignments do not exceed its capacity, and raise ValueError if any capacity is negative. Also remove an unnecessary top-of-file path comment. * Refactor solver to support arbitrary group capacities and improve star distribution logic. * Fix: optimize CP-SAT solver search tree and star distribution bounds Resolves critical performance regressions and infeasibility states introduced by custom group capacities. The solver previously suffered from thread starvation, combinatorial explosion during the proof-of-optimality phase, and mathematically contradictory constraints. Key modifications: Proportional Star Bounds: Replaced flat global min/max bounds with capacity-weighted bounds (len(stars) * group_capacities[g] / num_people). This strictly prevents the solver from attempting to assign more stars to a group than its total capacity allows. Score Symmetry Breaking: Implemented g_sums[g1] <= g_sums[g2] for groups with identical capacities. This slices the redundant search tree by mathematically enforcing a single valid ordering for mirrored configurations, drastically accelerating the proof-of-optimality phase. Objective Lower-Bound Integrity: Restored the exact linear multiplier (actual == g_sum * num_people) for the deviation target. This ensures the optimal lower bound remains exactly 0, preventing the solver from exhaustively searching for mathematically impossible fraction-based zero-gap states. Thread Throttling: Added a minimum update interval (0.25s for Streamlit UI, 0.1s for CLI) to the solver callbacks. This prevents rapid micro-optimizations from overwhelming the main Python thread and freezing the DOM/console output. * Refactor solver architecture for transparency, maintainability, and user-led optimization This commit completes the architectural overhaul of the solver's execution pipeline, focusing on operational transparency and centralized configuration. It addresses the "round-robin" feedback loop regarding solver performance and status reporting. Key Changes: Architectural Refactoring: Extracted the core CP-SAT model building logic into a shared build_partition_model helper in src/core/solver.py. This ensures that the mathematical constraints (proportional stars, symmetry breaking, and scoring) remain identical across the CLI and Streamlit interfaces. Solver Transparency: Implemented explicit tracking of the CP-SAT solver's return status. The UI now distinguishes between a "Proven Optimal" solution and a "Best Found" solution (Feasible status) resulting from a timeout. User-Controllable Performance: Added a "Max Calculation Time" slider to Step 2, allowing users to define their own patience threshold. The solver now returns the exact elapsed time to the results page to provide better feedback on complexity. Centralized Constants: Migrated all "magic numbers" and configuration limits—including UI timeout ranges, score scaling factors, and the server-side hard timeout cap—into src/core/config.py for simplified developer maintenance. UI/UX Polish: Updated the Step 3 results header with dynamic alert banners that state the exact time taken to reach the displayed grouping and the mathematical certainty (Optimal vs. Feasible) of the result. Stability Fixes: Corrected a logic error in the objective function where pre-rounding targets in Python prevented the solver from proving optimality, and implemented score-based symmetry breaking to speed up the convergence of identically-sized groups. * Reduce solver timeout and clamp UI timeouts Lower SOLVER_TIMEOUT from 300s to 120s to tighten the server hard cap. Compute UI_TIMEOUT_MAX as max(UI_TIMEOUT_MIN, SOLVER_TIMEOUT) so it never falls below the UI minimum, and update UI_TIMEOUT_DEFAULT to enforce the minimum while capping at 60s and respecting the new max. Also remove an extraneous blank line.
This commit refactors the core engine and user interface to transition from a single-score optimization model to a dynamic, multi-dimensional scoring system. This allows for more complex group balancing across various continuous variables (e.g., Score1, Score2, ...) using user-defined weights.Key Changes:Dynamic Data Schema: Deprecated the hardcoded Score column. The system now automatically identifies all input columns matching the SCORE_PREFIX (default: "Score") and treats them as continuous optimization dimensions.Multi-Objective Solver: Updated the CP-SAT objective function to minimize a weighted sum of absolute deviations across all detected score dimensions. This includes a new weighting mechanism where users can specify the relative importance ($W_n$) of each score in the UI.Architectural Refactoring:Centralized model construction logic into build_partition_model to support multi-score inputs across CLI and Web interfaces.Refactored group aggregation logic in group_helpers.py to calculate averages and sums for all score dimensions simultaneously.UI/UX Enhancements:Step 2: Dynamically generates numeric inputs for score weights based on detected columns in the participant data.Step 3: Updated Result Cards and the Assignments Editor to display and track statistics for all score dimensions.Excel Export Evolution: Overhauled exporter.py to generate a dynamic matrix view that adjusts its width and header structure based on the number of score dimensions used.Test Suite Synchronization: Updated all unit tests across test_config.py, test_data_loader.py, test_exporter.py, and test_solver.py to align with the new multi-dimensional API and variable-weighted solver signatures.Maintainability Fixes: Implemented defensive clamping for UI timeout constants in config.py to prevent validation errors if the hard timeout cap is set lower than the UI minimum.
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
1 task
Detect score columns across all participants and use safe lookups to avoid KeyErrors (group_balancer.py). Harden CP-SAT model bounds to support negative and zero-sum score dimensions, compute a dynamic diff bound, and use safer name lookups (src/core/solver.py). Tighten UI behavior and formatting: warn when no score columns, use 2-decimal formatting for numeric columns, and avoid rendering inputs when empty (src/ui/steps.py, src/ui/results_renderer.py). Upgrade Excel exporter with dynamic column labeling, computed header size, and accurate dataset-level stats derived from the result DataFrame (src/utils/exporter.py). Update and add tests to reflect SCORE_PREFIX expectation and multi-dimensional, weighted solver behavior; include small type/format tweaks. Also add a binary errors.err file.
* chore(deps): bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [numpy](https://github.com/numpy/numpy), [pandas](https://github.com/pandas-dev/pandas) and [ruff](https://github.com/astral-sh/ruff). Updates `numpy` from 2.2.6 to 2.4.4 - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](numpy/numpy@v2.2.6...v2.4.4) Updates `pandas` from 2.3.3 to 3.0.2 - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Commits](pandas-dev/pandas@v2.3.3...v3.0.2) Updates `ruff` from 0.15.10 to 0.15.11 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](astral-sh/ruff@0.15.10...0.15.11) --- updated-dependencies: - dependency-name: numpy dependency-version: 2.4.4 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: pandas dependency-version: 3.0.2 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: ruff dependency-version: 0.15.11 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * chore: update supported python versions (3.10-3.14); update requirements.txt; fix linting/formatting --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Introduce advanced constraint support (Groupers/Separators) and solver options across core, UI and tests. Added COL_GROUPER and COL_SEPARATOR config keys and increased SOLVER_TIMEOUT; data loader and session init now inject missing tag columns. Solver was refactored to support opt_mode (Simple/Advanced) and conflict_priority, implement pigeonhole spreading for Separators, cohesion penalties to keep Groupers together, improved star handling, and cleaner objective construction; SolutionPrinter and solver parameter usage were streamlined. Streamlit interface and step UI updated with advanced solver controls, file import/tag handling, session defaults, and safer result rendering. Expanded tests to cover Simple mode, pigeonhole/separator behavior, cohesion, and tag conflict resolution; adjusted existing tests for new signatures and behaviors.
Treat Groupers/Separators as character-tokenized tags (ignore commas/spaces) and update conflict/cohesion logic accordingly. Inform users in the UI about the new tagging model, improve file upload handling and data validation (warnings for empty names/invalid scores), refine solver configuration controls and error handling, and adjust result editor behavior and metrics display. Reduce global SOLVER_TIMEOUT from 3600s to 600s. Update unit tests to reflect character tokenization and add tests for comma handling and character-based grouping. Miscellaneous cleanup: remove stray prints, minor comment tweaks, and normalize solver_interface call arguments.
Remove the legacy 'star' (ADVANTAGE_CHAR) feature and related distribution logic across the codebase. Deleted ADVANTAGE_CHAR and all respect_stars parameters and constraints from the solver and its callers, removed star counting from group aggregation and tests, and removed star-related test cases. UI updates: revised instructions to treat every character in Groupers/Separators as its own tag (commas/spaces ignored), updated sample manual data to use single-character tags, and added an "Add Score Column" button. Fixed results card column indexing for displayed averages. Misc: cleaned up an unused import, adjusted internal comment section numbering, and updated tests to match the simplified behavior.
Multiple improvements across data loading, solver logic, UI navigation, and tests: - src/core/data_loader.py: Preserve original score series, coerce to numeric, and emit warnings for missing or non-numeric scores before filling with zeros. - src/core/solver.py: Make conflict-priority checks exact (==) and simplify optimization-mode comparison; tighten weighted-difference variable bounds to avoid excessive ranges by computing a safe bound using weight multiplier. - src/ui/session_manager.py: Clamp navigation input to valid steps (1-3) before rerunning. - src/ui/steps.py: Robustly generate new score column names by computing the max numeric suffix to avoid collisions; simplify radio options using concise keys with formatters for labels; add has_scores guard and warning, and disable the "Generate Groupings" button unless capacities and scores are valid. - tests/test_solver.py: Update solver tests to match the refined conflict-resolution and capacity logic; increase participant/capacity scenarios and strengthen assertions to verify group placement for both Groupers and Separators cases; add helper checks for grouping expectations. These changes improve input robustness, prevent naming collisions, constrain solver variables safely, and make the UI and tests consistent with the updated behavior.
Replace the string sentinel "_SIMPLE_TOTAL_" with an object sentinel to avoid accidental string comparisons and to prevent that token from appearing in CP-SAT variable names. Derive a col_name_str for all score columns (including the simple total) and use it when naming model variables, and only apply the ordering constraint to the first non-skipped score column. Update UI table formatting to include the "Sum" column. Adjust tests to reflect separator and capacity changes (use a 3/1 split and empty-string separators) and assert separator spread counts instead of fixed group sizes.
Solver: normalize None/NaN values for grouper/separator before tokenization; compute max_total_w_diff during scoring and derive a dynamic base_cohesion_penalty (replacing the fixed 10**9) so cohesion penalties are scaled relative to score contributions; move cohesion penalty construction after scoring and adjust capacity penalty scaling. UI - results_renderer: include constraint tag columns (grouper/separator) in group card member table and ensure score columns formatting; add header metrics comment. UI - steps: improve numeric coercion by only counting non-empty invalid values, fill invalid numerics with 0, coerce categorical constraint columns to strings (empty for NaN), and add stable keys to weight inputs. These changes improve robustness to sparse input data and make cohesion objective weight-safe and UI displays more complete.
…nsional-Scoring Implement dynamic data schema and multi-dimensional weighted scoring
- Added module and function-level docstrings to build.py and all __init__.py files - Standardized documentation across all core, ui, and util modules - Cleaned up annotations and ensured professional comment standards
- Softened 'proven optimal' claim to 'high-quality mathematically optimized' to reflect feasible solutions during timeouts.
…ation-readme.md docs: enhance project documentation and standardize python docstrings
- Migrated CI to uv and updated requirements. - Implemented core solver architecture (Builder, Strategy, TagProcessor). - Hardened security with path validation, size limits, and CP-SAT overflow protection. - Decoupled UI logic into Service layers and removed unsafe_allow_html. - Modernized Streamlit parameters (use_container_width -> width='stretch'). - Achieved 100% Google-style documentation compliance. - Expanded test suite to 77 tests with 94% functional coverage. - Restored and verified original UI look and feel.
…-Sizes,-and-Advanced-Categorical-Constraints' into Professional-standards-refactor
… Professional-standards-refactor
…Group-Balancer into ci/cd-pipeline-upgrade
…ew feedback Phase 1: CI hardening, SHA pinning, and bot-actor guards. Phase 2: Solver logic RUF046 fixes and missing-aware participant models. Phase 3: Stabilized Pre-CI pipeline with sequential pytest and output streaming. Phase 4: Hermeticized test suite with better mocking and dynamic scaling.
Phase 1: Hardened CI workflow skip logic and stabilized pre-CI tool exports/validation. Phase 2: Optimized UI performance with Excel memoization and explicitly initialized solver symmetry. Phase 3: Synchronized GEMINI.md standards with refined caching and testing insights. Phase 4: Hermeticized UI tests to handle Streamlit cache serialization.
1. CI: Simplified version range determination by removing stale 3.15-dev filter. 2. UI: Optimized cache hashing by excluding the DataFrame from auto-hashing. 3. Tools: Hardened version validation with exact equality checks. 4. Tests: Hermeticized edge tests by removing dead code mocks.
1. UI: Fixed solver error swallowing by prioritizing error rendering over the missing-result guard. 2. Tools: Implemented logical version range fallback (3.10-3.14) for inverted min/max inputs. 3. Tools: Optimized directory cleanup with efficient in-place os.walk pruning. 4. Infrastructure: Simplified CI version range determination logic.
1. Removed ignored encoding argument from subprocess.run. 2. Tightened UI cache key to a tuple to prevent hash collisions.
…tants 1. GEMINI.md: Reframe PowerShell as maintainer-local preference. 2. tools/pre_ci.py: Define DEFAULT_MIN_PY and DEFAULT_MAX_PY constants.
1. tools/pre_ci.py: Updated execute() docstring to match implemented execution sequence.
refactor: professional standards refactor & uv migration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.