diff --git a/lib/WeBWorK/AchievementEvaluator.pm b/lib/WeBWorK/AchievementEvaluator.pm index b0aa6c20b9..ac2884066b 100644 --- a/lib/WeBWorK/AchievementEvaluator.pm +++ b/lib/WeBWorK/AchievementEvaluator.pm @@ -105,7 +105,6 @@ sub checkForAchievements { # $pg->{result} reflects the current submission, $pg->{state} holds the best result # close the unlimited achievement points loophole by only using the current result! $problem->status($pg->{result}->{score}); - $problem->sub_status($pg->{state}->{sub_recorded_score}); $problem->attempted(1); $problem->num_correct($pg->{state}->{num_of_correct_ans}); $problem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); diff --git a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm index b9d6f0c92b..d15fc6e14a 100644 --- a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm +++ b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm @@ -1456,11 +1456,17 @@ sub body { # next, store the state in the database if that makes sense if ($submitAnswers && $will{recordAnswers}) { - $problems[$i]->status(wwRound(2,$pg_results[$i]->{state}->{recorded_score})); + # Reduced scoring adjustments + my $new_score = WeBWorK::ContentGenerator::ProblemUtil::ProblemUtil::compute_reduced_score( + $self, $pureProblem, $set, $pg_results[$i]->{state}->{recorded_score}); + + $problems[$i]->status(wwRound(2,$new_score)); + $problems[$i]->sub_status($pg_results[$i]->{state}->{recorded_score}); $problems[$i]->attempted(1); $problems[$i]->num_correct($pg_results[$i]->{state}->{num_of_correct_ans}); $problems[$i]->num_incorrect($pg_results[$i]->{state}->{num_of_incorrect_ans}); - $pureProblem->status(wwRound(2,$pg_results[$i]->{state}->{recorded_score})); + $pureProblem->status(wwRound(2,$new_score)); + $pureProblem->sub_status($pg_results[$i]->{state}->{recorded_score}); $pureProblem->attempted(1); $pureProblem->num_correct($pg_results[$i]->{state}->{num_of_correct_ans}); $pureProblem->num_incorrect($pg_results[$i]->{state}->{num_of_incorrect_ans}); @@ -1746,8 +1752,9 @@ sub body { my $pScore = 0; my $numParts = 0; if (ref($pg)) { # then we have a pg object - ### - $pScore = $pg->{state}->{recorded_score}; + # Reduced scoring adjustments + $pScore = WeBWorK::ContentGenerator::ProblemUtil::ProblemUtil::compute_reduced_score( + $self, $problems[$i], $set, $pg->{state}->{recorded_score}); $probStatus[$i] = $pScore; $numParts = 1; ### diff --git a/lib/WeBWorK/ContentGenerator/ProblemUtil/ProblemUtil.pm b/lib/WeBWorK/ContentGenerator/ProblemUtil/ProblemUtil.pm index bc8dbbf37f..f1c701dec0 100644 --- a/lib/WeBWorK/ContentGenerator/ProblemUtil/ProblemUtil.pm +++ b/lib/WeBWorK/ContentGenerator/ProblemUtil/ProblemUtil.pm @@ -134,13 +134,16 @@ sub process_and_log_answer{ # store state in DB if it makes sense if ($will{recordAnswers}) { - $problem->status($pg->{state}->{recorded_score}); - $problem->sub_status($pg->{state}->{sub_recorded_score}); + # Reduced scoring adjustments + my $new_score = compute_reduced_score($self, $problem, $set, $pg->{state}->{recorded_score}); + + $problem->status($new_score); + $problem->sub_status($pg->{state}->{recorded_score}); $problem->attempted(1); $problem->num_correct($pg->{state}->{num_of_correct_ans}); $problem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); - $pureProblem->status($pg->{state}->{recorded_score}); - $pureProblem->sub_status($pg->{state}->{sub_recorded_score}); + $pureProblem->status($new_score); + $pureProblem->sub_status($pg->{state}->{recorded_score}); $pureProblem->attempted(1); $pureProblem->num_correct($pg->{state}->{num_of_correct_ans}); $pureProblem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); @@ -675,4 +678,34 @@ Comment: $comment return ""; } +# Determines if a set is in the reduced scoring period and applies +# the reduced scoring adjustment to the portion of the score earned +# during the reduced scoring period. +sub compute_reduced_score { + my ($self, $problem, $set, $new_status) = @_; + + my $r = $self->r; + my $reducedScoringEnabled = $r->{ce}->{pg}{ansEvalDefaults}{enableReducedScoring}; + my $reducedScoringValue = $r->{ce}->{pg}{ansEvalDefaults}{reducedScoringValue}; + + # If no adjustments need to be applied, return the full score. + if (! $reducedScoringEnabled + || ! $set->enable_reduced_scoring + || ! $set->reduced_scoring_date + || $set->reduced_scoring_date == $set->due_date + || time < $set->reduced_scoring_date + || $reducedScoringValue == 1 + ) { + return $new_status; + } + + # Invert the reduced scoring computation to get the portion of the + # grade earned before the reduced scoring date, then return the + # adjusted score by applying the reduced scoring adjustment to the + # portion done after the reduced scoring date. + my $pre_reduced_score = $problem->sub_status - ($problem->sub_status + - $problem->status) / (1 - $reducedScoringValue); + return $pre_reduced_score + $reducedScoringValue * ($new_status - $pre_reduced_score); +} + 1; diff --git a/lib/WeBWorK/DB/Record/UserProblem.pm b/lib/WeBWorK/DB/Record/UserProblem.pm index f3c0812b94..0e848a0d72 100644 --- a/lib/WeBWorK/DB/Record/UserProblem.pm +++ b/lib/WeBWorK/DB/Record/UserProblem.pm @@ -43,14 +43,14 @@ BEGIN { # periodic re-randomization number of attempts for the current seed prCount => {type => "INT"}, problem_seed => { type=>"INT" }, - status => { type=>"FLOAT" }, + status => { type=>"FLOAT" }, # The adjusted problem score attempted => { type=>"INT" }, last_answer => { type=>"TEXT" }, num_correct => { type=>"INT" }, num_incorrect => { type=>"INT" }, att_to_open_children => { type=>"INT" }, counts_parent_grade => { type=>"INT" }, - sub_status => { type=>"FLOAT" }, # A subsidiary status used to implement the reduced scoring period + sub_status => { type=>"FLOAT" }, # The raw problem score before any adjustments # a field for flags which need to be set flags => { type=>"TEXT" }, ); diff --git a/lib/WeBWorK/PG/Local.pm b/lib/WeBWorK/PG/Local.pm index cf1071eaff..e105968b04 100644 --- a/lib/WeBWorK/PG/Local.pm +++ b/lib/WeBWorK/PG/Local.pm @@ -375,8 +375,7 @@ EOF #warn "PG: retrieving the problem state and giving it to the translator\n"; $translator->rh_problem_state({ - recorded_score => $problem->status, - sub_recorded_score => $problem->sub_status, + recorded_score => $problem->sub_status, # using sub_status since it is the raw score. num_of_correct_ans => $problem->num_correct, num_of_incorrect_ans => $problem->num_incorrect, }); diff --git a/lib/WeBWorK/PG/Remote.pm b/lib/WeBWorK/PG/Remote.pm index 573c396eed..0920a671b8 100644 --- a/lib/WeBWorK/PG/Remote.pm +++ b/lib/WeBWorK/PG/Remote.pm @@ -99,8 +99,7 @@ EOF extra_packages_to_load => [ @extra_packages_to_load ], envir => $envir, problem_state => { - recorded_score => $problem->status, - sub_recorded_score => $problem->sub_status, + recorded_score => $problem->sub_status, # Using sub_status since it is the raw score. num_of_correct_ans => $problem->num_correct, num_of_incorrect_ans => $problem->num_incorrect, },