Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions scripts/notebook_tools/check_split_reading_cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@
est un **compte par sortie**, pas un jugement par
cellule : voir la decision #17044 ci-dessous ;
- ``READING_BEFORE_CODE`` : cellule markdown ajoutee directement devant une
cellule de code AVEC sortie (la lecture doit
suivre la sortie, pas la preceder) ;
cellule de code AVEC sortie ET sans code execute
au-dessus d'elle (la lecture doit suivre la
sortie, pas la preceder ; sous un code execute,
le compte par sortie prend le relais -- #17044,
decision c.5877090210) ;
- ``EXERCISE_READING`` : cellule markdown ajoutee juste apres une cellule
d'exercice (stub sans sortie) -- l'etudiant ne
verra pas la lecture tant qu'il n'a pas complete.
Expand Down Expand Up @@ -620,7 +623,8 @@ def detect_added_readings(head_nb: dict, base_nb: dict | None) -> list[dict]:
4. Pour chaque cellule ajoutee qui est markdown, classifier via le
**contexte HEAD** :
- ``EXERCISE_READING`` prev_role == "exercise"
- ``READING_BEFORE_CODE`` next_role == "code_with_output"
- ``READING_BEFORE_CODE`` next_role == "code_with_output" ET
prev_role != "code_with_output"
- ``SECOND_READING`` la sortie que la cellule commente porte
**plus de lectures en tete qu'en base**

Expand Down Expand Up @@ -803,9 +807,16 @@ def _bucket_for(prev_role: str, next_role: str) -> str | None:
if prev_role == "exercise":
return "EXERCISE_READING_CANDIDATE"
if next_role in ("code_with_output", "exercise"):
# Une lecture ajoutee devant un exercice OU un code deja execute
# precede le resultat qu'elle est censee commenter -- dans les deux
# cas la place canonique est APRES, pas avant.
# Une lecture ajoutee sous un code execute est rattachee par
# ``_output_key_above`` a la sortie du dessus : elle releve du compte
# par sortie (SECOND_READING si le compte monte, rien sinon) -- la
# dire en meme temps « avant son resultat » serait l'incoherence
# mesuree sur #17044 (c.5877090210). READING_BEFORE_CODE ne survit
# que sans code execute directement au-dessus (prev_role md ou
# BOUNDARY) : la lecture y precede alors le resultat qu'elle est
# censee commenter, et la place canonique est APRES, pas avant.
if prev_role == "code_with_output":
return "SECOND_READING"
return "READING_BEFORE_CODE"
if prev_role in ("md", "code_with_output"):
return "SECOND_READING"
Expand Down
61 changes: 61 additions & 0 deletions scripts/tests/test_check_split_reading_cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,67 @@ def test_diff_reading_before_code_devant_sortie():
assert f["next_role"] == "code_with_output"


def test_diff_lecture_sous_code_devant_code_sans_exces_non_flaggee():
"""Decision #17044 (c.5877090210) : une lecture ajoutee directement SOUS un
code execute est rattachee par ``_output_key_above`` a la sortie du dessus
-- elle releve du compte par sortie, pas de la topologie. Devant le code
SUIVANT mais sans exces de lecture sur la sortie du dessus : rien a
signaler. Classe mesuree : cellule 8 d'Infer-08b (#18087), faux positif.
"""
base = nb(
code("print(1)"),
code("print(2)"),
)
head = nb(
code("print(1)"),
md("### Analyse du resultat\nLa convergence est nette."),
code("print(2)"),
)
assert detect_added_readings(head, base) == []


def test_diff_lecture_sous_code_avec_exces_rest_second_reading():
"""Meme topologie (prev = code execute, next = code), mais la sortie du
dessus portait deja une lecture : l'ajout fait monter le compte ->
SECOND_READING par le compte par sortie. Le bucket topologique ne dit plus
READING_BEFORE_CODE pour une cellule qu'il rattache par ailleurs a la
sortie du dessus (incoherence mesuree sur #17044).
"""
base = nb(
code("print(1)"),
md("### Lecture\nPremiere lecture legitime."),
code("print(2)"),
)
head = nb(
code("print(1)"),
md("### Lecture\nPremiere lecture legitime."),
md("### Lecture chiffree\nDeuxieme lecture sur la meme sortie."),
code("print(2)"),
)
findings = detect_added_readings(head, base)
assert [f["type"] for f in findings] == ["SECOND_READING"]


def test_diff_lecture_sous_md_devant_code_rest_reading_before_code():
"""Controle negatif de la decision : sans code execute directement
au-dessus (prev_role md), la lecture ajoutee devant un code execute RESTE
READING_BEFORE_CODE -- la place canonique d'une lecture introductive
n'a pas change.
"""
base = nb(
md("## 1. Contexte du banc"),
code("print(1)"),
)
head = nb(
md("## 1. Contexte du banc"),
md("### Lecture introductive\nOn annonce le resultat avant le code."),
code("print(1)"),
)
findings = detect_added_readings(head, base)
assert len(findings) == 1
assert findings[0]["type"] == "READING_BEFORE_CODE"


def test_diff_section_header_devant_code_non_flagge():
"""Carve-out #17777 etendu a READING_BEFORE_CODE : un en-tete de section
(titre d'organisation, meme suivi de prose) qui introduit le code qui
Expand Down
Loading