Skip to content

Commit 6efd0ac

Browse files
rootroot
authored andcommitted
fix: SOL review - restore content.py, fix test split, guard code-question lookup, fraction threshold
1 parent 3648f6f commit 6efd0ac

3 files changed

Lines changed: 49 additions & 39 deletions

File tree

‎app/content.py‎

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,20 @@ def lesson(
285285
),
286286
text(
287287
"if-result",
288-
"Что выведет этот код?\n\nif 3 > 5:\n print('да')\nelse:\n print('нет')",
288+
"Что выведет `if 3 > 5: print('да') else: print('нет')`?",
289289
["нет"],
290290
"3 не больше 5, поэтому выполняется ветка else.",
291291
),
292292
code(
293293
"if-code",
294-
"Дано `temperature = 22`. Если температура не меньше 25, выведи «Надень шорты», иначе — «Возьми куртку».",
295-
"temperature = 22\n# напиши условие и выведи подходящую одежду\n",
296-
[{"kind": "stdout", "expected": "Возьми куртку"}],
297-
"22 меньше 25, поэтому выполняется ветка else и выводится «Возьми куртку».",
298-
"Сравни temperature с 25 через >=. В if выведи «Надень шорты», в else — «Возьми куртку».",
294+
"Напиши `is_adult(age)`, возвращающую True при возрасте 18 и больше.",
295+
"def is_adult(age):\n # твой код\n pass\n",
296+
[
297+
{"kind": "call", "call": "is_adult(18)", "expected": True},
298+
{"kind": "call", "call": "is_adult(17)", "expected": False},
299+
],
300+
"Условие внутри функции помогает вернуть нужный логический результат.",
301+
"Сравни age с 18 и верни результат сравнения либо используй if/else.",
299302
),
300303
],
301304
),
@@ -335,11 +338,14 @@ def lesson(
335338
text("for-sum", "Чему равна сумма чисел в `range(1, 4)`?", ["6"], "Это 1 + 2 + 3 = 6."),
336339
code(
337340
"for-code",
338-
"Выведи числа от 1 до 5, каждое с новой строки.",
339-
"for number in range(1, 6):\n # выведи number\n",
340-
[{"kind": "stdout", "expected": "1\n2\n3\n4\n5"}],
341-
"range(1, 6) даёт числа от 1 до 5: верхняя граница не включается.",
342-
"В теле цикла вызови print(number).",
341+
"Напиши `sum_to(number)`, возвращающую сумму от 1 до number включительно.",
342+
"def sum_to(number):\n # твой код\n pass\n",
343+
[
344+
{"kind": "call", "call": "sum_to(1)", "expected": 1},
345+
{"kind": "call", "call": "sum_to(5)", "expected": 15},
346+
],
347+
"Цикл избавляет от ручного сложения каждого числа.",
348+
"Создай total = 0 и пройди range(1, number + 1).",
343349
),
344350
],
345351
),
@@ -385,11 +391,14 @@ def lesson(
385391
),
386392
code(
387393
"while-code",
388-
"Дано `start = 5`. Выведи обратный отсчёт до 1, каждое число с новой строки, затем выведи «Пуск!».",
389-
"start = 5\nwhile start > 0:\n # выведи start и уменьши его\n# выведи «Пуск!»\n",
390-
[{"kind": "stdout", "expected": "5\n4\n3\n2\n1\nПуск!"}],
391-
"while работает, пока start больше нуля: после каждого вывода уменьши start на 1, а затем выведи «Пуск!».",
392-
"В цикле напиши print(start) и start -= 1. После цикла — print('Пуск!').",
394+
"Напиши `countdown(start)`, возвращающую список от start до 1 через while.",
395+
"def countdown(start):\n # твой код\n pass\n",
396+
[
397+
{"kind": "call", "call": "countdown(1)", "expected": [1]},
398+
{"kind": "call", "call": "countdown(4)", "expected": [4, 3, 2, 1]},
399+
],
400+
"while хорош, когда счётчик меняется до достижения границы.",
401+
"Начни с result = [] и уменьшай start после добавления в список.",
393402
),
394403
],
395404
),

‎app/main.py‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,14 @@ def submit_lesson(lesson_id: str, submission: Submission) -> dict:
192192
question_ids = {question["id"] for question in lesson["questions"]}
193193
results, correct_count = grade_answers(submission.answers, question_ids)
194194
total = len(question_ids)
195-
code_question_id = next(
195+
code_question_ids = [
196196
question["id"] for question in lesson["questions"] if question["kind"] == "code"
197+
]
198+
code_correct = bool(code_question_ids) and all(
199+
any(r["question_id"] == question_id and r["correct"] for r in results)
200+
for question_id in code_question_ids
197201
)
198-
code_correct = next(
199-
item["correct"] for item in results if item["question_id"] == code_question_id
200-
)
201-
passed = code_correct and correct_count >= 2
202+
passed = (not code_question_ids or code_correct) and correct_count * 3 >= total * 2
202203
gained = 0
203204
if passed:
204205
gained, _ = save_lesson(lesson_id, correct_count, total, lesson["xp"])
@@ -213,7 +214,7 @@ def submit_lesson(lesson_id: str, submission: Submission) -> dict:
213214
if passed
214215
else (
215216
"Для зачёта нужно решить задачу на код"
216-
if correct_count >= 2 and not code_correct
217+
if correct_count * 3 >= total * 2 and not code_correct
217218
else "Нужно минимум 2 верных ответа из 3. Попробуй ещё раз — это нормально."
218219
),
219220
}

‎tests/test_api.py‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,23 @@ def test_lesson_unlocking_and_progression() -> None:
4040
def test_extended_course_unlocks_after_foundation() -> None:
4141
with TestClient(app) as client:
4242
client.post("/api/reset")
43+
for lesson in LESSONS[:12]:
44+
save_lesson(lesson["id"], 3, 3, lesson["xp"])
45+
46+
response = client.get("/api/lessons/operators-arithmetic")
47+
assert response.status_code == 200
48+
assert response.json()["order"] == 13
49+
50+
code_check = client.post(
51+
"/api/code/check",
52+
json={
53+
"question_id": "operators-arithmetic-code",
54+
"answer": "def increment(value):\n return value + 1\n",
55+
},
56+
)
57+
assert code_check.status_code == 200
58+
assert code_check.json()["correct"] is True
59+
client.post("/api/reset")
4360

4461

4562
def test_lesson_requires_correct_code_for_completion() -> None:
@@ -71,20 +88,3 @@ def test_lesson_requires_correct_code_for_completion() -> None:
7188
response = client.post("/api/lessons/hello/submit", json={"answers": code_only})
7289
assert response.json()["passed"] is False
7390
client.post("/api/reset")
74-
for lesson in LESSONS[:12]:
75-
save_lesson(lesson["id"], 3, 3, lesson["xp"])
76-
77-
response = client.get("/api/lessons/operators-arithmetic")
78-
assert response.status_code == 200
79-
assert response.json()["order"] == 13
80-
81-
code_check = client.post(
82-
"/api/code/check",
83-
json={
84-
"question_id": "operators-arithmetic-code",
85-
"answer": "def increment(value):\n return value + 1\n",
86-
},
87-
)
88-
assert code_check.status_code == 200
89-
assert code_check.json()["correct"] is True
90-
client.post("/api/reset")

0 commit comments

Comments
 (0)