Files
edx-platform/openedx/core/lib/grade_utils.py
Irtaza Akram ec2a698604 cleanup references of python 2 & <3.11 (#35799)
* chore: cleanup of old python references
2024-11-15 16:58:20 +05:00

67 lines
2.3 KiB
Python

"""
Helpers functions for grades and scores.
"""
import math
def compare_scores(earned1, possible1, earned2, possible2, treat_undefined_as_zero=False):
"""
Returns a tuple of:
1. Whether the 2nd set of scores is higher than the first.
2. Grade percentage of 1st set of scores.
3. Grade percentage of 2nd set of scores.
If ``treat_undefined_as_zero`` is True, this function will treat
cases where ``possible1`` or ``possible2`` is 0 as if
the (earned / possible) score is 0. If this flag is false,
a ZeroDivisionError is raised.
"""
try:
percentage1 = float(earned1) / float(possible1)
except ZeroDivisionError:
if not treat_undefined_as_zero:
raise
percentage1 = 0.0
try:
percentage2 = float(earned2) / float(possible2)
except ZeroDivisionError:
if not treat_undefined_as_zero:
raise
percentage2 = 0.0
is_higher = percentage2 >= percentage1
return is_higher, percentage1, percentage2
def is_score_higher_or_equal(earned1, possible1, earned2, possible2, treat_undefined_as_zero=False):
"""
Returns whether the 2nd set of scores is higher than the first.
If ``treat_undefined_as_zero`` is True, this function will treat
cases where ``possible1`` or ``possible2`` is 0 as if
the (earned / possible) score is 0. If this flag is false,
a ZeroDivisionError is raised.
"""
is_higher_or_equal, _, _ = compare_scores(earned1, possible1, earned2, possible2, treat_undefined_as_zero)
return is_higher_or_equal
def round_away_from_zero(number, digits=0):
"""
Round numbers using the 'away from zero' strategy as opposed to the
'Banker's rounding strategy.' The strategy refers to how we round when
a number is half way between two numbers. eg. 0.5, 1.5, etc. In python 3
numbers round towards even. So 0.5 would round to 0 but 1.5 would round to 2.
See here for more on floating point rounding strategies:
https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules
We want to continue to round away from zero so that student grades remain
consistent and don't suddenly change.
"""
p = 10.0 ** digits
if number >= 0:
return float(math.floor((number * p) + 0.5)) / p
else:
return float(math.ceil((number * p) - 0.5)) / p