From 536ab9387420f7f1e60afa55113b0c04363e3fb3 Mon Sep 17 00:00:00 2001 From: "Peter B. Johnson" Date: Fri, 30 Oct 2026 10:22:04 +0000 Subject: [PATCH] Write a Boolean answer as 1 or 0, compared as a string Lambda Feedback's own teacher test of a Boolean area sends isExactEqual answer 1, submission 1 and gradeParams {type: "str"}. in2lambda wrote the answer as true and no gradeParams, so a correct response of 1 never matched. The Python API keeps bool; the JSON now holds 1 or 0, for the answer and test payloads, with type "str" unless the author sets it. Co-Authored-By: Claude Opus 5.5 --- in2lambda/api/response_area.py | 12 ++++++++++++ in2lambda/json_convert/json_convert.py | 4 ++-- tests/test_boolean.py | 10 ++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/test_boolean.py diff --git a/in2lambda/api/response_area.py b/in2lambda/api/response_area.py index 430dcac..feda205 100644 --- a/in2lambda/api/response_area.py +++ b/in2lambda/api/response_area.py @@ -120,6 +120,10 @@ def _grade_params(self) -> Optional[dict[str, Any]]: """The parameters sent to the evaluation function.""" return self.grade_params + def _serial(self, value: Any) -> Any: + """An answer or test payload as Lambda Feedback stores it.""" + return value + @dataclass(kw_only=True) class _Maths(ResponseArea): @@ -185,6 +189,14 @@ class Boolean(ResponseArea): response_type: ClassVar[str] = "BOOLEAN" answer: bool = False + # Lambda Feedback stores the answer, and sends the response, as 1 or 0, and + # isExactEqual compares them as strings. + def _serial(self, value: Any) -> Any: + return int(value) if isinstance(value, bool) else value + + def _grade_params(self) -> Optional[dict[str, Any]]: + return {"type": "str", **(self.grade_params or {})} + @dataclass(kw_only=True) class MultipleChoice(ResponseArea): diff --git a/in2lambda/json_convert/json_convert.py b/in2lambda/json_convert/json_convert.py index 270ef38..186ee28 100644 --- a/in2lambda/json_convert/json_convert.py +++ b/in2lambda/json_convert/json_convert.py @@ -71,7 +71,7 @@ def _response_area_to_json(area: ResponseArea, order: int) -> dict[str, Any]: "tests": [ { "id": test.id, - "payload": test.payload, + "payload": area._serial(test.payload), "expectedResponse": {"isCorrect": test.is_correct}, } for test in area.tests @@ -80,7 +80,7 @@ def _response_area_to_json(area: ResponseArea, order: int) -> dict[str, Any]: "response": { "responseInput": { "responseType": area.response_type, - "answer": area.answer, + "answer": area._serial(area.answer), "config": area._config(), } }, diff --git a/tests/test_boolean.py b/tests/test_boolean.py new file mode 100644 index 0000000..51a8560 --- /dev/null +++ b/tests/test_boolean.py @@ -0,0 +1,10 @@ +"""A Boolean area is written as Lambda Feedback's own teacher test sends it.""" + +from in2lambda.api.response_area import Boolean +from in2lambda.json_convert.json_convert import _response_area_to_json + + +def test_a_boolean_answer_is_written_as_a_number_compared_as_a_string() -> None: + area = _response_area_to_json(Boolean(answer=True), 0) + assert area["response"]["responseInput"]["answer"] == 1 + assert area["gradeParams"] == {"type": "str"}