diff --git a/cms/db/task.py b/cms/db/task.py
index c753efdce1..acd83b2f11 100644
--- a/cms/db/task.py
+++ b/cms/db/task.py
@@ -500,7 +500,8 @@ def score_type_object(self) -> "ScoreType":
from cms.grading.scoretypes import get_score_type
# This can raise.
self._cached_score_type_object = get_score_type(
- self.score_type, self.score_type_parameters, public_testcases)
+ self.score_type, self.score_type_parameters, public_testcases,
+ self.task.score_precision)
# If an exception is raised these updates don't take place:
# that way, next time this property is accessed, we get a
# cache miss again and the same exception is raised again.
diff --git a/cms/grading/scoretypes/__init__.py b/cms/grading/scoretypes/__init__.py
index cdcaa9f642..eb97f6ecb7 100644
--- a/cms/grading/scoretypes/__init__.py
+++ b/cms/grading/scoretypes/__init__.py
@@ -46,7 +46,8 @@ def get_score_type_class(name: str):
def get_score_type(
- name: str, parameters: object, public_testcases: dict[str, bool]
+ name: str, parameters: object, public_testcases: dict[str, bool],
+ score_precision: int,
) -> ScoreType:
"""Construct the ScoreType specified by parameters.
@@ -63,4 +64,4 @@ def get_score_type(
"""
class_ = get_score_type_class(name)
- return class_(parameters, public_testcases)
+ return class_(parameters, public_testcases, score_precision)
diff --git a/cms/grading/scoretypes/abc.py b/cms/grading/scoretypes/abc.py
index aa1d1eb92b..127067f1d4 100644
--- a/cms/grading/scoretypes/abc.py
+++ b/cms/grading/scoretypes/abc.py
@@ -59,7 +59,8 @@ class ScoreType(metaclass=ABCMeta):
TEMPLATE = ""
- def __init__(self, parameters: object, public_testcases: dict[str, bool]):
+ def __init__(self, parameters: object, public_testcases: dict[str, bool],
+ score_precision: int):
"""Initializer.
parameters: format is specified in the subclasses.
@@ -70,6 +71,7 @@ def __init__(self, parameters: object, public_testcases: dict[str, bool]):
"""
self.parameters = parameters
self.public_testcases = public_testcases
+ self.score_precision = score_precision
# Preload the maximum possible scores.
try:
@@ -87,7 +89,6 @@ def format_score(
score: float,
max_score: float,
unused_score_details: object,
- score_precision: int,
translation: Translation = DEFAULT_TRANSLATION,
) -> str:
"""Produce the string of the score that is shown in CWS.
@@ -102,16 +103,14 @@ def format_score(
max_score: the maximum score that can be achieved.
unused_score_details: the opaque data structure that
the ScoreType produced for the submission when scoring it.
- score_precision: the maximum number of digits of the
- fractional digits to show.
translation: the translation to use.
return: the message to show.
"""
return "%s / %s" % (
- translation.format_decimal(round(score, score_precision)),
- translation.format_decimal(round(max_score, score_precision)))
+ translation.format_decimal(score),
+ translation.format_decimal(max_score))
def get_html_details(
self,
@@ -348,9 +347,17 @@ class ScoreTypeGroup(ScoreTypeAlone):
def get_max_score(self, group_parameter: ScoreTypeGroupParameters) -> float:
if isinstance(group_parameter, tuple) or isinstance(group_parameter, list):
- return group_parameter[0]
+ score = group_parameter[0]
else:
- return group_parameter["max_score"]
+ score = group_parameter["max_score"]
+ assert (
+ round(
+ score,
+ self.score_precision
+ ) == score
+ ), (f"The max score for a subtask"
+ "has more precision than the task allows.")
+ return score
def get_testcases(self, group_parameter: ScoreTypeGroupParameters) -> int | str | list[str]:
if isinstance(group_parameter, tuple) or isinstance(group_parameter, list):
@@ -507,7 +514,7 @@ def compute_score(self, submission_result):
tc["show_in_oi_restricted_feedback"] = (
tc["idx"] == tc_first_lowest_idx)
- score += st_score
+ score += rounded_score
subtasks.append({
"idx": st_idx,
# We store the fraction so that an "example" testcase
@@ -519,12 +526,17 @@ def compute_score(self, submission_result):
"max_score": self.get_max_score(parameter),
"testcases": testcases})
if all(self.public_testcases[tc_idx] for tc_idx in target):
- public_score += st_score
+ public_score += rounded_score
public_subtasks.append(subtasks[-1])
else:
public_subtasks.append({"idx": st_idx,
"testcases": public_testcases})
- ranking_details.append("%g" % st_score)
+ ranking_details.append("%g" % rounded_score)
+
+ # The following line should be unnecessary since subtask scores
+ # are rounded. However we are using floats not Decimals
+ # and this can cause errors. So we round again to be sure.
+ score = round(score, score_precision)
return score, subtasks, public_score, public_subtasks, ranking_details
diff --git a/cms/grading/scoring.py b/cms/grading/scoring.py
index 114f560e41..b74782620a 100644
--- a/cms/grading/scoring.py
+++ b/cms/grading/scoring.py
@@ -108,7 +108,6 @@ def task_score(
task: Task,
public: bool = False,
only_tokened: bool = False,
- rounded: bool = False,
) -> tuple[float, bool]:
"""Return the score of a contest's user on a task.
@@ -122,7 +121,6 @@ def task_score(
at the results of tokened submissions (that is, the score that the user
would obtain if all non-tokened submissions scored 0.0, or equivalently
had not been scored yet).
- rounded: if True, round the score to the task's score_precision.
return: the score of user on task, and True if not
all submissions of the participation in the task have been scored.
@@ -177,8 +175,12 @@ def task_score(
score = _task_score_max_tokened_last(score_details_tokened)
else:
raise ValueError("Unknown score mode '%s'" % task.score_mode)
- if rounded:
- score = round(score, task.score_precision)
+
+ # The following line should be unnecessary since subtask scores
+ # are rounded. However we are using floats not Decimals
+ # and this can cause errors. So we round again to be sure.
+ score = round(score, task.score_precision)
+
return score, partial
diff --git a/cms/server/admin/handlers/contestranking.py b/cms/server/admin/handlers/contestranking.py
index 2adc4f2600..ca8806a67a 100644
--- a/cms/server/admin/handlers/contestranking.py
+++ b/cms/server/admin/handlers/contestranking.py
@@ -66,7 +66,7 @@ def get(self, contest_id, format="online"):
total_score = 0.0
partial = False
for task in self.contest.tasks:
- t_score, t_partial = task_score(p, task, rounded=True)
+ t_score, t_partial = task_score(p, task)
p.scores.append((t_score, t_partial))
total_score += t_score
partial = partial or t_partial
diff --git a/cms/server/admin/templates/submission.html b/cms/server/admin/templates/submission.html
index 727e043671..7213ab56d1 100644
--- a/cms/server/admin/templates/submission.html
+++ b/cms/server/admin/templates/submission.html
@@ -129,9 +129,9 @@
Submission details
Score as seen by user |
{% if s.token is not none %}
- {{ st.format_score(sr.score, st.max_score, sr.score_details, s.task.score_precision) }}
+ {{ st.format_score(sr.score, st.max_score, sr.score_details) }}
{% else %}
- {{ st.format_score(sr.public_score, st.max_public_score, sr.public_score_details, s.task.score_precision) }}
+ {{ st.format_score(sr.public_score, st.max_public_score, sr.public_score_details) }}
{% endif %}
|
diff --git a/cms/server/contest/formatting.py b/cms/server/contest/formatting.py
index 2b670fa35d..7b04bc1b0c 100644
--- a/cms/server/contest/formatting.py
+++ b/cms/server/contest/formatting.py
@@ -130,7 +130,7 @@ def format_token_rules(
return result
-def get_score_class(score: float, max_score: float, score_precision: int) -> str:
+def get_score_class(score: float, max_score: float) -> str:
"""Return a CSS class to visually represent the score/max_score
score: the score of the submission.
@@ -139,8 +139,6 @@ def get_score_class(score: float, max_score: float, score_precision: int) -> str
return: class name
"""
- score = round(score, score_precision)
- max_score = round(max_score, score_precision)
if score <= 0:
return "score_0"
elif score >= max_score:
diff --git a/cms/server/contest/handlers/tasksubmission.py b/cms/server/contest/handlers/tasksubmission.py
index a5cdedee4b..9a88f41dbd 100644
--- a/cms/server/contest/handlers/tasksubmission.py
+++ b/cms/server/contest/handlers/tasksubmission.py
@@ -143,9 +143,9 @@ def get(self, task_name):
)
public_score, is_public_score_partial = task_score(
- participation, task, public=True, rounded=True)
+ participation, task, public=True)
tokened_score, is_tokened_score_partial = task_score(
- participation, task, only_tokened=True, rounded=True)
+ participation, task, only_tokened=True)
# These two should be the same, anyway.
is_score_partial = is_public_score_partial or is_tokened_score_partial
@@ -221,9 +221,9 @@ def add_task_score(self, participation: Participation, task: Task, data: dict):
.options(joinedload(Submission.results))\
.all()
data["task_public_score"], public_score_is_partial = \
- task_score(participation, task, public=True, rounded=True)
+ task_score(participation, task, public=True)
data["task_tokened_score"], tokened_score_is_partial = \
- task_score(participation, task, only_tokened=True, rounded=True)
+ task_score(participation, task, only_tokened=True)
# These two should be the same, anyway.
data["task_score_is_partial"] = \
public_score_is_partial or tokened_score_is_partial
@@ -267,26 +267,22 @@ def get(self, task_name, opaque_id):
score_type = task.active_dataset.score_type_object
if score_type.max_public_score > 0:
- data["max_public_score"] = \
- round(score_type.max_public_score, task.score_precision)
+ data["max_public_score"] = score_type.max_public_score
if data["status"] == SubmissionResult.SCORED:
- data["public_score"] = \
- round(sr.public_score, task.score_precision)
+ data["public_score"] = sr.public_score
data["public_score_message"] = score_type.format_score(
sr.public_score, score_type.max_public_score,
- sr.public_score_details, task.score_precision,
+ sr.public_score_details,
translation=self.translation)
if score_type.max_public_score < score_type.max_score:
- data["max_score"] = \
- round(score_type.max_score, task.score_precision)
+ data["max_score"] = score_type.max_score
if data["status"] == SubmissionResult.SCORED \
and (submission.token is not None
or self.r_params["actual_phase"] == 3):
- data["score"] = \
- round(sr.score, task.score_precision)
+ data["score"] = sr.score
data["score_message"] = score_type.format_score(
sr.score, score_type.max_score,
- sr.score_details, task.score_precision,
+ sr.score_details,
translation=self.translation)
self.write(data)
diff --git a/cms/server/contest/templates/macro/submission.html b/cms/server/contest/templates/macro/submission.html
index 172cdcb691..944ade423e 100644
--- a/cms/server/contest/templates/macro/submission.html
+++ b/cms/server/contest/templates/macro/submission.html
@@ -169,8 +169,8 @@
{% if score_type is defined and score_type.max_public_score > 0 %}
{% if status == SubmissionResult.SCORED %}
-
- {{ score_type.format_score(sr.public_score, score_type.max_public_score, sr.public_score_details, task.score_precision, translation=translation) }}
+ |
+ {{ score_type.format_score(sr.public_score, score_type.max_public_score, sr.public_score_details, translation=translation) }}
|
{% else %}
@@ -180,8 +180,8 @@
{% endif %}
{% if score_type is defined and score_type.max_public_score < score_type.max_score %}
{% if status == SubmissionResult.SCORED and (s.token is not none or actual_phase == 3) %}
- |
- {{ score_type.format_score(sr.score, score_type.max_score, sr.score_details, task.score_precision, translation=translation) }}
+ |
+ {{ score_type.format_score(sr.score, score_type.max_score, sr.score_details, translation=translation) }}
|
{% else %}
diff --git a/cms/server/contest/templates/task_submissions.html b/cms/server/contest/templates/task_submissions.html
index dddba88f8c..6ffc3d1ba3 100644
--- a/cms/server/contest/templates/task_submissions.html
+++ b/cms/server/contest/templates/task_submissions.html
@@ -193,7 +193,7 @@ {% trans name=task.title, short_name=task.name %}{{ name }} ({{ short_name }
{% if score_type.max_public_score > 0 %}
{# Show the public score (alone, if everything is public or tokens are disabled, or together with the tokened score). #}
+ class="{{ "span6" if two_task_scores else "span12" }} well well-small task_score {{ get_score_class(public_score, score_type.max_public_score) }}">
{% if score_type.max_public_score == score_type.max_score %}
{% trans %}Score:{% endtrans %}
@@ -203,7 +203,7 @@ {% trans name=task.title, short_name=task.name %}{{ name }} ({{ short_name }
- {{ score_type.format_score(public_score, score_type.max_public_score, none, task.score_precision, translation=translation) }}
+ {{ score_type.format_score(public_score, score_type.max_public_score, none, translation=translation) }}
{% if is_score_partial %}
{% endif %}
@@ -214,7 +214,7 @@ {% trans name=task.title, short_name=task.name %}{{ name }} ({{ short_name }
{% if score_type.max_public_score < score_type.max_score %}
{# Show the tokened score (alone if everything is non-public, or together with the public score). #}
+ class="{{ "span6" if two_task_scores else "span12" }} well well-small task_score {{ get_score_class(tokened_score, score_type.max_score) if can_use_tokens else "undefined" }}">
{% if can_use_tokens %}
{% trans %}Score of tokened submissions:{% endtrans %}
@@ -225,7 +225,7 @@ {% trans name=task.title, short_name=task.name %}{{ name }} ({{ short_name }
{% if can_use_tokens %}
- {{ score_type.format_score(tokened_score, score_type.max_score, none, task.score_precision, translation=translation) }}
+ {{ score_type.format_score(tokened_score, score_type.max_score, none, translation=translation) }}
{% if is_score_partial %}
{% endif %}
diff --git a/cms/service/ProxyService.py b/cms/service/ProxyService.py
index 6b8dfa7665..f59ea1db87 100644
--- a/cms/service/ProxyService.py
+++ b/cms/service/ProxyService.py
@@ -405,7 +405,6 @@ def operations_for_score(self, submission: Submission):
# This check is probably useless.
if submission_result is not None and submission_result.scored():
- # We're sending the unrounded score to RWS
subchange_data["score"] = submission_result.score
subchange_data["extra"] = submission_result.ranking_score_details
diff --git a/cmstestsuite/unit_tests/grading/scoretypes/GroupMinTest.py b/cmstestsuite/unit_tests/grading/scoretypes/GroupMinTest.py
index 0104e8bd49..294471c750 100755
--- a/cmstestsuite/unit_tests/grading/scoretypes/GroupMinTest.py
+++ b/cmstestsuite/unit_tests/grading/scoretypes/GroupMinTest.py
@@ -42,47 +42,47 @@ def setUp(self):
def test_paramaters_correct(self):
"""Test that correct parameters do not throw."""
- GroupMin([], self._public_testcases)
- GroupMin([[40, 2], [60.0, 2]], self._public_testcases)
- GroupMin([[40, "1_*"], [60.0, "2_*"]], self._public_testcases)
+ GroupMin([], self._public_testcases, 2)
+ GroupMin([[40, 2], [60.0, 2]], self._public_testcases, 2)
+ GroupMin([[40, "1_*"], [60.0, "2_*"]], self._public_testcases, 2)
def test_paramaters_invalid_types(self):
with self.assertRaises(ValueError):
- GroupMin([1], self._public_testcases)
+ GroupMin([1], self._public_testcases, 2)
with self.assertRaises(ValueError):
- GroupMin(1, self._public_testcases)
+ GroupMin(1, self._public_testcases, 2)
def test_paramaters_invalid_wrong_item_len(self):
with self.assertRaises(ValueError):
- GroupMin([[]], self._public_testcases)
+ GroupMin([[]], self._public_testcases, 2)
with self.assertRaises(ValueError):
- GroupMin([[1]], self._public_testcases)
+ GroupMin([[1]], self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_paramaters_invalid_wrong_item_len_not_caught(self):
with self.assertRaises(ValueError):
- GroupMin([[1, 2, 3]], self._public_testcases)
+ GroupMin([[1, 2, 3]], self._public_testcases, 2)
def test_parameter_invalid_wrong_max_score_type(self):
with self.assertRaises(ValueError):
- GroupMin([["a", 10]], self._public_testcases)
+ GroupMin([["a", 10]], self._public_testcases, 2)
def test_parameter_invalid_wrong_testcases_type(self):
with self.assertRaises(ValueError):
- GroupMin([[100, 1j]], self._public_testcases)
+ GroupMin([[100, 1j]], self._public_testcases, 2)
def test_parameter_invalid_inconsistent_testcases_type(self):
with self.assertRaises(ValueError):
- GroupMin([[40, 10], [40, "1_*"]], self._public_testcases)
+ GroupMin([[40, 10], [40, "1_*"]], self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_paramaters_invalid_testcases_too_many(self):
with self.assertRaises(ValueError):
- GroupMin([[100, 20]], self._public_testcases)
+ GroupMin([[100, 20]], self._public_testcases, 2)
def test_parameter_invalid_testcases_regex_no_match_type(self):
with self.assertRaises(ValueError):
- GroupMin([[100, "9_*"]], self._public_testcases)
+ GroupMin([[100, "9_*"]], self._public_testcases, 2)
def test_max_scores_regexp(self):
"""Test max score is correct when groups are regexp-defined."""
@@ -93,19 +93,19 @@ def test_max_scores_regexp(self):
# Only group 1_* is public.
public_testcases = dict(self._public_testcases)
- self.assertEqual(GroupMin(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMin(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1, header))
# All groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = True
- self.assertEqual(GroupMin(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMin(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1 + s2 + s3, header))
# No groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = False
- self.assertEqual(GroupMin(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMin(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, 0, header))
def test_max_scores_number(self):
@@ -117,25 +117,25 @@ def test_max_scores_number(self):
# Only group 1_* is public.
public_testcases = dict(self._public_testcases)
- self.assertEqual(GroupMin(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMin(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1, header))
# All groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = True
- self.assertEqual(GroupMin(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMin(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1 + s2 + s3, header))
# No groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = False
- self.assertEqual(GroupMin(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMin(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, 0.0, header))
def test_compute_score(self):
s1, s2, s3 = 10.5, 30.5, 59
parameters = [[0, "0_*"], [s1, "1_*"], [s2, "2_*"], [s3, "3_*"]]
- gmin = GroupMin(parameters, self._public_testcases)
+ gmin = GroupMin(parameters, self._public_testcases, 2)
sr = self.get_submission_result(self._public_testcases)
# All correct.
diff --git a/cmstestsuite/unit_tests/grading/scoretypes/GroupMulTest.py b/cmstestsuite/unit_tests/grading/scoretypes/GroupMulTest.py
index dbcb44e8b5..c163792d39 100755
--- a/cmstestsuite/unit_tests/grading/scoretypes/GroupMulTest.py
+++ b/cmstestsuite/unit_tests/grading/scoretypes/GroupMulTest.py
@@ -42,47 +42,47 @@ def setUp(self):
def test_paramaters_correct(self):
"""Test that correct parameters do not throw."""
- GroupMul([], self._public_testcases)
- GroupMul([[40, 2], [60.0, 2]], self._public_testcases)
- GroupMul([[40, "1_*"], [60.0, "2_*"]], self._public_testcases)
+ GroupMul([], self._public_testcases, 2)
+ GroupMul([[40, 2], [60.0, 2]], self._public_testcases, 2)
+ GroupMul([[40, "1_*"], [60.0, "2_*"]], self._public_testcases, 2)
def test_paramaters_invalid_types(self):
with self.assertRaises(ValueError):
- GroupMul([1], self._public_testcases)
+ GroupMul([1], self._public_testcases, 2)
with self.assertRaises(ValueError):
- GroupMul(1, self._public_testcases)
+ GroupMul(1, self._public_testcases, 2)
def test_paramaters_invalid_wrong_item_len(self):
with self.assertRaises(ValueError):
- GroupMul([[]], self._public_testcases)
+ GroupMul([[]], self._public_testcases, 2)
with self.assertRaises(ValueError):
- GroupMul([[1]], self._public_testcases)
+ GroupMul([[1]], self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_paramaters_invalid_wrong_item_len_not_caught(self):
with self.assertRaises(ValueError):
- GroupMul([[1, 2, 3]], self._public_testcases)
+ GroupMul([[1, 2, 3]], self._public_testcases, 2)
def test_parameter_invalid_wrong_max_score_type(self):
with self.assertRaises(ValueError):
- GroupMul([["a", 10]], self._public_testcases)
+ GroupMul([["a", 10]], self._public_testcases, 2)
def test_parameter_invalid_wrong_testcases_type(self):
with self.assertRaises(ValueError):
- GroupMul([[100, 1j]], self._public_testcases)
+ GroupMul([[100, 1j]], self._public_testcases, 2)
def test_parameter_invalid_inconsistent_testcases_type(self):
with self.assertRaises(ValueError):
- GroupMul([[40, 10], [40, "1_*"]], self._public_testcases)
+ GroupMul([[40, 10], [40, "1_*"]], self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_paramaters_invalid_testcases_too_many(self):
with self.assertRaises(ValueError):
- GroupMul([[100, 20]], self._public_testcases)
+ GroupMul([[100, 20]], self._public_testcases, 2)
def test_parameter_invalid_testcases_regex_no_match_type(self):
with self.assertRaises(ValueError):
- GroupMul([[100, "9_*"]], self._public_testcases)
+ GroupMul([[100, "9_*"]], self._public_testcases, 2)
def test_max_scores_regexp(self):
"""Test max score is correct when groups are regexp-defined."""
@@ -93,19 +93,19 @@ def test_max_scores_regexp(self):
# Only group 1_* is public.
public_testcases = dict(self._public_testcases)
- self.assertEqual(GroupMul(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMul(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1, header))
# All groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = True
- self.assertEqual(GroupMul(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMul(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1 + s2 + s3, header))
# No groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = False
- self.assertEqual(GroupMul(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMul(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, 0, header))
def test_max_scores_number(self):
@@ -117,25 +117,25 @@ def test_max_scores_number(self):
# Only group 1_* is public.
public_testcases = dict(self._public_testcases)
- self.assertEqual(GroupMul(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMul(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1, header))
# All groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = True
- self.assertEqual(GroupMul(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMul(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1 + s2 + s3, header))
# No groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = False
- self.assertEqual(GroupMul(parameters, public_testcases).max_scores(),
+ self.assertEqual(GroupMul(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, 0, header))
def test_compute_score(self):
s1, s2, s3 = 10.5, 30.5, 59
parameters = [[0, "0_*"], [s1, "1_*"], [s2, "2_*"], [s3, "3_*"]]
- gmul = GroupMul(parameters, self._public_testcases)
+ gmul = GroupMul(parameters, self._public_testcases, 2)
sr = self.get_submission_result(self._public_testcases)
# All correct.
diff --git a/cmstestsuite/unit_tests/grading/scoretypes/GroupThresholdTest.py b/cmstestsuite/unit_tests/grading/scoretypes/GroupThresholdTest.py
index e6215736e3..8601345225 100755
--- a/cmstestsuite/unit_tests/grading/scoretypes/GroupThresholdTest.py
+++ b/cmstestsuite/unit_tests/grading/scoretypes/GroupThresholdTest.py
@@ -42,55 +42,55 @@ def setUp(self):
def test_paramaters_correct(self):
"""Test that correct parameters do not throw."""
- GroupThreshold([], self._public_testcases)
+ GroupThreshold([], self._public_testcases, 2)
GroupThreshold([[40, 2, 500], [60.0, 2, 1000]],
- self._public_testcases)
+ self._public_testcases, 2)
GroupThreshold([[40, "1_*", 500.5], [60.0, "2_*", 1000]],
- self._public_testcases)
+ self._public_testcases, 2)
def test_paramaters_invalid_types(self):
with self.assertRaises(ValueError):
- GroupThreshold([1], self._public_testcases)
+ GroupThreshold([1], self._public_testcases, 2)
with self.assertRaises(ValueError):
- GroupThreshold(1, self._public_testcases)
+ GroupThreshold(1, self._public_testcases, 2)
def test_paramaters_invalid_wrong_item_len(self):
with self.assertRaises(ValueError):
- GroupThreshold([[]], self._public_testcases)
+ GroupThreshold([[]], self._public_testcases, 2)
with self.assertRaises(ValueError):
- GroupThreshold([[1]], self._public_testcases)
+ GroupThreshold([[1]], self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_paramaters_invalid_wrong_item_len_not_caught(self):
with self.assertRaises(ValueError):
- GroupThreshold([[1, 2]], self._public_testcases)
+ GroupThreshold([[1, 2]], self._public_testcases, 2)
def test_parameter_invalid_wrong_max_score_type(self):
with self.assertRaises(ValueError):
- GroupThreshold([["a", 10, 1000]], self._public_testcases)
+ GroupThreshold([["a", 10, 1000]], self._public_testcases, 2)
def test_parameter_invalid_wrong_testcases_type(self):
with self.assertRaises(ValueError):
- GroupThreshold([[100, 1j, 1000]], self._public_testcases)
+ GroupThreshold([[100, 1j, 1000]], self._public_testcases, 2)
def test_parameter_invalid_inconsistent_testcases_type(self):
with self.assertRaises(ValueError):
GroupThreshold([[40, 10, 500], [40, "1_*", 1000]],
- self._public_testcases)
+ self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_paramaters_invalid_testcases_too_many(self):
with self.assertRaises(ValueError):
- GroupThreshold([[100, 20, 1000]], self._public_testcases)
+ GroupThreshold([[100, 20, 1000]], self._public_testcases, 2)
def test_parameter_invalid_testcases_regex_no_match_type(self):
with self.assertRaises(ValueError):
- GroupThreshold([[100, "9_*", 1000]], self._public_testcases)
+ GroupThreshold([[100, "9_*", 1000]], self._public_testcases, 2)
@unittest.skip("Not yet detected.")
def test_parameter_invalid_wrong_threshold_type_not_caught(self):
with self.assertRaises(ValueError):
- GroupThreshold([[100, 1, 1000j]], self._public_testcases)
+ GroupThreshold([[100, 1, 1000j]], self._public_testcases, 2)
def test_max_scores_regexp(self):
"""Test max score is correct when groups are regexp-defined."""
@@ -102,21 +102,21 @@ def test_max_scores_regexp(self):
# Only group 1_* is public.
public_testcases = dict(self._public_testcases)
self.assertEqual(
- GroupThreshold(parameters, public_testcases).max_scores(),
+ GroupThreshold(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1, header))
# All groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = True
self.assertEqual(
- GroupThreshold(parameters, public_testcases).max_scores(),
+ GroupThreshold(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1 + s2 + s3, header))
# No groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = False
self.assertEqual(
- GroupThreshold(parameters, public_testcases).max_scores(),
+ GroupThreshold(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, 0, header))
def test_max_scores_number(self):
@@ -129,28 +129,28 @@ def test_max_scores_number(self):
# Only group 1_* is public.
public_testcases = dict(self._public_testcases)
self.assertEqual(
- GroupThreshold(parameters, public_testcases).max_scores(),
+ GroupThreshold(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1, header))
# All groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = True
self.assertEqual(
- GroupThreshold(parameters, public_testcases).max_scores(),
+ GroupThreshold(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, s1 + s2 + s3, header))
# No groups are public
for testcase in public_testcases.keys():
public_testcases[testcase] = False
self.assertEqual(
- GroupThreshold(parameters, public_testcases).max_scores(),
+ GroupThreshold(parameters, public_testcases, 2).max_scores(),
(s1 + s2 + s3, 0, header))
def test_compute_score(self):
s1, s2, s3 = 10.5, 30.5, 59
parameters = [[0, "0_*", 0],
[s1, "1_*", 10], [s2, "2_*", 20], [s3, "3_*", 30]]
- st = GroupThreshold(parameters, self._public_testcases)
+ st = GroupThreshold(parameters, self._public_testcases, 2)
sr = self.get_submission_result(self._public_testcases)
# All correct (below threshold).
diff --git a/cmstestsuite/unit_tests/grading/scoretypes/SumTest.py b/cmstestsuite/unit_tests/grading/scoretypes/SumTest.py
index b952e1b04b..1a243026cf 100755
--- a/cmstestsuite/unit_tests/grading/scoretypes/SumTest.py
+++ b/cmstestsuite/unit_tests/grading/scoretypes/SumTest.py
@@ -39,24 +39,24 @@ def setUp(self):
def test_paramaters_correct(self):
"""Test that correct parameters do not throw."""
- Sum(100, self._public_testcases)
- Sum(1.5, self._public_testcases)
+ Sum(100, self._public_testcases, 2)
+ Sum(1.5, self._public_testcases, 2)
def test_paramaters_invalid(self):
with self.assertRaises(ValueError):
- Sum([], self._public_testcases)
+ Sum([], self._public_testcases, 2)
with self.assertRaises(ValueError):
- Sum("1", self._public_testcases)
+ Sum("1", self._public_testcases, 2)
def test_max_scores(self):
testcase_score = 10.5
self.assertEqual(Sum(testcase_score,
- self._public_testcases).max_scores(),
+ self._public_testcases, 2).max_scores(),
(testcase_score * 4, testcase_score, []))
def test_compute_score(self):
testcase_score = 10.5
- st = Sum(testcase_score, self._public_testcases)
+ st = Sum(testcase_score, self._public_testcases, 2)
sr = self.get_submission_result(self._public_testcases)
# All correct.
diff --git a/cmstestsuite/unit_tests/grading/scoring_test.py b/cmstestsuite/unit_tests/grading/scoring_test.py
index c7b95969f3..cca9d8e574 100755
--- a/cmstestsuite/unit_tests/grading/scoring_test.py
+++ b/cmstestsuite/unit_tests/grading/scoring_test.py
@@ -46,10 +46,9 @@ def setUp(self):
def at(self, timestamp):
return self.timestamp + timedelta(seconds=timestamp)
- def call(self, public=False, only_tokened=False, rounded=False):
+ def call(self, public=False, only_tokened=False):
return task_score(self.participation, self.task,
- public=public, only_tokened=only_tokened,
- rounded=rounded)
+ public=public, only_tokened=only_tokened)
def add_result(self, timestamp, score, tokened=False, score_details=None,
public_score=None, public_score_details=None):
@@ -245,21 +244,6 @@ def test_partial(self):
self.session.flush()
self.assertEqual(self.call(), (30 * 0.2 + 40 * 0.5 + 30 * 0.2, True))
- def test_rounding(self):
- # No rounding should happen at the subtask or task level.
- self.add_result(self.at(1), 80 + 0.000_2,
- score_details=[
- self.subtask(1, 80, 1.0),
- self.subtask(2, 20, 0.000_01),
- ])
- self.add_result(self.at(2), 0.000_4,
- score_details=[
- self.subtask(1, 80, 0.0),
- self.subtask(2, 20, 0.000_02),
- ])
- self.session.flush()
- self.assertEqual(self.call(), (80 + 0.000_4, False))
-
def test_public(self):
self.add_result(self.at(1),
30 * 1.0 + 40 * 1.0 + 30 * 1.0,
@@ -369,17 +353,11 @@ def test_only_tokened(self):
self.session.flush()
self.assertEqual(self.call(only_tokened=True), (44.4, False))
- def test_unrounded(self):
- self.add_result(self.at(1), 44.44444, tokened=False)
- self.add_result(self.at(2), 44.44443, tokened=False)
- self.session.flush()
- self.assertEqual(self.call(), (44.44444, False))
-
def test_rounded(self):
self.add_result(self.at(1), 44.44444, tokened=False)
self.add_result(self.at(2), 44.44443, tokened=False)
self.session.flush()
- self.assertEqual(self.call(rounded=True), (44.44, False))
+ self.assertEqual(self.call(), (44.44, False))
if __name__ == "__main__":
|