Skip to content

fix: fix the problem score when added in graded sub-section#272

Open
marslanabdulrauf wants to merge 1 commit into
openedx:mainfrom
mitodl:marslan/12023-problem-score
Open

fix: fix the problem score when added in graded sub-section#272
marslanabdulrauf wants to merge 1 commit into
openedx:mainfrom
mitodl:marslan/12023-problem-score

Conversation

@marslanabdulrauf

Copy link
Copy Markdown
Contributor

Related Ticket

https://github.com/mitodl/hq/issues/12023 (MIT internal)

Description

This pull request makes a targeted improvement to the grading logic in the CapaBlock XBlock. The main change ensures that when a learner has not made any attempts on a problem, the possible score reflects the current definition of the problem, rather than a potentially outdated persisted score. This helps maintain grading accuracy, especially after problem edits.

Grading logic improvements:

  • Updated get_progress in capa_block.py to set raw_possible to the current max_score() when there are no attempts, ensuring the possible score is always up-to-date with the latest problem definition.

Steps to reproduce: (main branch)

  1. Log in as a course author.
  2. Go to a unit inside of a graded subsection
  3. Add a problem (any problem) - put in something for the problem question and answer.
  4. The default for any new problem is to be weighted at 1 point.
  5. Save the problem, publish the unit.
  6. The problem will show as worth 0 points and ungraded. (see first screenshot)

Testing

Repeat the above steps after checking out to this branch

Merge checklist:
Check off if complete or not applicable:

  • Version bumped
  • Changelog record added
  • Documentation updated (not only docstrings)
  • Fixup commits are squashed away
  • Unit tests added/updated
  • Manual testing instructions provided
  • Noted any: Concerns, dependencies, migration issues, deadlines, tickets

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Jul 6, 2026
@openedx-webhooks

Copy link
Copy Markdown

Thanks for the pull request, @marslanabdulrauf!

This repository is currently maintained by @openedx/axim-engineering.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts CapaBlock grading progress calculation so that when a learner has zero attempts, the “possible points” reflects the current problem definition (via max_score) rather than a potentially stale persisted value, improving grading accuracy after problem edits.

Changes:

  • Update CapaBlock.get_progress() to recompute raw_possible from the current problem definition when attempts == 0.
  • Bump package version from 0.17.0 to 0.17.1.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
xblocks_contrib/problem/capa_block.py Adjusts progress computation for zero-attempt learners to avoid stale possible-point values.
xblocks_contrib/init.py Version bump to reflect the behavioral change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +998 to +1003
if not self.attempts:
# Nothing has ever been submitted for this user/block, so there's no
# real grade history to protect. Reflect the problem's current
# definition instead of a stale persisted score (e.g. left over from
# before an author edited the problem after it was first previewed).
raw_possible = self.max_score() or raw_possible
Comment on lines +998 to +1003
if not self.attempts:
# Nothing has ever been submitted for this user/block, so there's no
# real grade history to protect. Reflect the problem's current
# definition instead of a stale persisted score (e.g. left over from
# before an author edited the problem after it was first previewed).
raw_possible = self.max_score() or raw_possible

@farhan farhan 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.

Thanks for the fix — the diagnosis is correct: the score persisted into Scope.user_state at first lcp init (capa_block.py:892-893) is never refreshed after an author edits the problem, so get_progress() reports a stale total for users with no attempts.

A few requests before merge:

  • ⚠️ Performance: the new max_score() call re-parses the problem on every render/AJAX for unattempted users — please memoize or narrow the condition
  • 🧪 Tests: grading-behavior change ships with no unit tests (checklist unchecked) — existing get_progress tests are easy to extend
  • 🔁 Upstream parity: the identical code in edx-platform/xmodule/capa_block.py (still the flag-off default) keeps the bug — please file a companion issue/PR
  • 📝 Changelog: version bumped but no CHANGELOG.rst entry
  • 💬 Nit: max_score() or raw_possible conflates "parse error" with "genuinely 0-point problem"

Details

Performancemax_score() builds a fresh LoncapaSystem + LoncapaProblem each call (full XML parse + responder instantiation; minimal_init=True only skips script execution, and nothing caches the result). get_progress() runs once per student_view render and three times per AJAX dispatch (handle_ajax L512/538/541), and not self.attempts is true for every learner before their first submission — the majority of problem views. Previously the render path had zero max_score() calls. Options: memoize per block instance, reuse self.lcp.get_max_score() when lcp is already built, or restrict the recompute to self.score and self.score.raw_possible == 0.

Tests — two cheap cases next to the existing get_progress tests in xblocks_contrib/problem/tests/test_capa_block.py: (1) stale persisted score + attempts == 0 → current max_score() wins; (2) attempts > 0 → persisted score is protected.

Upstream parityget_progress in edx-platform/xmodule/capa_block.py#L918 is identical and unfixed, and the extracted block only runs behind a waffle flag, so flag-on/off deployments will display different point totals for the same course. Even if the intent is to fix forward only, an issue on edx-platform documenting the divergence would help.

Fallback nitmax_score() returns 0 both on LoncapaProblemError and for a genuinely zero-point problem; max_score() or raw_possible falls back to the stale persisted score in both cases — the exact bug class this PR fixes, in the other direction. A short comment (or distinguishing the two) would make the intent clear.

@farhan

farhan commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@marslanabdulrauf Some agentic code review, please address the changes if you agree.

Sharing of the test screenshots will be great.

Thanks for creating the PR.

@mphilbrick211 mphilbrick211 moved this from Needs Triage to In Eng Review in Contributions Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open-source-contribution PR author is not from Axim or 2U

Projects

Status: In Eng Review

Development

Successfully merging this pull request may close these issues.

5 participants