Skip to content

Commit dec6396

Browse files
committed
barebones version complete
1 parent 3d69573 commit dec6396

5 files changed

Lines changed: 157 additions & 48 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77

88
# Remove python caching
99
__pycache__
10+
11+
# Custom local build and test scripts
12+
test.bat

app/algorithm.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,27 @@ def grading_function(body: dict) -> dict:
1919
to output the grading response.
2020
"""
2121

22-
return {"is_correct": True, "received_body": body}
22+
type_dict = {"float": float, "int": int, "str": str, "dict": dict}
23+
req_type = body["params"]["type"]
24+
25+
# Try cast each of the inputs to their requested type:
26+
errors = []
27+
try:
28+
res = type_dict[req_type](body["response"])
29+
except ValueError as e:
30+
errors += [
31+
{"description": f"Could not cast `response` parameter to {req_type}"}
32+
]
33+
34+
try:
35+
ans = type_dict[req_type](body["answer"])
36+
except ValueError as e:
37+
errors += [{"description": f"Could not cast `answer` parameter to {req_type}"}]
38+
39+
if errors:
40+
return {"error": errors}
41+
42+
# Are they equaL?
43+
is_exact_equal = res == ans
44+
45+
return {"is_correct": is_exact_equal}

app/schema.json

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
{
2-
"$schema": "http://json-schema.org/draft/2019-09/schema#",
3-
"title": "Generic schema for the data passed to a grading cloud function.",
4-
"type": "object",
5-
"properties": {
6-
"example": {"const": "property"}
7-
},
8-
"required": ["example"],
9-
"additionalProperties": false
10-
}
2+
"$schema": "http://json-schema.org/draft/2019-09/schema#",
3+
"title": "Generic schema for the data passed to a grading cloud function.",
4+
"type": "object",
5+
"properties": {
6+
"answer": {},
7+
"response": {},
8+
"params": {
9+
"type": "object",
10+
"properties": {
11+
"type": { "enum": ["int", "float", "str", "dict"] }
12+
},
13+
"required": ["type"]
14+
}
15+
},
16+
"required": ["answer", "response", "params"],
17+
"additionalProperties": true
18+
}

app/tests/grading.py

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,91 @@
22

33
from ..algorithm import grading_function
44

5+
56
class TestGradingFunction(unittest.TestCase):
67
"""
7-
TestCase Class used to test the algorithm.
8-
---
9-
Tests are used here to check that the algorithm written
10-
is working as it should.
11-
12-
It's best practise to write these tests first to get a
13-
kind of 'specification' for how your algorithm should
14-
work, and you should run these tests before committing
15-
your code to AWS.
16-
17-
Read the docs on how to use unittest here:
18-
https://docs.python.org/3/library/unittest.html
19-
20-
Use grading_function() to check your algorithm works
21-
as it should.
8+
TestCase Class used to test the algorithm.
9+
---
10+
Tests are used here to check that the algorithm written
11+
is working as it should.
12+
13+
It's best practise to write these tests first to get a
14+
kind of 'specification' for how your algorithm should
15+
work, and you should run these tests before committing
16+
your code to AWS.
17+
18+
Read the docs on how to use unittest here:
19+
https://docs.python.org/3/library/unittest.html
20+
21+
Use grading_function() to check your algorithm works
22+
as it should.
2223
"""
23-
def test_returns_is_correct_true(self):
24-
body = {}
24+
25+
def test_evaluate_as_int(self):
26+
body = {"answer": "45", "response": "45", "params": {"type": "int"}}
2527

2628
response = grading_function(body)
2729

2830
self.assertEqual(response.get("is_correct"), True)
31+
self.assertEqual(response.get("error", False), False)
32+
33+
def test_invalid_int(self):
34+
body = {"answer": "0", "response": "1.0", "params": {"type": "int"}}
35+
36+
response = grading_function(body)
37+
38+
self.assertIsNotNone(response.get("error", None))
39+
40+
def test_evaluate_as_float(self):
41+
body = {"answer": "4.80", "response": "4.8", "params": {"type": "float"}}
42+
43+
response = grading_function(body)
44+
45+
self.assertEqual(response.get("is_correct"), True)
46+
self.assertEqual(response.get("error", False), False)
47+
48+
def test_invalid_float(self):
49+
body = {"answer": "abc", "response": "1", "params": {"type": "int"}}
50+
51+
response = grading_function(body)
52+
53+
self.assertIsNotNone(response.get("error", None))
54+
55+
def test_evaluate_as_string(self):
56+
body = {
57+
"answer": "dogs",
58+
"response": "dogs",
59+
"params": {"type": "str"},
60+
}
61+
62+
response = grading_function(body)
63+
64+
self.assertEqual(response.get("is_correct"), True)
65+
self.assertEqual(response.get("error", False), False)
66+
67+
def test_evaluate_as_string_incorrect(self):
68+
body = {
69+
"answer": "1.0",
70+
"response": "1",
71+
"params": {"type": "str"},
72+
}
73+
74+
response = grading_function(body)
75+
76+
self.assertEqual(response.get("is_correct"), False)
77+
78+
def test_evaluate_as_dict(self):
79+
body = {
80+
"answer": {"a": 1, "b": 2},
81+
"response": {"b": 2, "a": 1},
82+
"params": {"type": "dict"},
83+
}
84+
85+
response = grading_function(body)
86+
87+
self.assertEqual(response.get("is_correct"), True)
88+
self.assertEqual(response.get("error", False), False)
89+
2990

3091
if __name__ == "__main__":
31-
unittest.main()
92+
unittest.main()

app/tests/validation.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,61 @@
22

33
from ..tools.validate import validate_request
44

5+
56
class TestSchemaValidation(unittest.TestCase):
67
"""
7-
TestCase Class used to test the schema.
8-
---
9-
Tests are used here to check that the schema is able to
10-
validate and reject request bodies that would otherwise
11-
cause the program to crash.
12-
13-
It's best practise to write these tests first to get a
14-
kind of 'specification' for what your schema should
15-
accept or reject, and you should run these tests before
16-
committing your code to git.
17-
18-
Read the docs on how to use unittest here:
19-
https://docs.python.org/3/library/unittest.html
20-
21-
Use validate_request() to check your schema works as
22-
it should.
8+
TestCase Class used to test the schema.
9+
---
10+
Tests are used here to check that the schema is able to
11+
validate and reject request bodies that would otherwise
12+
cause the program to crash.
13+
14+
It's best practise to write these tests first to get a
15+
kind of 'specification' for what your schema should
16+
accept or reject, and you should run these tests before
17+
committing your code to git.
18+
19+
Read the docs on how to use unittest here:
20+
https://docs.python.org/3/library/unittest.html
21+
22+
Use validate_request() to check your schema works as
23+
it should.
2324
"""
25+
2426
def test_empty_request_body(self):
2527
body = {}
2628

2729
validation_error = validate_request(body)
2830

2931
self.assertNotEqual(validation_error, None)
30-
self.assertEqual(validation_error.get("message"), "Schema threw an error when validating the request body.")
32+
self.assertEqual(
33+
validation_error.get("message"),
34+
"Schema threw an error when validating the request body.",
35+
)
3136

3237
def test_invalid_grading_data(self):
3338
body = {"hello": "world"}
3439

3540
validation_error = validate_request(body)
3641

3742
self.assertNotEqual(validation_error, None)
38-
self.assertEqual(validation_error.get("message"), "Schema threw an error when validating the request body.")
43+
self.assertEqual(
44+
validation_error.get("message"),
45+
"Schema threw an error when validating the request body.",
46+
)
3947

4048
def test_valid_grading_data(self):
41-
body = {"example": "property"}
49+
# This body will throw an error when grading, but is valid according to the schema
50+
body = {
51+
"answer": "1.0",
52+
"response": "1",
53+
"params": {"type": "int"},
54+
}
4255

4356
validation_error = validate_request(body)
4457

4558
self.assertEqual(validation_error, None)
4659

60+
4761
if __name__ == "__main__":
48-
unittest.main()
62+
unittest.main()

0 commit comments

Comments
 (0)