[{"data":1,"prerenderedAt":3635},["ShallowReactive",2],{"navigation":3,"\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions.memo":140,"\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions.memo__counterpart":657,"\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions.memo__slides":646,"annexes-memo:\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions":3309,"annexes-slides:\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions":646},[4,24,112],{"title":5,"path":6,"stem":7,"children":8},"SNT · Seconde","\u002Fsnt-2nde","0.snt-2nde\u002F0.index",[9,10],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13,"children":14},"Photographie numérique","\u002Fsnt-2nde\u002Fsg-photo-numerique","0.snt-2nde\u002Fsg-photo-numerique\u002F0.index",[15,16,20],{"title":11,"path":12,"stem":13},{"title":17,"path":18,"stem":19},"Photosites, pixels et résolution","\u002Fsnt-2nde\u002Fsg-photo-numerique\u002Fpixels-resolution","0.snt-2nde\u002Fsg-photo-numerique\u002F1.pixels-resolution",{"title":21,"path":22,"stem":23},"Traiter une image en Python","\u002Fsnt-2nde\u002Fsg-photo-numerique\u002Ftraitement-rgb","0.snt-2nde\u002Fsg-photo-numerique\u002F4.traitement-rgb",{"title":25,"path":26,"stem":27,"children":28},"NSI · Première","\u002Fnsi-1ere","1.nsi-1ere\u002F0.index",[29,30,52,82],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":34},"Représentation des données : types construits","\u002Fnsi-1ere\u002Fpc-types-construits","1.nsi-1ere\u002Fpc-types-construits\u002F0.index",[35,36,40,44,48],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39},"Tableaux et listes","\u002Fnsi-1ere\u002Fpc-types-construits\u002Ftableaux-listes","1.nsi-1ere\u002Fpc-types-construits\u002F1.tableaux-listes",{"title":41,"path":42,"stem":43},"Listes en compréhension","\u002Fnsi-1ere\u002Fpc-types-construits\u002Fcomprehension","1.nsi-1ere\u002Fpc-types-construits\u002F2.comprehension",{"title":45,"path":46,"stem":47},"Tuples et p-uplets nommés","\u002Fnsi-1ere\u002Fpc-types-construits\u002Ftuples","1.nsi-1ere\u002Fpc-types-construits\u002F3.tuples",{"title":49,"path":50,"stem":51},"Dictionnaires","\u002Fnsi-1ere\u002Fpc-types-construits\u002Fdictionnaires","1.nsi-1ere\u002Fpc-types-construits\u002F4.dictionnaires",{"title":53,"path":54,"stem":55,"children":56},"Langages et programmation","\u002Fnsi-1ere\u002Fpg-langages-prog","1.nsi-1ere\u002Fpg-langages-prog\u002F0.index",[57,58,62,66,70,74,78],{"title":53,"path":54,"stem":55},{"title":59,"path":60,"stem":61},"Langages : diversité et unité","\u002Fnsi-1ere\u002Fpg-langages-prog\u002Fdiversite-langages","1.nsi-1ere\u002Fpg-langages-prog\u002F1.diversite-langages",{"title":63,"path":64,"stem":65},"Constructions élémentaires","\u002Fnsi-1ere\u002Fpg-langages-prog\u002Fconstructions-elementaires","1.nsi-1ere\u002Fpg-langages-prog\u002F2.constructions-elementaires",{"title":67,"path":68,"stem":69},"Fonctions","\u002Fnsi-1ere\u002Fpg-langages-prog\u002Ffonctions","1.nsi-1ere\u002Fpg-langages-prog\u002F3.fonctions",{"title":71,"path":72,"stem":73},"Spécification d'une fonction","\u002Fnsi-1ere\u002Fpg-langages-prog\u002Fspecification","1.nsi-1ere\u002Fpg-langages-prog\u002F4.specification",{"title":75,"path":76,"stem":77},"Mise au point des programmes","\u002Fnsi-1ere\u002Fpg-langages-prog\u002Fmise-au-point","1.nsi-1ere\u002Fpg-langages-prog\u002F5.mise-au-point",{"title":79,"path":80,"stem":81},"Utilisation de bibliothèques","\u002Fnsi-1ere\u002Fpg-langages-prog\u002Fbibliotheques","1.nsi-1ere\u002Fpg-langages-prog\u002F6.bibliotheques",{"title":83,"path":84,"stem":85,"children":86},"Algorithmique","\u002Fnsi-1ere\u002Fph-algorithmique","1.nsi-1ere\u002Fph-algorithmique\u002F0.index",[87,88,92,96,100,104,108],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},"Parcours séquentiel d'un tableau","\u002Fnsi-1ere\u002Fph-algorithmique\u002Fparcours-sequentiel","1.nsi-1ere\u002Fph-algorithmique\u002F1.parcours-sequentiel",{"title":93,"path":94,"stem":95},"Bases de la complexité","\u002Fnsi-1ere\u002Fph-algorithmique\u002Fcomplexite-bases","1.nsi-1ere\u002Fph-algorithmique\u002F2.complexite-bases",{"title":97,"path":98,"stem":99},"Tris par sélection et par insertion","\u002Fnsi-1ere\u002Fph-algorithmique\u002Ftris","1.nsi-1ere\u002Fph-algorithmique\u002F3.tris",{"title":101,"path":102,"stem":103},"Recherche dichotomique","\u002Fnsi-1ere\u002Fph-algorithmique\u002Fdichotomie","1.nsi-1ere\u002Fph-algorithmique\u002F4.dichotomie",{"title":105,"path":106,"stem":107},"Algorithmes gloutons","\u002Fnsi-1ere\u002Fph-algorithmique\u002Fgloutons","1.nsi-1ere\u002Fph-algorithmique\u002F5.gloutons",{"title":109,"path":110,"stem":111},"Les k plus proches voisins (k-NN)","\u002Fnsi-1ere\u002Fph-algorithmique\u002Fknn","1.nsi-1ere\u002Fph-algorithmique\u002F6.knn",{"title":113,"path":114,"stem":115,"children":116},"NSI · Terminale","\u002Fnsi-tale","2.nsi-tale\u002F0.index",[117,118],{"title":113,"path":114,"stem":115},{"title":119,"path":120,"stem":121,"children":122},"Structures de données","\u002Fnsi-tale\u002Fta-structures-donnees","2.nsi-tale\u002Fta-structures-donnees\u002F0.index",[123,124,128,132,136],{"title":119,"path":120,"stem":121},{"title":125,"path":126,"stem":127},"Objet, classe, interface","\u002Fnsi-tale\u002Fta-structures-donnees\u002Finterface-implementation","2.nsi-tale\u002Fta-structures-donnees\u002F1.interface-implementation",{"title":129,"path":130,"stem":131},"Implémenter une file FIFO","\u002Fnsi-tale\u002Fta-structures-donnees\u002Fimplementer-une-structure","2.nsi-tale\u002Fta-structures-donnees\u002F2.implementer-une-structure",{"title":133,"path":134,"stem":135},"Listes, piles, files, dictionnaires","\u002Fnsi-tale\u002Fta-structures-donnees\u002Flistes-piles-files-dict","2.nsi-tale\u002Fta-structures-donnees\u002F3.listes-piles-files-dict",{"title":137,"path":138,"stem":139},"Docstring, tests, assertions","\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions","2.nsi-tale\u002Fta-structures-donnees\u002F4.contrat-tests-assertions",{"id":141,"title":142,"bo":143,"body":147,"description":645,"eval":646,"extension":647,"icon":646,"labo":646,"meta":648,"navigation":649,"path":650,"publie":651,"quizContext":646,"quizzes":652,"readingTime":434,"seo":653,"stem":655,"tp":646,"__hash__":656},"coursMemo\u002F2.nsi-tale\u002Fta-structures-donnees\u002F4.contrat-tests-assertions.memo.md","Un contrat, trois écritures",[144,145,146],"TA04","PG04","PG03",{"type":148,"value":149,"toc":638},"minimark",[150,155,175,179,252,256,364,368,417,421,634],[151,152,154],"h2",{"id":153},"en-une-phrase","En une phrase",[156,157,158],"p",{},[159,160,161,162,166,167,171,172,174],"strong",{},"Un contrat s'écrit trois fois : en français dans la docstring, en ",[163,164,165],"code",{},"assert"," dans un jeu de tests écrit ",[168,169,170],"em",{},"avant"," le code, en ",[163,173,165],{}," dans la méthode pour refuser un appel interdit.",[151,176,178],{"id":177},"à-mémoriser","À mémoriser",[180,181,182,193,203,211,217,228,234],"ul",{},[183,184,185,188,189,192],"li",{},[159,186,187],{},"Docstring"," : le contrat écrit dans le code ; ",[163,190,191],{},"help(Pile.depiler)"," l'affiche sans ouvrir le corps.",[183,194,195,198,199,202],{},[159,196,197],{},"Précondition"," : ce que l'appel doit garantir avant ; ",[159,200,201],{},"postcondition"," : ce que la méthode promet après.",[183,204,205,210],{},[159,206,207,208],{},"Une promesse du contrat, un ",[163,209,165],{}," : c'est ainsi que s'écrit un jeu de tests.",[183,212,213,214,216],{},"Le jeu de tests ne dépend que du contrat, donc il s'écrit ",[159,215,170],{}," le code.",[183,218,219,220,223,224,227],{},"Un bon jeu de tests ",[159,221,222],{},"échoue"," tant que le code n'existe pas et ",[159,225,226],{},"passe"," une fois qu'il est juste : il définit « fini ».",[183,229,230,233],{},[159,231,232],{},"Le succès d'un jeu de tests ne garantit pas la correction d'un programme",", seulement celle des cas écrits.",[183,235,236,237,240,241,244,245,240,248,251],{},"Le test vit ",[159,238,239],{},"dehors"," et accuse ",[159,242,243],{},"l'implémentation"," ; l'assertion vit ",[159,246,247],{},"dedans",[159,249,250],{},"l'appelant",".",[151,253,255],{"id":254},"à-savoir-reconnaître","À savoir reconnaître",[257,258,259,272],"table",{},[260,261,262],"thead",{},[263,264,265,269],"tr",{},[266,267,268],"th",{},"Situation",[266,270,271],{},"Ce que c'est",[273,274,275,298,316,338,346,354],"tbody",{},[263,276,277,291],{},[278,279,280,283,284,287,288],"td",{},[163,281,282],{},"assert p.depiler() == \"R\""," après ",[163,285,286],{},"empiler(7)",", ",[163,289,290],{},"empiler(\"R\")",[278,292,293,294,297],{},"un ",[159,295,296],{},"test"," : dehors, accuse l'implémentation",[263,299,300,309],{},[278,301,302,305,306],{},[163,303,304],{},"assert not self.est_vide()"," en première ligne de ",[163,307,308],{},"depiler",[278,310,311,312,315],{},"une ",[159,313,314],{},"précondition"," : dedans, accuse l'appelant",[263,317,318,327],{},[278,319,320,323,324],{},[163,321,322],{},"assert len(p) == 2"," juste après ",[163,325,326],{},"p.sommet()",[278,328,329,330,333,334,337],{},"test d'une ",[159,331,332],{},"absence d'effet"," : ",[163,335,336],{},"sommet"," ne retire rien",[263,339,340,343],{},[278,341,342],{},"Le test échoue sur une classe sans corps",[278,344,345],{},"normal : il liste ce qu'il reste à écrire",[263,347,348,351],{},[278,349,350],{},"Une implémentation fausse passe le test",[278,352,353],{},"un cas manque au jeu de tests",[263,355,356,361],{},[278,357,358],{},[163,359,360],{},"IndexError: pop from empty list",[278,362,363],{},"message qui parle des entrailles, pas du contrat : précondition non écrite",[151,365,367],{"id":366},"pièges-courants","Pièges courants",[180,369,370,377,384,387,393,404,414],{},[183,371,372,373,376],{},"Tester l'implémentation (",[163,374,375],{},"p.elements == [...]",") au lieu du contrat.",[183,378,379,380,383],{},"N'empiler qu'",[159,381,382],{},"un"," élément pour tester LIFO : une file passerait aussi.",[183,385,386],{},"Conclure qu'un code est juste parce que ses tests passent.",[183,388,389,392],{},[163,390,391],{},"assert (condition, \"message\")"," : un tuple non vide est toujours vrai, l'assertion ne saute jamais.",[183,394,395,396,399,400,403],{},"Ne rien écrire sur ",[163,397,398],{},"depiler()"," ou ",[163,401,402],{},"sommet()"," d'une pile vide : le code décide alors à la place du contrat.",[183,405,406,407,409,410,413],{},"Compter sur ",[163,408,165],{}," pour la sécurité : ",[163,411,412],{},"python -O"," les désactive toutes.",[183,415,416],{},"Le jeu de tests se relance à chaque modification, pas une seule fois.",[151,418,420],{"id":419},"syntaxe-python","Syntaxe Python",[422,423,428],"pre",{"className":424,"code":425,"language":426,"meta":427,"style":427},"language-python shiki shiki-themes github-light github-light github-dark","class Pile:\n    def depiler(self):\n        \"\"\"Retirer l'élément du sommet et le renvoyer.\n        Précondition : la pile n'est pas vide.\"\"\"\n        assert not self.est_vide(), \"depiler exige une pile non vide\"\n        return self.elements.pop()\n\n\ndef tester_pile(fabriquer_une_pile):\n    p = fabriquer_une_pile()\n    assert p.est_vide()\n    p.empiler(7)\n    p.empiler(\"R\")\n    assert p.sommet() == \"R\"\n    assert len(p) == 2            # sommet ne retire rien\n    assert p.depiler() == \"R\"\n    assert p.depiler() == 7\n    assert p.est_vide()\n","python","",[163,429,430,447,459,466,472,491,502,509,514,526,538,547,559,569,583,603,615,627],{"__ignoreMap":427},[431,432,435,439,443],"span",{"class":433,"line":434},"line",1,[431,436,438],{"class":437},"s8jYJ","class",[431,440,442],{"class":441},"snPdu"," Pile",[431,444,446],{"class":445},"sxrX7",":\n",[431,448,450,453,456],{"class":433,"line":449},2,[431,451,452],{"class":437},"    def",[431,454,455],{"class":441}," depiler",[431,457,458],{"class":445},"(self):\n",[431,460,462],{"class":433,"line":461},3,[431,463,465],{"class":464},"sIIMD","        \"\"\"Retirer l'élément du sommet et le renvoyer.\n",[431,467,469],{"class":433,"line":468},4,[431,470,471],{"class":464},"        Précondition : la pile n'est pas vide.\"\"\"\n",[431,473,475,478,481,485,488],{"class":433,"line":474},5,[431,476,477],{"class":437},"        assert",[431,479,480],{"class":437}," not",[431,482,484],{"class":483},"sBjJW"," self",[431,486,487],{"class":445},".est_vide(), ",[431,489,490],{"class":464},"\"depiler exige une pile non vide\"\n",[431,492,494,497,499],{"class":433,"line":493},6,[431,495,496],{"class":437},"        return",[431,498,484],{"class":483},[431,500,501],{"class":445},".elements.pop()\n",[431,503,505],{"class":433,"line":504},7,[431,506,508],{"emptyLinePlaceholder":507},true,"\n",[431,510,512],{"class":433,"line":511},8,[431,513,508],{"emptyLinePlaceholder":507},[431,515,517,520,523],{"class":433,"line":516},9,[431,518,519],{"class":437},"def",[431,521,522],{"class":441}," tester_pile",[431,524,525],{"class":445},"(fabriquer_une_pile):\n",[431,527,529,532,535],{"class":433,"line":528},10,[431,530,531],{"class":445},"    p ",[431,533,534],{"class":437},"=",[431,536,537],{"class":445}," fabriquer_une_pile()\n",[431,539,541,544],{"class":433,"line":540},11,[431,542,543],{"class":437},"    assert",[431,545,546],{"class":445}," p.est_vide()\n",[431,548,550,553,556],{"class":433,"line":549},12,[431,551,552],{"class":445},"    p.empiler(",[431,554,555],{"class":483},"7",[431,557,558],{"class":445},")\n",[431,560,562,564,567],{"class":433,"line":561},13,[431,563,552],{"class":445},[431,565,566],{"class":464},"\"R\"",[431,568,558],{"class":445},[431,570,572,574,577,580],{"class":433,"line":571},14,[431,573,543],{"class":437},[431,575,576],{"class":445}," p.sommet() ",[431,578,579],{"class":437},"==",[431,581,582],{"class":464}," \"R\"\n",[431,584,586,588,591,594,596,599],{"class":433,"line":585},15,[431,587,543],{"class":437},[431,589,590],{"class":483}," len",[431,592,593],{"class":445},"(p) ",[431,595,579],{"class":437},[431,597,598],{"class":483}," 2",[431,600,602],{"class":601},"sCsY4","            # sommet ne retire rien\n",[431,604,606,608,611,613],{"class":433,"line":605},16,[431,607,543],{"class":437},[431,609,610],{"class":445}," p.depiler() ",[431,612,579],{"class":437},[431,614,582],{"class":464},[431,616,618,620,622,624],{"class":433,"line":617},17,[431,619,543],{"class":437},[431,621,610],{"class":445},[431,623,579],{"class":437},[431,625,626],{"class":483}," 7\n",[431,628,630,632],{"class":433,"line":629},18,[431,631,543],{"class":437},[431,633,546],{"class":445},[635,636,637],"style",{},"html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":427,"searchDepth":449,"depth":449,"links":639},[640,641,642,643,644],{"id":153,"depth":449,"text":154},{"id":177,"depth":449,"text":178},{"id":254,"depth":449,"text":255},{"id":366,"depth":449,"text":367},{"id":419,"depth":449,"text":420},"Mémo de révision : docstring, jeu de tests écrit avant le code, assertion de précondition.",null,"md",{},false,"\u002Fnsi-tale\u002Fta-structures-donnees\u002Fcontrat-tests-assertions.memo","2026-09-25",[],{"title":142,"description":654},"Mémo de révision : docstring, jeu de tests écrit avant le code, assertion de précondition.","2.nsi-tale\u002Fta-structures-donnees\u002F4.contrat-tests-assertions.memo","C7dbu12fm-hfaMJhtbKgU24lbTgFDaFElKPOHcAHDiM",{"id":658,"title":659,"bo":660,"body":661,"description":3231,"eval":646,"extension":647,"icon":646,"labo":646,"meta":3232,"navigation":3233,"path":138,"publie":651,"quizContext":646,"quizzes":3234,"readingTime":434,"seo":3305,"stem":139,"tp":646,"__hash__":3308},"cours\u002F2.nsi-tale\u002Fta-structures-donnees\u002F4.contrat-tests-assertions.md","Un contrat, trois écritures : docstring, tests, assertions",[144,145,146],{"type":148,"value":662,"toc":3220},[663,667,678,693,700,756,781,785,800,898,905,1033,1043,1046,1077,1081,1095,1103,1177,1180,1190,1202,1209,1384,1401,1436,1472,1476,1482,1501,1769,1776,1783,1806,1810,1816,1858,2350,2365,2384,2456,2470,2496,2500,2510,2591,2598,2624,2819,2823,2836,2911,2914,2930,2965,2995,3026,3028,3087,3091,3094,3208,3215,3217],[151,664,666],{"id":665},"introduction","Introduction",[156,668,669,670,673,674,677],{},"Les cours précédents ont lu le contrat d'une structure du côté de qui\nl'",[159,671,672],{},"utilise"," : l'interface dit ce qu'une pile ou une file promet, et deux\nimplémentations différentes peuvent tenir la même promesse (",[675,676],"bo-ref",{"code":144},").",[156,679,680,681,684,685,688,689,692],{},"Ce cours lit le même contrat de l'autre côté, celui de qui ",[159,682,683],{},"écrit"," le code.\nVu de là, le contrat sert à deux choses. Il permet d'écrire le ",[159,686,687],{},"jeu de tests\navant la première ligne de code",", puisque les tests ne dépendent que de ce que\nla structure promet. Et il ",[159,690,691],{},"borne le périmètre"," du programme : il dit ce\nqu'il y a à écrire, donc à quoi on reconnaît que c'est fini.",[156,694,695,696,699],{},"Le fil conducteur tient en une phrase : un même contrat s'écrit ",[159,697,698],{},"trois fois",",\net les trois écritures disent la même chose.",[257,701,702,715],{},[260,703,704],{},[263,705,706,709,712],{},[266,707,708],{},"Écriture",[266,710,711],{},"Où elle vit",[266,713,714],{},"Ce qu'elle fait",[273,716,717,730,743],{},[263,718,719,724,727],{},[278,720,721],{},[159,722,723],{},"La docstring",[278,725,726],{},"dans le code, en français",[278,728,729],{},"dit ce que la méthode promet",[263,731,732,737,740],{},[278,733,734],{},[159,735,736],{},"Le jeu de tests",[278,738,739],{},"hors de la classe",[278,741,742],{},"éprouve l'implémentation sur des cas choisis",[263,744,745,750,753],{},[278,746,747],{},[159,748,749],{},"L'assertion",[278,751,752],{},"dans la méthode",[278,754,755],{},"refuse un appel que le contrat interdit",[757,758,759],"note",{},[156,760,761,762,764,765,768,769,771,772,768,774,776,777,780],{},"Aucune de ces trois notions n'est neuve : spécification, docstring et ",[163,763,165],{},"\nont été posés en Première (",[766,767,71],"a",{"href":72},",\n",[675,770],{"code":145},") et les jeux de tests aussi (",[766,773,75],{"href":76},[675,775],{"code":146},"). Ce qui est neuf, c'est l'",[159,778,779],{},"ordre"," : le test s'écrit en\npremier, et l'assertion change de rôle selon l'endroit où elle vit.",[151,782,784],{"id":783},"première-écriture-la-docstring","Première écriture : la docstring",[156,786,787,788,791,792,795,796,799],{},"Le contrat d'une pile tient dans un tableau : pour chaque opération, ce qu'elle\nreçoit, ce qu'elle renvoie, et si elle modifie la pile. C'est l'interface de la\n",[163,789,790],{},"Pile"," du cours précédent, avec ",[163,793,794],{},"len(p)"," en plus (la méthode spéciale\n",[163,797,798],{},"__len__",") pour pouvoir compter les éléments.",[257,801,802,818],{},[260,803,804],{},[263,805,806,809,812,815],{},[266,807,808],{},"Méthode",[266,810,811],{},"Reçoit",[266,813,814],{},"Renvoie",[266,816,817],{},"Modifie la pile ?",[273,819,820,842,856,871,885],{},[263,821,822,827,833,836],{},[278,823,824],{},[163,825,826],{},"empiler(x)",[278,828,829,830],{},"un élément ",[163,831,832],{},"x",[278,834,835],{},"rien",[278,837,838,839,841],{},"oui : ",[163,840,832],{}," passe au sommet",[263,843,844,848,850,853],{},[278,845,846],{},[163,847,398],{},[278,849,835],{},[278,851,852],{},"l'élément du sommet",[278,854,855],{},"oui : il est retiré",[263,857,858,862,864,866],{},[278,859,860],{},[163,861,402],{},[278,863,835],{},[278,865,852],{},[278,867,868],{},[159,869,870],{},"non",[263,872,873,878,880,883],{},[278,874,875],{},[163,876,877],{},"est_vide()",[278,879,835],{},[278,881,882],{},"un booléen",[278,884,870],{},[263,886,887,891,893,896],{},[278,888,889],{},[163,890,794],{},[278,892,835],{},[278,894,895],{},"le nombre d'éléments",[278,897,870],{},[156,899,900,901,904],{},"Ce tableau ",[159,902,903],{},"est"," la documentation de la classe : il suffit de recopier chaque\nligne dans la docstring de la méthode correspondante. Rien n'est ajouté, seule\nla place change.",[422,906,908],{"className":424,"code":907,"language":426,"meta":427,"style":427},"class Pile:\n    \"\"\"Une pile : on n'accède qu'au dessus (LIFO).\"\"\"\n\n    def __init__(self):\n        \"\"\"Fabriquer une pile neuve, vide.\"\"\"\n\n    def empiler(self, x):\n        \"\"\"Poser l'élément x sur le dessus de la pile.\"\"\"\n\n    def depiler(self):\n        \"\"\"Retirer l'élément du sommet et le renvoyer.\"\"\"\n\n    def sommet(self):\n        \"\"\"Renvoyer l'élément du sommet sans le retirer.\"\"\"\n\n    def est_vide(self):\n        \"\"\"Renvoyer True si la pile ne contient aucun élément.\"\"\"\n\n    def __len__(self):\n        \"\"\"Renvoyer le nombre d'éléments de la pile.\"\"\"\n",[163,909,910,918,923,927,936,941,945,955,960,964,972,977,981,990,995,999,1008,1013,1017,1027],{"__ignoreMap":427},[431,911,912,914,916],{"class":433,"line":434},[431,913,438],{"class":437},[431,915,442],{"class":441},[431,917,446],{"class":445},[431,919,920],{"class":433,"line":449},[431,921,922],{"class":464},"    \"\"\"Une pile : on n'accède qu'au dessus (LIFO).\"\"\"\n",[431,924,925],{"class":433,"line":461},[431,926,508],{"emptyLinePlaceholder":507},[431,928,929,931,934],{"class":433,"line":468},[431,930,452],{"class":437},[431,932,933],{"class":483}," __init__",[431,935,458],{"class":445},[431,937,938],{"class":433,"line":474},[431,939,940],{"class":464},"        \"\"\"Fabriquer une pile neuve, vide.\"\"\"\n",[431,942,943],{"class":433,"line":493},[431,944,508],{"emptyLinePlaceholder":507},[431,946,947,949,952],{"class":433,"line":504},[431,948,452],{"class":437},[431,950,951],{"class":441}," empiler",[431,953,954],{"class":445},"(self, x):\n",[431,956,957],{"class":433,"line":511},[431,958,959],{"class":464},"        \"\"\"Poser l'élément x sur le dessus de la pile.\"\"\"\n",[431,961,962],{"class":433,"line":516},[431,963,508],{"emptyLinePlaceholder":507},[431,965,966,968,970],{"class":433,"line":528},[431,967,452],{"class":437},[431,969,455],{"class":441},[431,971,458],{"class":445},[431,973,974],{"class":433,"line":540},[431,975,976],{"class":464},"        \"\"\"Retirer l'élément du sommet et le renvoyer.\"\"\"\n",[431,978,979],{"class":433,"line":549},[431,980,508],{"emptyLinePlaceholder":507},[431,982,983,985,988],{"class":433,"line":561},[431,984,452],{"class":437},[431,986,987],{"class":441}," sommet",[431,989,458],{"class":445},[431,991,992],{"class":433,"line":571},[431,993,994],{"class":464},"        \"\"\"Renvoyer l'élément du sommet sans le retirer.\"\"\"\n",[431,996,997],{"class":433,"line":585},[431,998,508],{"emptyLinePlaceholder":507},[431,1000,1001,1003,1006],{"class":433,"line":605},[431,1002,452],{"class":437},[431,1004,1005],{"class":441}," est_vide",[431,1007,458],{"class":445},[431,1009,1010],{"class":433,"line":617},[431,1011,1012],{"class":464},"        \"\"\"Renvoyer True si la pile ne contient aucun élément.\"\"\"\n",[431,1014,1015],{"class":433,"line":629},[431,1016,508],{"emptyLinePlaceholder":507},[431,1018,1020,1022,1025],{"class":433,"line":1019},19,[431,1021,452],{"class":437},[431,1023,1024],{"class":483}," __len__",[431,1026,458],{"class":445},[431,1028,1030],{"class":433,"line":1029},20,[431,1031,1032],{"class":464},"        \"\"\"Renvoyer le nombre d'éléments de la pile.\"\"\"\n",[156,1034,1035,1036,1039,1040,1042],{},"Cette classe n'a ",[159,1037,1038],{},"aucun corps de méthode",", et pourtant elle dit tout ce que\nle contrat dit. La documentation se lit sans ouvrir le code :\n",[163,1041,191],{}," affiche la phrase, et elle suffit pour utiliser la\npile.",[156,1044,1045],{},"Quatre mots pour parler d'un contrat :",[180,1047,1048,1054,1062,1071],{},[183,1049,1050,1053],{},[159,1051,1052],{},"prototype"," : le nom d'une méthode, ce qu'elle reçoit, ce qu'elle renvoie ;",[183,1055,1056,1058,1059,1061],{},[159,1057,314],{}," : ce que l'appel doit garantir ",[168,1060,170],{}," (une pile non vide,\npar exemple) ;",[183,1063,1064,1066,1067,1070],{},[159,1065,201],{}," : ce que la méthode promet ",[168,1068,1069],{},"après",", si la précondition\nest tenue ;",[183,1072,1073,1076],{},[159,1074,1075],{},"docstring"," : le contrat écrit dans le code, entre triples guillemets.",[151,1078,1080],{"id":1079},"deuxième-écriture-le-jeu-de-tests","Deuxième écriture : le jeu de tests",[156,1082,1083,1084,1086,1087,1090,1091,1094],{},"Une instruction ",[163,1085,165],{}," est une affirmation : vraie, rien ne se passe ; fausse,\nl'exécution s'arrête sur une ",[163,1088,1089],{},"AssertionError"," qui nomme ce qui a échoué. Un\n",[159,1092,1093],{},"jeu de tests"," est une suite d'affirmations tirées du contrat.",[156,1096,1097,1098,251],{},"La traduction est mécanique : ",[159,1099,1100,1101],{},"une promesse du contrat, un ",[163,1102,165],{},[257,1104,1105,1118],{},[260,1106,1107],{},[263,1108,1109,1112],{},[266,1110,1111],{},"Ce que le contrat promet",[266,1113,1114,1115,1117],{},"L'",[163,1116,165],{}," qui l'éprouve",[273,1119,1120,1130,1146,1156,1167],{},[263,1121,1122,1125],{},[278,1123,1124],{},"une pile neuve est vide",[278,1126,1127],{},[163,1128,1129],{},"assert p.est_vide()",[263,1131,1132,1141],{},[278,1133,1134,1135,1137,1138,1140],{},"après ",[163,1136,286],{}," puis ",[163,1139,290],{},", le sommet est le dernier posé",[278,1142,1143],{},[163,1144,1145],{},"assert p.sommet() == \"R\"",[263,1147,1148,1152],{},[278,1149,1150,337],{},[163,1151,336],{},[278,1153,1154],{},[163,1155,322],{},[263,1157,1158,1163],{},[278,1159,1160,1162],{},[163,1161,308],{}," rend le dernier élément empilé",[278,1164,1165],{},[163,1166,282],{},[263,1168,1169,1172],{},[278,1170,1171],{},"… puis celui qui était dessous",[278,1173,1174],{},[163,1175,1176],{},"assert p.depiler() == 7",[156,1178,1179],{},"Deux lignes du tableau méritent qu'on s'y arrête.",[156,1181,1182,1185,1186,1189],{},[159,1183,1184],{},"Empiler deux éléments, pas un."," Avec un seul élément, le premier entré et le\ndernier entré sont le même : une ",[168,1187,1188],{},"file"," passerait le test. Pour éprouver\n« dernier entré, premier sorti », il faut au moins deux entrées ; sinon, la\npropriété qui définit la pile n'est tout simplement pas mise à l'épreuve.",[156,1191,1192,1195,1196,1198,1199,1201],{},[159,1193,1194],{},"Tester une absence."," « ",[163,1197,336],{}," ne retire rien » promet une absence d'effet,\net une absence ne se lit pas dans la valeur renvoyée : ",[163,1200,402],{}," renvoie le\nbon élément, qu'il le retire ou non. Il faut regarder ailleurs : ici, la\nlongueur de la pile, qui doit rester à 2.",[156,1203,1204,1205,1208],{},"Rassemblées dans une fonction, ces affirmations forment le test. Il reçoit en\nparamètre ",[159,1206,1207],{},"la classe à éprouver",", ce qui permet de lui soumettre n'importe\nquelle implémentation :",[422,1210,1212],{"className":424,"code":1211,"language":426,"meta":427,"style":427},"def tester_pile(fabriquer_une_pile):\n    \"\"\"Éprouver une classe de pile. Ne connaît que le CONTRAT :\n    aucune mention de liste, d'append ou de pop.\"\"\"\n    p = fabriquer_une_pile()\n    assert p.est_vide(), \"une pile neuve est vide\"\n\n    p.empiler(7)\n    p.empiler(\"R\")\n    assert len(p) == 2, \"deux empiler, deux éléments\"\n    assert not p.est_vide()\n\n    assert p.sommet() == \"R\", \"sommet renvoie le dessus\"\n    assert len(p) == 2, \"sommet ne retire rien\"\n\n    assert p.depiler() == \"R\", \"depiler renvoie le dessus\"\n    assert p.depiler() == 7, \"sous R, il y avait 7\"\n    assert p.est_vide(), \"tout est ressorti\"\n    return \"le contrat est honoré\"\n",[163,1213,1214,1222,1227,1232,1240,1250,1254,1262,1270,1287,1295,1299,1315,1332,1336,1351,1367,1376],{"__ignoreMap":427},[431,1215,1216,1218,1220],{"class":433,"line":434},[431,1217,519],{"class":437},[431,1219,522],{"class":441},[431,1221,525],{"class":445},[431,1223,1224],{"class":433,"line":449},[431,1225,1226],{"class":464},"    \"\"\"Éprouver une classe de pile. Ne connaît que le CONTRAT :\n",[431,1228,1229],{"class":433,"line":461},[431,1230,1231],{"class":464},"    aucune mention de liste, d'append ou de pop.\"\"\"\n",[431,1233,1234,1236,1238],{"class":433,"line":468},[431,1235,531],{"class":445},[431,1237,534],{"class":437},[431,1239,537],{"class":445},[431,1241,1242,1244,1247],{"class":433,"line":474},[431,1243,543],{"class":437},[431,1245,1246],{"class":445}," p.est_vide(), ",[431,1248,1249],{"class":464},"\"une pile neuve est vide\"\n",[431,1251,1252],{"class":433,"line":493},[431,1253,508],{"emptyLinePlaceholder":507},[431,1255,1256,1258,1260],{"class":433,"line":504},[431,1257,552],{"class":445},[431,1259,555],{"class":483},[431,1261,558],{"class":445},[431,1263,1264,1266,1268],{"class":433,"line":511},[431,1265,552],{"class":445},[431,1267,566],{"class":464},[431,1269,558],{"class":445},[431,1271,1272,1274,1276,1278,1280,1282,1284],{"class":433,"line":516},[431,1273,543],{"class":437},[431,1275,590],{"class":483},[431,1277,593],{"class":445},[431,1279,579],{"class":437},[431,1281,598],{"class":483},[431,1283,287],{"class":445},[431,1285,1286],{"class":464},"\"deux empiler, deux éléments\"\n",[431,1288,1289,1291,1293],{"class":433,"line":528},[431,1290,543],{"class":437},[431,1292,480],{"class":437},[431,1294,546],{"class":445},[431,1296,1297],{"class":433,"line":540},[431,1298,508],{"emptyLinePlaceholder":507},[431,1300,1301,1303,1305,1307,1310,1312],{"class":433,"line":549},[431,1302,543],{"class":437},[431,1304,576],{"class":445},[431,1306,579],{"class":437},[431,1308,1309],{"class":464}," \"R\"",[431,1311,287],{"class":445},[431,1313,1314],{"class":464},"\"sommet renvoie le dessus\"\n",[431,1316,1317,1319,1321,1323,1325,1327,1329],{"class":433,"line":561},[431,1318,543],{"class":437},[431,1320,590],{"class":483},[431,1322,593],{"class":445},[431,1324,579],{"class":437},[431,1326,598],{"class":483},[431,1328,287],{"class":445},[431,1330,1331],{"class":464},"\"sommet ne retire rien\"\n",[431,1333,1334],{"class":433,"line":571},[431,1335,508],{"emptyLinePlaceholder":507},[431,1337,1338,1340,1342,1344,1346,1348],{"class":433,"line":585},[431,1339,543],{"class":437},[431,1341,610],{"class":445},[431,1343,579],{"class":437},[431,1345,1309],{"class":464},[431,1347,287],{"class":445},[431,1349,1350],{"class":464},"\"depiler renvoie le dessus\"\n",[431,1352,1353,1355,1357,1359,1362,1364],{"class":433,"line":605},[431,1354,543],{"class":437},[431,1356,610],{"class":445},[431,1358,579],{"class":437},[431,1360,1361],{"class":483}," 7",[431,1363,287],{"class":445},[431,1365,1366],{"class":464},"\"sous R, il y avait 7\"\n",[431,1368,1369,1371,1373],{"class":433,"line":617},[431,1370,543],{"class":437},[431,1372,1246],{"class":445},[431,1374,1375],{"class":464},"\"tout est ressorti\"\n",[431,1377,1378,1381],{"class":433,"line":629},[431,1379,1380],{"class":437},"    return",[431,1382,1383],{"class":464}," \"le contrat est honoré\"\n",[1385,1386,1387],"tip",{},[156,1388,1389,1390,1393,1394,1397,1398,1400],{},"Le test ne mentionne ",[159,1391,1392],{},"aucune"," implémentation. S'il écrivait\n",[163,1395,1396],{},"assert p.elements == [7, \"R\"]",", il ne testerait plus le contrat mais une façon\nparticulière de le réaliser, et rejetterait à tort une ",[163,1399,790],{}," correcte rangée\nautrement.",[1402,1403,1407,1420],"self-eval-qcm",{"correct":1404,"explanation":1405,"slug":1406},"2","Avec un seul élément, premier entré et dernier entré se confondent : une file rendrait le même élément et passerait le test. Deux entrées suffisent à distinguer LIFO de FIFO.","contrat-tests-assertions-c1",[1408,1409,1410],"template",{"v-slot:question":427},[156,1411,1412,1413,1416,1417,1419],{},"Pourquoi le test empile-t-il ",[159,1414,1415],{},"deux"," éléments avant d'appeler ",[163,1418,398],{}," ?",[1408,1421,1422],{"v-slot:choices":427},[180,1423,1424,1427,1433],{},[183,1425,1426],{},"Pour vérifier que la pile accepte plusieurs types d'éléments",[183,1428,1429,1430],{},"Pour tester la performance de ",[163,1431,1432],{},"empiler",[183,1434,1435],{},"Parce qu'avec un seul élément, une file passerait aussi le test",[1402,1437,1441,1452],{"correct":1438,"explanation":1439,"slug":1440},"1","sommet() renvoie le bon élément qu'il le retire ou non : la valeur renvoyée ne dit rien de l'effet. C'est la longueur, inchangée, qui prouve qu'il n'a rien retiré.","contrat-tests-assertions-c2",[1408,1442,1443],{"v-slot:question":427},[156,1444,1445,1446,1448,1449,1451],{},"Quel ",[163,1447,165],{}," éprouve la promesse « ",[163,1450,402],{}," ne retire rien » ?",[1408,1453,1454],{"v-slot:choices":427},[180,1455,1456,1460,1467],{},[183,1457,1458],{},[163,1459,1145],{},[183,1461,1462,1464,1465],{},[163,1463,322],{}," juste après l'appel à ",[163,1466,402],{},[183,1468,1469],{},[163,1470,1471],{},"assert p.sommet() is not None",[151,1473,1475],{"id":1474},"le-test-avant-le-code","Le test avant le code",[156,1477,1478,1479,1481],{},"Le jeu de tests ne dépend que du contrat. Il peut donc s'écrire ",[159,1480,170],{}," la\nmoindre ligne d'implémentation, et c'est précisément l'ordre recommandé.",[156,1483,1484,1485,1487,1488,1490,1491,1493,1494,1497,1498,1500],{},"Lancé sur la ",[163,1486,790],{}," sans corps de la première partie, le test ",[159,1489,222],{}," dès sa\npremière ligne : ",[163,1492,877],{}," renvoie ",[163,1495,1496],{},"None",", qui compte comme faux, donc\n",[163,1499,1129],{}," échoue.\nCe n'est pas un raté du test, c'est le résultat attendu.",[1502,1503,1504],"python-snippet",{},[422,1505,1507],{"className":424,"code":1506,"language":426,"meta":427,"style":427},"class Pile:\n    \"\"\"Le contrat seul : aucune méthode n'a de corps.\"\"\"\n    def __init__(self): pass\n    def empiler(self, x): pass\n    def depiler(self): pass\n    def sommet(self): pass\n    def est_vide(self): pass\n    def __len__(self): pass\n\ndef tester_pile(fabriquer_une_pile):\n    p = fabriquer_une_pile()\n    assert p.est_vide(), \"une pile neuve est vide\"\n    p.empiler(7)\n    p.empiler(\"R\")\n    assert len(p) == 2, \"deux empiler, deux éléments\"\n    assert p.sommet() == \"R\", \"sommet renvoie le dessus\"\n    assert len(p) == 2, \"sommet ne retire rien\"\n    assert p.depiler() == \"R\", \"depiler renvoie le dessus\"\n    assert p.depiler() == 7, \"sous R, il y avait 7\"\n    assert p.est_vide(), \"tout est ressorti\"\n    return \"le contrat est honoré\"\n\ntry:\n    print(tester_pile(Pile))\nexcept AssertionError as e:\n    print(\"échec :\", e)\n",[163,1508,1509,1517,1522,1534,1545,1555,1565,1575,1585,1589,1597,1605,1613,1621,1629,1645,1659,1675,1689,1703,1711,1718,1723,1731,1740,1755],{"__ignoreMap":427},[431,1510,1511,1513,1515],{"class":433,"line":434},[431,1512,438],{"class":437},[431,1514,442],{"class":441},[431,1516,446],{"class":445},[431,1518,1519],{"class":433,"line":449},[431,1520,1521],{"class":464},"    \"\"\"Le contrat seul : aucune méthode n'a de corps.\"\"\"\n",[431,1523,1524,1526,1528,1531],{"class":433,"line":461},[431,1525,452],{"class":437},[431,1527,933],{"class":483},[431,1529,1530],{"class":445},"(self): ",[431,1532,1533],{"class":437},"pass\n",[431,1535,1536,1538,1540,1543],{"class":433,"line":468},[431,1537,452],{"class":437},[431,1539,951],{"class":441},[431,1541,1542],{"class":445},"(self, x): ",[431,1544,1533],{"class":437},[431,1546,1547,1549,1551,1553],{"class":433,"line":474},[431,1548,452],{"class":437},[431,1550,455],{"class":441},[431,1552,1530],{"class":445},[431,1554,1533],{"class":437},[431,1556,1557,1559,1561,1563],{"class":433,"line":493},[431,1558,452],{"class":437},[431,1560,987],{"class":441},[431,1562,1530],{"class":445},[431,1564,1533],{"class":437},[431,1566,1567,1569,1571,1573],{"class":433,"line":504},[431,1568,452],{"class":437},[431,1570,1005],{"class":441},[431,1572,1530],{"class":445},[431,1574,1533],{"class":437},[431,1576,1577,1579,1581,1583],{"class":433,"line":511},[431,1578,452],{"class":437},[431,1580,1024],{"class":483},[431,1582,1530],{"class":445},[431,1584,1533],{"class":437},[431,1586,1587],{"class":433,"line":516},[431,1588,508],{"emptyLinePlaceholder":507},[431,1590,1591,1593,1595],{"class":433,"line":528},[431,1592,519],{"class":437},[431,1594,522],{"class":441},[431,1596,525],{"class":445},[431,1598,1599,1601,1603],{"class":433,"line":540},[431,1600,531],{"class":445},[431,1602,534],{"class":437},[431,1604,537],{"class":445},[431,1606,1607,1609,1611],{"class":433,"line":549},[431,1608,543],{"class":437},[431,1610,1246],{"class":445},[431,1612,1249],{"class":464},[431,1614,1615,1617,1619],{"class":433,"line":561},[431,1616,552],{"class":445},[431,1618,555],{"class":483},[431,1620,558],{"class":445},[431,1622,1623,1625,1627],{"class":433,"line":571},[431,1624,552],{"class":445},[431,1626,566],{"class":464},[431,1628,558],{"class":445},[431,1630,1631,1633,1635,1637,1639,1641,1643],{"class":433,"line":585},[431,1632,543],{"class":437},[431,1634,590],{"class":483},[431,1636,593],{"class":445},[431,1638,579],{"class":437},[431,1640,598],{"class":483},[431,1642,287],{"class":445},[431,1644,1286],{"class":464},[431,1646,1647,1649,1651,1653,1655,1657],{"class":433,"line":605},[431,1648,543],{"class":437},[431,1650,576],{"class":445},[431,1652,579],{"class":437},[431,1654,1309],{"class":464},[431,1656,287],{"class":445},[431,1658,1314],{"class":464},[431,1660,1661,1663,1665,1667,1669,1671,1673],{"class":433,"line":617},[431,1662,543],{"class":437},[431,1664,590],{"class":483},[431,1666,593],{"class":445},[431,1668,579],{"class":437},[431,1670,598],{"class":483},[431,1672,287],{"class":445},[431,1674,1331],{"class":464},[431,1676,1677,1679,1681,1683,1685,1687],{"class":433,"line":629},[431,1678,543],{"class":437},[431,1680,610],{"class":445},[431,1682,579],{"class":437},[431,1684,1309],{"class":464},[431,1686,287],{"class":445},[431,1688,1350],{"class":464},[431,1690,1691,1693,1695,1697,1699,1701],{"class":433,"line":1019},[431,1692,543],{"class":437},[431,1694,610],{"class":445},[431,1696,579],{"class":437},[431,1698,1361],{"class":483},[431,1700,287],{"class":445},[431,1702,1366],{"class":464},[431,1704,1705,1707,1709],{"class":433,"line":1029},[431,1706,543],{"class":437},[431,1708,1246],{"class":445},[431,1710,1375],{"class":464},[431,1712,1714,1716],{"class":433,"line":1713},21,[431,1715,1380],{"class":437},[431,1717,1383],{"class":464},[431,1719,1721],{"class":433,"line":1720},22,[431,1722,508],{"emptyLinePlaceholder":507},[431,1724,1726,1729],{"class":433,"line":1725},23,[431,1727,1728],{"class":437},"try",[431,1730,446],{"class":445},[431,1732,1734,1737],{"class":433,"line":1733},24,[431,1735,1736],{"class":483},"    print",[431,1738,1739],{"class":445},"(tester_pile(Pile))\n",[431,1741,1743,1746,1749,1752],{"class":433,"line":1742},25,[431,1744,1745],{"class":437},"except",[431,1747,1748],{"class":483}," AssertionError",[431,1750,1751],{"class":437}," as",[431,1753,1754],{"class":445}," e:\n",[431,1756,1758,1760,1763,1766],{"class":433,"line":1757},26,[431,1759,1736],{"class":483},[431,1761,1762],{"class":445},"(",[431,1764,1765],{"class":464},"\"échec :\"",[431,1767,1768],{"class":445},", e)\n",[156,1770,1771,1772,1775],{},"Le repère à retenir : ",[159,1773,1774],{},"un bon jeu de tests échoue tant que le code n'existe\npas, et passe une fois qu'il est juste."," Entre les deux, chaque échec désigne\nce qu'il reste à écrire. Le test devient alors la définition de « fini » : le\ntravail s'arrête quand il passe, ni avant ni beaucoup après.",[156,1777,1778,1779,1782],{},"Un test qui passerait ",[159,1780,1781],{},"déjà"," sur une classe vide serait suspect : il\nn'éprouverait rien.",[1402,1784,1788,1793],{"correct":1785,"explanation":1786,"slug":1787},"0","Un test écrit depuis le contrat échoue tant que le code n'existe pas. Son échec n'accuse pas le test : il liste ce qu'il reste à écrire.","contrat-tests-assertions-c3",[1408,1789,1790],{"v-slot:question":427},[156,1791,1792],{},"Le jeu de tests, lancé sur une classe dont les méthodes n'ont pas de corps, échoue. Qu'en conclure ?",[1408,1794,1795],{"v-slot:choices":427},[180,1796,1797,1800,1803],{},[183,1798,1799],{},"Rien d'anormal : le test indique ce qu'il reste à écrire",[183,1801,1802],{},"Le test est mal écrit et doit être corrigé",[183,1804,1805],{},"Il faut écrire le code d'abord, et le test ensuite",[151,1807,1809],{"id":1808},"ce-quun-jeu-de-tests-ne-dit-pas","Ce qu'un jeu de tests ne dit pas",[156,1811,1812,1813,1815],{},"Trois implémentations de ",[163,1814,790],{},", chacune fausse à sa manière, passent devant le\nmême test, sans qu'il change d'une virgule :",[180,1817,1818,1832,1846],{},[183,1819,1820,333,1825,1827,1828,1831],{},[159,1821,1822],{},[163,1823,1824],{},"PileA",[163,1826,308],{}," renvoie le plus ",[159,1829,1830],{},"ancien"," élément au lieu du plus\nrécent ;",[183,1833,1834,333,1839,1841,1842,1845],{},[159,1835,1836],{},[163,1837,1838],{},"PileB",[163,1840,336],{}," ",[159,1843,1844],{},"retire"," l'élément qu'il renvoie ;",[183,1847,1848,1853,1854,1857],{},[159,1849,1850],{},[163,1851,1852],{},"PileC"," : au-delà de trois éléments, la pile ",[159,1855,1856],{},"oublie"," le plus ancien,\nsans rien signaler.",[1502,1859,1860],{},[422,1861,1863],{"className":424,"code":1862,"language":426,"meta":427,"style":427},"def tester_pile(fabriquer_une_pile):\n    p = fabriquer_une_pile()\n    assert p.est_vide(), \"une pile neuve est vide\"\n    p.empiler(7)\n    p.empiler(\"R\")\n    assert len(p) == 2, \"deux empiler, deux éléments\"\n    assert p.sommet() == \"R\", \"sommet renvoie le dessus\"\n    assert len(p) == 2, \"sommet ne retire rien\"\n    assert p.depiler() == \"R\", \"depiler renvoie le dessus\"\n    assert p.depiler() == 7, \"sous R, il y avait 7\"\n    assert p.est_vide(), \"tout est ressorti\"\n    return \"le contrat est honoré\"\n\nclass PileA:\n    def __init__(self): self.elements = []\n    def empiler(self, x): self.elements.append(x)\n    def depiler(self): return self.elements.pop(0)      # le plus ancien !\n    def sommet(self): return self.elements[-1]\n    def est_vide(self): return len(self.elements) == 0\n    def __len__(self): return len(self.elements)\n\nclass PileB(PileA):\n    def depiler(self): return self.elements.pop()\n    def sommet(self): return self.elements.pop()        # retire !\n\nclass PileC(PileA):\n    def empiler(self, x):\n        self.elements.append(x)\n        if len(self.elements) > 3:\n            self.elements.pop(0)                         # oublie le plus ancien\n    def depiler(self): return self.elements.pop()\n\nfor nom, classe in [(\"PileA\", PileA), (\"PileB\", PileB), (\"PileC\", PileC)]:\n    try:\n        print(nom, \":\", tester_pile(classe))\n    except AssertionError as e:\n        print(nom, \": REJETÉE,\", e)\n",[163,1864,1865,1873,1881,1889,1897,1905,1921,1935,1951,1965,1979,1987,1993,1997,2006,2025,2038,2062,2085,2109,2128,2132,2146,2160,2178,2182,2195,2204,2212,2234,2250,2265,2270,2303,2311,2326,2338],{"__ignoreMap":427},[431,1866,1867,1869,1871],{"class":433,"line":434},[431,1868,519],{"class":437},[431,1870,522],{"class":441},[431,1872,525],{"class":445},[431,1874,1875,1877,1879],{"class":433,"line":449},[431,1876,531],{"class":445},[431,1878,534],{"class":437},[431,1880,537],{"class":445},[431,1882,1883,1885,1887],{"class":433,"line":461},[431,1884,543],{"class":437},[431,1886,1246],{"class":445},[431,1888,1249],{"class":464},[431,1890,1891,1893,1895],{"class":433,"line":468},[431,1892,552],{"class":445},[431,1894,555],{"class":483},[431,1896,558],{"class":445},[431,1898,1899,1901,1903],{"class":433,"line":474},[431,1900,552],{"class":445},[431,1902,566],{"class":464},[431,1904,558],{"class":445},[431,1906,1907,1909,1911,1913,1915,1917,1919],{"class":433,"line":493},[431,1908,543],{"class":437},[431,1910,590],{"class":483},[431,1912,593],{"class":445},[431,1914,579],{"class":437},[431,1916,598],{"class":483},[431,1918,287],{"class":445},[431,1920,1286],{"class":464},[431,1922,1923,1925,1927,1929,1931,1933],{"class":433,"line":504},[431,1924,543],{"class":437},[431,1926,576],{"class":445},[431,1928,579],{"class":437},[431,1930,1309],{"class":464},[431,1932,287],{"class":445},[431,1934,1314],{"class":464},[431,1936,1937,1939,1941,1943,1945,1947,1949],{"class":433,"line":511},[431,1938,543],{"class":437},[431,1940,590],{"class":483},[431,1942,593],{"class":445},[431,1944,579],{"class":437},[431,1946,598],{"class":483},[431,1948,287],{"class":445},[431,1950,1331],{"class":464},[431,1952,1953,1955,1957,1959,1961,1963],{"class":433,"line":516},[431,1954,543],{"class":437},[431,1956,610],{"class":445},[431,1958,579],{"class":437},[431,1960,1309],{"class":464},[431,1962,287],{"class":445},[431,1964,1350],{"class":464},[431,1966,1967,1969,1971,1973,1975,1977],{"class":433,"line":528},[431,1968,543],{"class":437},[431,1970,610],{"class":445},[431,1972,579],{"class":437},[431,1974,1361],{"class":483},[431,1976,287],{"class":445},[431,1978,1366],{"class":464},[431,1980,1981,1983,1985],{"class":433,"line":540},[431,1982,543],{"class":437},[431,1984,1246],{"class":445},[431,1986,1375],{"class":464},[431,1988,1989,1991],{"class":433,"line":549},[431,1990,1380],{"class":437},[431,1992,1383],{"class":464},[431,1994,1995],{"class":433,"line":561},[431,1996,508],{"emptyLinePlaceholder":507},[431,1998,1999,2001,2004],{"class":433,"line":571},[431,2000,438],{"class":437},[431,2002,2003],{"class":441}," PileA",[431,2005,446],{"class":445},[431,2007,2008,2010,2012,2014,2017,2020,2022],{"class":433,"line":585},[431,2009,452],{"class":437},[431,2011,933],{"class":483},[431,2013,1530],{"class":445},[431,2015,2016],{"class":483},"self",[431,2018,2019],{"class":445},".elements ",[431,2021,534],{"class":437},[431,2023,2024],{"class":445}," []\n",[431,2026,2027,2029,2031,2033,2035],{"class":433,"line":605},[431,2028,452],{"class":437},[431,2030,951],{"class":441},[431,2032,1542],{"class":445},[431,2034,2016],{"class":483},[431,2036,2037],{"class":445},".elements.append(x)\n",[431,2039,2040,2042,2044,2046,2049,2051,2054,2056,2059],{"class":433,"line":617},[431,2041,452],{"class":437},[431,2043,455],{"class":441},[431,2045,1530],{"class":445},[431,2047,2048],{"class":437},"return",[431,2050,484],{"class":483},[431,2052,2053],{"class":445},".elements.pop(",[431,2055,1785],{"class":483},[431,2057,2058],{"class":445},")      ",[431,2060,2061],{"class":601},"# le plus ancien !\n",[431,2063,2064,2066,2068,2070,2072,2074,2077,2080,2082],{"class":433,"line":629},[431,2065,452],{"class":437},[431,2067,987],{"class":441},[431,2069,1530],{"class":445},[431,2071,2048],{"class":437},[431,2073,484],{"class":483},[431,2075,2076],{"class":445},".elements[",[431,2078,2079],{"class":437},"-",[431,2081,1438],{"class":483},[431,2083,2084],{"class":445},"]\n",[431,2086,2087,2089,2091,2093,2095,2097,2099,2101,2104,2106],{"class":433,"line":1019},[431,2088,452],{"class":437},[431,2090,1005],{"class":441},[431,2092,1530],{"class":445},[431,2094,2048],{"class":437},[431,2096,590],{"class":483},[431,2098,1762],{"class":445},[431,2100,2016],{"class":483},[431,2102,2103],{"class":445},".elements) ",[431,2105,579],{"class":437},[431,2107,2108],{"class":483}," 0\n",[431,2110,2111,2113,2115,2117,2119,2121,2123,2125],{"class":433,"line":1029},[431,2112,452],{"class":437},[431,2114,1024],{"class":483},[431,2116,1530],{"class":445},[431,2118,2048],{"class":437},[431,2120,590],{"class":483},[431,2122,1762],{"class":445},[431,2124,2016],{"class":483},[431,2126,2127],{"class":445},".elements)\n",[431,2129,2130],{"class":433,"line":1713},[431,2131,508],{"emptyLinePlaceholder":507},[431,2133,2134,2136,2139,2141,2143],{"class":433,"line":1720},[431,2135,438],{"class":437},[431,2137,2138],{"class":441}," PileB",[431,2140,1762],{"class":445},[431,2142,1824],{"class":441},[431,2144,2145],{"class":445},"):\n",[431,2147,2148,2150,2152,2154,2156,2158],{"class":433,"line":1725},[431,2149,452],{"class":437},[431,2151,455],{"class":441},[431,2153,1530],{"class":445},[431,2155,2048],{"class":437},[431,2157,484],{"class":483},[431,2159,501],{"class":445},[431,2161,2162,2164,2166,2168,2170,2172,2175],{"class":433,"line":1733},[431,2163,452],{"class":437},[431,2165,987],{"class":441},[431,2167,1530],{"class":445},[431,2169,2048],{"class":437},[431,2171,484],{"class":483},[431,2173,2174],{"class":445},".elements.pop()        ",[431,2176,2177],{"class":601},"# retire !\n",[431,2179,2180],{"class":433,"line":1742},[431,2181,508],{"emptyLinePlaceholder":507},[431,2183,2184,2186,2189,2191,2193],{"class":433,"line":1757},[431,2185,438],{"class":437},[431,2187,2188],{"class":441}," PileC",[431,2190,1762],{"class":445},[431,2192,1824],{"class":441},[431,2194,2145],{"class":445},[431,2196,2198,2200,2202],{"class":433,"line":2197},27,[431,2199,452],{"class":437},[431,2201,951],{"class":441},[431,2203,954],{"class":445},[431,2205,2207,2210],{"class":433,"line":2206},28,[431,2208,2209],{"class":483},"        self",[431,2211,2037],{"class":445},[431,2213,2215,2218,2220,2222,2224,2226,2229,2232],{"class":433,"line":2214},29,[431,2216,2217],{"class":437},"        if",[431,2219,590],{"class":483},[431,2221,1762],{"class":445},[431,2223,2016],{"class":483},[431,2225,2103],{"class":445},[431,2227,2228],{"class":437},">",[431,2230,2231],{"class":483}," 3",[431,2233,446],{"class":445},[431,2235,2237,2240,2242,2244,2247],{"class":433,"line":2236},30,[431,2238,2239],{"class":483},"            self",[431,2241,2053],{"class":445},[431,2243,1785],{"class":483},[431,2245,2246],{"class":445},")                         ",[431,2248,2249],{"class":601},"# oublie le plus ancien\n",[431,2251,2253,2255,2257,2259,2261,2263],{"class":433,"line":2252},31,[431,2254,452],{"class":437},[431,2256,455],{"class":441},[431,2258,1530],{"class":445},[431,2260,2048],{"class":437},[431,2262,484],{"class":483},[431,2264,501],{"class":445},[431,2266,2268],{"class":433,"line":2267},32,[431,2269,508],{"emptyLinePlaceholder":507},[431,2271,2273,2276,2279,2282,2285,2288,2291,2294,2297,2300],{"class":433,"line":2272},33,[431,2274,2275],{"class":437},"for",[431,2277,2278],{"class":445}," nom, classe ",[431,2280,2281],{"class":437},"in",[431,2283,2284],{"class":445}," [(",[431,2286,2287],{"class":464},"\"PileA\"",[431,2289,2290],{"class":445},", PileA), (",[431,2292,2293],{"class":464},"\"PileB\"",[431,2295,2296],{"class":445},", PileB), (",[431,2298,2299],{"class":464},"\"PileC\"",[431,2301,2302],{"class":445},", PileC)]:\n",[431,2304,2306,2309],{"class":433,"line":2305},34,[431,2307,2308],{"class":437},"    try",[431,2310,446],{"class":445},[431,2312,2314,2317,2320,2323],{"class":433,"line":2313},35,[431,2315,2316],{"class":483},"        print",[431,2318,2319],{"class":445},"(nom, ",[431,2321,2322],{"class":464},"\":\"",[431,2324,2325],{"class":445},", tester_pile(classe))\n",[431,2327,2329,2332,2334,2336],{"class":433,"line":2328},36,[431,2330,2331],{"class":437},"    except",[431,2333,1748],{"class":483},[431,2335,1751],{"class":437},[431,2337,1754],{"class":445},[431,2339,2341,2343,2345,2348],{"class":433,"line":2340},37,[431,2342,2316],{"class":483},[431,2344,2319],{"class":445},[431,2346,2347],{"class":464},"\": REJETÉE,\"",[431,2349,1768],{"class":445},[156,2351,2352,2354,2355,2357,2358,2360,2361,2364],{},[163,2353,1824],{}," et ",[163,2356,1838],{}," sont rejetées : deux éléments suffisent à les démasquer.\n",[163,2359,1852],{},", elle, ",[159,2362,2363],{},"passe, et reste fausse",". Le jeu de tests n'empile jamais\nquatre éléments, donc il ne voit rien.",[156,2366,2367,2368,2371,2372,2375,2376,2379,2380,2383],{},"C'est la phrase du programme de Première, rencontrée en situation : ",[159,2369,2370],{},"le succès\nd'un jeu de tests ne garantit pas la correction d'un programme."," Un test qui\npasse prouve seulement que ",[168,2373,2374],{},"les cas écrits"," passent. D'où l'importance du\n",[159,2377,2378],{},"nombre"," et du ",[159,2381,2382],{},"choix"," des cas : ici, un cas « beaucoup d'éléments »\nmanquait.",[422,2385,2387],{"className":424,"code":2386,"language":426,"meta":427,"style":427},"p = PileC()\nfor n in [1, 2, 3, 4]:\n    p.empiler(n)\nassert len(p) == 4, \"empiler quatre éléments en laisse quatre\"   # PileC échoue\n",[163,2388,2389,2399,2430,2435],{"__ignoreMap":427},[431,2390,2391,2394,2396],{"class":433,"line":434},[431,2392,2393],{"class":445},"p ",[431,2395,534],{"class":437},[431,2397,2398],{"class":445}," PileC()\n",[431,2400,2401,2403,2406,2408,2411,2413,2415,2417,2419,2422,2424,2427],{"class":433,"line":449},[431,2402,2275],{"class":437},[431,2404,2405],{"class":445}," n ",[431,2407,2281],{"class":437},[431,2409,2410],{"class":445}," [",[431,2412,1438],{"class":483},[431,2414,287],{"class":445},[431,2416,1404],{"class":483},[431,2418,287],{"class":445},[431,2420,2421],{"class":483},"3",[431,2423,287],{"class":445},[431,2425,2426],{"class":483},"4",[431,2428,2429],{"class":445},"]:\n",[431,2431,2432],{"class":433,"line":461},[431,2433,2434],{"class":445},"    p.empiler(n)\n",[431,2436,2437,2439,2441,2443,2445,2448,2450,2453],{"class":433,"line":468},[431,2438,165],{"class":437},[431,2440,590],{"class":483},[431,2442,593],{"class":445},[431,2444,579],{"class":437},[431,2446,2447],{"class":483}," 4",[431,2449,287],{"class":445},[431,2451,2452],{"class":464},"\"empiler quatre éléments en laisse quatre\"",[431,2454,2455],{"class":601},"   # PileC échoue\n",[2457,2458,2461],"card",{"icon":2459,"title":2460},"i-lucide-target","Le périmètre, c'est ce que le contrat a dit",[156,2462,2463,2465,2466,2469],{},[163,2464,1852],{}," n'est pas fautive par étourderie : elle honore un ",[159,2467,2468],{},"autre"," contrat,\ncelui d'une pile de capacité bornée, que le contrat écrit n'interdisait nulle\npart. Le périmètre d'un programme n'est pas ce que son code fait : c'est ce que\nson contrat a dit. Un contrat précis (« la pile n'a pas de limite de taille »)\naurait appelé le test qui manquait.",[1402,2471,2474,2481],{"correct":1438,"explanation":2472,"slug":2473},"Un jeu de tests ne vérifie que les cas qu'il contient. PileC passe parce qu'aucun cas n'empile plus de trois éléments : le succès d'un jeu de tests ne garantit pas la correction.","contrat-tests-assertions-c4",[1408,2475,2476],{"v-slot:question":427},[156,2477,2478,2480],{},[163,2479,1852],{}," passe le jeu de tests. Qu'en conclure ?",[1408,2482,2483],{"v-slot:choices":427},[180,2484,2485,2490,2493],{},[183,2486,2487,2489],{},[163,2488,1852],{}," est correcte",[183,2491,2492],{},"Le jeu de tests ne couvre pas le cas qui la met en défaut",[183,2494,2495],{},"Le jeu de tests est faux et doit être supprimé",[151,2497,2499],{"id":2498},"troisième-écriture-lassertion-dans-la-méthode","Troisième écriture : l'assertion dans la méthode",[156,2501,2502,2503,2509],{},"Le tableau du contrat ne dit pas ",[159,2504,2505,2506,2508],{},"ce que doit faire ",[163,2507,398],{}," sur une pile\nvide",". Deux réponses sont également correctes, à condition d'être écrites.",[180,2511,2512,2581],{},[183,2513,2514,2517,2518,2520,2521,2523,2524,2567,2570,2571,2573,2574,2577,2578,2580],{},[159,2515,2516],{},"L'interdire."," La pile non vide devient une ",[159,2519,314],{},", et ",[163,2522,308],{},"\ncommence par la vérifier :",[422,2525,2527],{"className":424,"code":2526,"language":426,"meta":427,"style":427},"def depiler(self):\n    \"\"\"Retirer l'élément du sommet et le renvoyer.\n    Précondition : la pile n'est pas vide.\"\"\"\n    assert not self.est_vide(), \"depiler exige une pile non vide\"\n    return self.elements.pop()\n",[163,2528,2529,2537,2542,2547,2559],{"__ignoreMap":427},[431,2530,2531,2533,2535],{"class":433,"line":434},[431,2532,519],{"class":437},[431,2534,455],{"class":441},[431,2536,458],{"class":445},[431,2538,2539],{"class":433,"line":449},[431,2540,2541],{"class":464},"    \"\"\"Retirer l'élément du sommet et le renvoyer.\n",[431,2543,2544],{"class":433,"line":461},[431,2545,2546],{"class":464},"    Précondition : la pile n'est pas vide.\"\"\"\n",[431,2548,2549,2551,2553,2555,2557],{"class":433,"line":468},[431,2550,543],{"class":437},[431,2552,480],{"class":437},[431,2554,484],{"class":483},[431,2556,487],{"class":445},[431,2558,490],{"class":464},[431,2560,2561,2563,2565],{"class":433,"line":474},[431,2562,1380],{"class":437},[431,2564,484],{"class":483},[431,2566,501],{"class":445},[2568,2569],"br",{},"La même précondition vaut pour ",[163,2572,402],{},". Lever une exception explicite,\ncomme le ",[163,2575,2576],{},"raise IndexError(\"pile vide\")"," de la ",[163,2579,790],{}," du cours précédent, est\nune autre façon de l'interdire : le message nomme lui aussi le contrat.",[183,2582,2583,1841,2586,1493,2588,2590],{},[159,2584,2585],{},"La définir.",[163,2587,308],{},[163,2589,1496],{}," sur une pile vide, et la\ndocumentation le dit.",[156,2592,2593,2594,2597],{},"Ce qui serait fautif, c'est de ",[159,2595,2596],{},"ne rien dire"," : le code déciderait alors à la\nplace du contrat, et personne ne saurait si le comportement obtenu était voulu.",[156,2599,2600,2601,2604,2605,2607,2608,2611,2612,2615,2616,2619,2620,2623],{},"La différence se voit dans le message d'erreur. Sans précondition écrite,\n",[163,2602,2603],{},"[].pop()"," lève ",[163,2606,360],{},", un message qui parle des\n",[159,2609,2610],{},"entrailles"," de la classe (une liste, un ",[163,2613,2614],{},"pop","). Avec l'assertion,\n",[163,2617,2618],{},"AssertionError: depiler exige une pile non vide"," parle de ",[159,2621,2622],{},"l'appel",", et\nnomme la promesse qui n'a pas été tenue.",[1502,2625,2626],{},[422,2627,2629],{"className":424,"code":2628,"language":426,"meta":427,"style":427},"class Pile:\n    def __init__(self): self.elements = []\n    def empiler(self, x): self.elements.append(x)\n    def est_vide(self): return len(self.elements) == 0\n    def depiler(self):\n        return self.elements.pop()\n\nclass PileGardee(Pile):\n    def depiler(self):\n        assert not self.est_vide(), \"depiler exige une pile non vide\"\n        return self.elements.pop()\n\nfor classe in [Pile, PileGardee]:\n    try:\n        classe().depiler()\n    except Exception as e:\n        print(classe.__name__, \"->\", type(e).__name__, \":\", e)\n",[163,2630,2631,2639,2655,2667,2689,2697,2705,2709,2722,2730,2742,2750,2754,2766,2772,2777,2788],{"__ignoreMap":427},[431,2632,2633,2635,2637],{"class":433,"line":434},[431,2634,438],{"class":437},[431,2636,442],{"class":441},[431,2638,446],{"class":445},[431,2640,2641,2643,2645,2647,2649,2651,2653],{"class":433,"line":449},[431,2642,452],{"class":437},[431,2644,933],{"class":483},[431,2646,1530],{"class":445},[431,2648,2016],{"class":483},[431,2650,2019],{"class":445},[431,2652,534],{"class":437},[431,2654,2024],{"class":445},[431,2656,2657,2659,2661,2663,2665],{"class":433,"line":461},[431,2658,452],{"class":437},[431,2660,951],{"class":441},[431,2662,1542],{"class":445},[431,2664,2016],{"class":483},[431,2666,2037],{"class":445},[431,2668,2669,2671,2673,2675,2677,2679,2681,2683,2685,2687],{"class":433,"line":468},[431,2670,452],{"class":437},[431,2672,1005],{"class":441},[431,2674,1530],{"class":445},[431,2676,2048],{"class":437},[431,2678,590],{"class":483},[431,2680,1762],{"class":445},[431,2682,2016],{"class":483},[431,2684,2103],{"class":445},[431,2686,579],{"class":437},[431,2688,2108],{"class":483},[431,2690,2691,2693,2695],{"class":433,"line":474},[431,2692,452],{"class":437},[431,2694,455],{"class":441},[431,2696,458],{"class":445},[431,2698,2699,2701,2703],{"class":433,"line":493},[431,2700,496],{"class":437},[431,2702,484],{"class":483},[431,2704,501],{"class":445},[431,2706,2707],{"class":433,"line":504},[431,2708,508],{"emptyLinePlaceholder":507},[431,2710,2711,2713,2716,2718,2720],{"class":433,"line":511},[431,2712,438],{"class":437},[431,2714,2715],{"class":441}," PileGardee",[431,2717,1762],{"class":445},[431,2719,790],{"class":441},[431,2721,2145],{"class":445},[431,2723,2724,2726,2728],{"class":433,"line":516},[431,2725,452],{"class":437},[431,2727,455],{"class":441},[431,2729,458],{"class":445},[431,2731,2732,2734,2736,2738,2740],{"class":433,"line":528},[431,2733,477],{"class":437},[431,2735,480],{"class":437},[431,2737,484],{"class":483},[431,2739,487],{"class":445},[431,2741,490],{"class":464},[431,2743,2744,2746,2748],{"class":433,"line":540},[431,2745,496],{"class":437},[431,2747,484],{"class":483},[431,2749,501],{"class":445},[431,2751,2752],{"class":433,"line":549},[431,2753,508],{"emptyLinePlaceholder":507},[431,2755,2756,2758,2761,2763],{"class":433,"line":561},[431,2757,2275],{"class":437},[431,2759,2760],{"class":445}," classe ",[431,2762,2281],{"class":437},[431,2764,2765],{"class":445}," [Pile, PileGardee]:\n",[431,2767,2768,2770],{"class":433,"line":571},[431,2769,2308],{"class":437},[431,2771,446],{"class":445},[431,2773,2774],{"class":433,"line":585},[431,2775,2776],{"class":445},"        classe().depiler()\n",[431,2778,2779,2781,2784,2786],{"class":433,"line":605},[431,2780,2331],{"class":437},[431,2782,2783],{"class":483}," Exception",[431,2785,1751],{"class":437},[431,2787,1754],{"class":445},[431,2789,2790,2792,2795,2798,2800,2803,2805,2808,2811,2813,2815,2817],{"class":433,"line":617},[431,2791,2316],{"class":483},[431,2793,2794],{"class":445},"(classe.",[431,2796,2797],{"class":483},"__name__",[431,2799,287],{"class":445},[431,2801,2802],{"class":464},"\"->\"",[431,2804,287],{"class":445},[431,2806,2807],{"class":483},"type",[431,2809,2810],{"class":445},"(e).",[431,2812,2797],{"class":483},[431,2814,287],{"class":445},[431,2816,2322],{"class":464},[431,2818,1768],{"class":445},[151,2820,2822],{"id":2821},"dedans-ou-dehors","Dedans ou dehors",[156,2824,2825,2826,2828,2829,2832,2833,251],{},"Le jeu de tests et la précondition s'écrivent tous deux avec ",[163,2827,165],{},". Ce qui\nles distingue n'est pas la syntaxe mais ",[159,2830,2831],{},"l'endroit où ils vivent",", et donc\n",[159,2834,2835],{},"qui ils mettent en cause",[257,2837,2838,2850],{},[260,2839,2840],{},[263,2841,2842,2844,2847],{},[266,2843],{},[266,2845,2846],{},"Le test",[266,2848,2849],{},"L'assertion (précondition)",[273,2851,2852,2863,2883,2896],{},[263,2853,2854,2859,2861],{},[278,2855,2856],{},[159,2857,2858],{},"Où il vit",[278,2860,739],{},[278,2862,752],{},[263,2864,2865,2870,2877],{},[278,2866,2867],{},[159,2868,2869],{},"Ce qu'il accuse",[278,2871,2872,2873,2876],{},"l'",[159,2874,2875],{},"implémentation"," : « ce code est faux »",[278,2878,2872,2879,2882],{},[159,2880,2881],{},"appelant"," : « cet appel n'avait pas le droit »",[263,2884,2885,2890,2893],{},[278,2886,2887],{},[159,2888,2889],{},"Quand il s'exécute",[278,2891,2892],{},"à la demande, pendant le développement, sur des cas choisis",[278,2894,2895],{},"à chaque appel, sur les vraies données",[263,2897,2898,2903,2905],{},[278,2899,2900],{},[159,2901,2902],{},"Part-il avec le programme ?",[278,2904,870],{},[278,2906,2907,2908,2910],{},"oui (sauf sous ",[163,2909,412],{},")",[156,2912,2913],{},"Le critère tient en une ligne :",[2915,2916,2917,2923],"blockquote",{},[156,2918,236,2919,240,2921,251],{},[159,2920,239],{},[159,2922,243],{},[156,2924,2925,2926,240,2928,251],{},"L'assertion vit ",[159,2927,247],{},[159,2929,250],{},[1402,2931,2934,2948],{"correct":1404,"explanation":2932,"slug":2933},"Placée en première ligne de depiler, cette assertion vérifie une précondition : si elle saute, c'est l'appel qui est fautif (depiler sur une pile vide), pas le code de la pile.","contrat-tests-assertions-c5",[1408,2935,2936],{"v-slot:question":427},[156,2937,2938,2939,2941,2942,2944,2945,2947],{},"Quand ",[163,2940,304],{},", première ligne de ",[163,2943,308],{},", lève une ",[163,2946,1089],{},", qui est mis en cause ?",[1408,2949,2950],{"v-slot:choices":427},[180,2951,2952,2957,2959],{},[183,2953,2954,2955],{},"L'implémentation de ",[163,2956,308],{},[183,2958,736],{},[183,2960,2961,2962,2964],{},"Le code qui a appelé ",[163,2963,308],{}," sur une pile vide",[1402,2966,2969,2982],{"correct":1785,"explanation":2967,"slug":2968},"Cette ligne vit hors de la classe et compare un résultat à ce que le contrat promet : c'est un test. S'il échoue, c'est l'implémentation de depiler qui est fausse.","contrat-tests-assertions-c6",[1408,2970,2971],{"v-slot:question":427},[156,2972,2973,2974,2976,2977,1137,2979,2981],{},"La ligne ",[163,2975,282],{},", écrite après avoir empilé ",[163,2978,555],{},[163,2980,566],{},", est…",[1408,2983,2984],{"v-slot:choices":427},[180,2985,2986,2989,2992],{},[183,2987,2988],{},"un test : elle vit dehors et accuse l'implémentation",[183,2990,2991],{},"une précondition : elle vit dedans et accuse l'appelant",[183,2993,2994],{},"une postcondition écrite dans la docstring",[2996,2997,2999,3004],"self-eval-ordering",{"slug":2998},"contrat-tests-assertions-c7",[1408,3000,3001],{"v-slot:question":427},[156,3002,3003],{},"Remettre dans l'ordre les étapes d'écriture d'une structure à partir de son contrat :",[1408,3005,3006],{"v-slot:items":427},[180,3007,3008,3011,3017,3020,3023],{},[183,3009,3010],{},"Écrire la docstring de chaque méthode",[183,3012,3013,3014,3016],{},"Traduire chaque promesse en ",[163,3015,165],{}," dans un jeu de tests",[183,3018,3019],{},"Lancer le jeu de tests sur la classe vide et constater l'échec",[183,3021,3022],{},"Écrire le corps des méthodes",[183,3024,3025],{},"Relancer le jeu de tests jusqu'à ce qu'il passe",[151,3027,367],{"id":366},[180,3029,3030,3039,3045,3053,3075],{},[183,3031,3032,1841,3035,3038],{},[159,3033,3034],{},"Tester l'implémentation au lieu du contrat.",[163,3036,3037],{},"assert p.elements == [7]","\nrejette une pile correcte rangée autrement. Le test ne passe que par les\nméthodes de l'interface.",[183,3040,3041,3044],{},[159,3042,3043],{},"Un seul élément pour tester l'ordre."," Pile et file rendent alors le même\nélément ; la propriété LIFO n'est pas éprouvée.",[183,3046,3047,3050,3051,677],{},[159,3048,3049],{},"Conclure d'un test qui passe que le code est juste."," Il prouve seulement\nque les cas écrits passent (",[163,3052,1852],{},[183,3054,3055,1841,3060,3063,3064,3067,3068,3071,3072,251],{},[159,3056,3057,3058,251],{},"Mettre des parenthèses autour d'un ",[163,3059,165],{},[163,3061,3062],{},"assert (x > 0, \"message\")","\nteste un ",[159,3065,3066],{},"tuple"," non vide, toujours vrai : l'assertion ne saute jamais.\nPython le signale d'ailleurs par un ",[163,3069,3070],{},"SyntaxWarning: assertion is always true",". Écrire ",[163,3073,3074],{},"assert x > 0, \"message\"",[183,3076,3077,3082,3083,3086],{},[159,3078,3079,3080,251],{},"Confier une vérification de sécurité à ",[163,3081,165],{}," Python lancé avec\nl'option ",[163,3084,3085],{},"-O"," ignore toutes les assertions. Elles documentent et gardent un\ncontrat entre parties d'un même programme ; elles ne filtrent pas une saisie\nmalveillante.",[151,3088,3090],{"id":3089},"pour-aller-plus-loin","Pour aller plus loin",[156,3092,3093],{},"Deux outils industrialisent le jeu de tests.",[180,3095,3096,3181],{},[183,3097,3098,3099,3102,3103,3106,3107,3110,3111,3114,3115],{},"Les ",[159,3100,3101],{},"doctests"," placent les exemples directement dans la docstring :\npremière et deuxième écritures réunies. ",[163,3104,3105],{},"python -m doctest fichier.py","\nexécute chaque ligne ",[163,3108,3109],{},">>>"," et compare son résultat à la ligne suivante. Il\nn'affiche rien quand tout passe ; l'option ",[163,3112,3113],{},"-v"," détaille chaque exemple.",[422,3116,3118],{"className":424,"code":3117,"language":426,"meta":427,"style":427},"def double(n):\n    \"\"\"Renvoyer le double de n.\n\n    >>> double(3)\n    6\n    >>> double(-2)\n    -4\n    \"\"\"\n    return 2 * n\n",[163,3119,3120,3130,3135,3139,3147,3152,3159,3164,3169],{"__ignoreMap":427},[431,3121,3122,3124,3127],{"class":433,"line":434},[431,3123,519],{"class":437},[431,3125,3126],{"class":441}," double",[431,3128,3129],{"class":445},"(n):\n",[431,3131,3132],{"class":433,"line":449},[431,3133,3134],{"class":464},"    \"\"\"Renvoyer le double de n.\n",[431,3136,3137],{"class":433,"line":461},[431,3138,508],{"emptyLinePlaceholder":507},[431,3140,3141,3144],{"class":433,"line":468},[431,3142,3143],{"class":437},"    >>> ",[431,3145,3146],{"class":464},"double(3)\n",[431,3148,3149],{"class":433,"line":474},[431,3150,3151],{"class":464},"    6\n",[431,3153,3154,3156],{"class":433,"line":493},[431,3155,3143],{"class":437},[431,3157,3158],{"class":464},"double(-2)\n",[431,3160,3161],{"class":433,"line":504},[431,3162,3163],{"class":464},"    -4\n",[431,3165,3166],{"class":433,"line":511},[431,3167,3168],{"class":464},"    \"\"\"\n",[431,3170,3171,3173,3175,3178],{"class":433,"line":516},[431,3172,1380],{"class":437},[431,3174,598],{"class":483},[431,3176,3177],{"class":437}," *",[431,3179,3180],{"class":445}," n\n",[183,3182,3183,3188,3189,3192,3193,3196,3197,3199,3200,3203,3204,3207],{},[159,3184,3185],{},[163,3186,3187],{},"pytest"," découvre tous les fichiers ",[163,3190,3191],{},"test_*.py",", exécute toutes les\nfonctions ",[163,3194,3195],{},"test_*"," qu'ils contiennent, et rapporte chaque ",[163,3198,165],{}," qui a\néchoué. ",[163,3201,3202],{},"pytest.raises(AssertionError)"," vérifie qu'un appel interdit est bien\nrefusé : c'est un test ",[168,3205,3206],{},"de"," la précondition.",[156,3209,3210,3211,3214],{},"C'est aussi le format de l'",[159,3212,3213],{},"épreuve pratique"," du baccalauréat : une\nspécification donnée, des exemples, et du code à écrire jusqu'à ce qu'ils\npassent.",[675,3216],{"code":144},[635,3218,3219],{},"html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":427,"searchDepth":449,"depth":449,"links":3221},[3222,3223,3224,3225,3226,3227,3228,3229,3230],{"id":665,"depth":449,"text":666},{"id":783,"depth":449,"text":784},{"id":1079,"depth":449,"text":1080},{"id":1474,"depth":449,"text":1475},{"id":1808,"depth":449,"text":1809},{"id":2498,"depth":449,"text":2499},{"id":2821,"depth":449,"text":2822},{"id":366,"depth":449,"text":367},{"id":3089,"depth":449,"text":3090},"Le contrat d'une structure lu du côté de qui écrit le code : la documentation qui le dit, le jeu de tests écrit avant la première ligne, l'assertion qui le garde du dedans.",{},{"title":137},[3235,3247,3258,3263,3272,3286,3298],{"slug":1406,"question":3236,"questionBody":3237,"explanation":1405,"kind":3244,"choices":3245,"correct":1404,"multi":649},"Pourquoi le test empile-t-il deux éléments avant d'appeler depiler() ?",[3238],[156,3239,1412,3240,1416,3242,1419],{},[159,3241,1415],{},[163,3243,398],{},"qcm",[1426,3246,1435],"Pour tester la performance de empiler",{"slug":1440,"question":3248,"questionBody":3249,"explanation":1439,"kind":3244,"choices":3256,"correct":1438,"multi":649},"Quel assert éprouve la promesse « sommet() ne retire rien » ?",[3250],[156,3251,1445,3252,1448,3254,1451],{},[163,3253,165],{},[163,3255,402],{},[1145,3257,1471],"assert len(p) == 2 juste après l'appel à sommet()",{"slug":1787,"question":1792,"questionBody":3259,"explanation":1786,"kind":3244,"choices":3262,"correct":1785,"multi":649},[3260],[156,3261,1792],{},[1799,1802,1805],{"slug":2473,"question":3264,"questionBody":3265,"explanation":2472,"kind":3244,"choices":3270,"correct":1438,"multi":649},"PileC passe le jeu de tests. Qu'en conclure ?",[3266],[156,3267,3268,2480],{},[163,3269,1852],{},[3271,2492,2495],"PileC est correcte",{"slug":2933,"question":3273,"questionBody":3274,"explanation":2932,"kind":3244,"choices":3283,"correct":1404,"multi":649},"Quand assert not self.est_vide(), première ligne de depiler, lève une AssertionError, qui est mis en cause ?",[3275],[156,3276,2938,3277,2941,3279,2944,3281,2947],{},[163,3278,304],{},[163,3280,308],{},[163,3282,1089],{},[3284,736,3285],"L'implémentation de depiler","Le code qui a appelé depiler sur une pile vide",{"slug":2968,"question":3287,"questionBody":3288,"explanation":2967,"kind":3244,"choices":3297,"correct":1785,"multi":649},"La ligne assert p.depiler() == \"R\", écrite après avoir empilé 7 puis \"R\", est…",[3289],[156,3290,2973,3291,2976,3293,1137,3295,2981],{},[163,3292,282],{},[163,3294,555],{},[163,3296,566],{},[2988,2991,2994],{"slug":2998,"question":3003,"questionBody":3299,"explanation":427,"kind":3302,"items":3303},[3300],[156,3301,3003],{},"ordering",[3010,3304,3019,3022,3025],"Traduire chaque promesse en assert dans un jeu de tests",{"title":3306,"description":3307},"Un contrat, trois écritures : docstring, tests, assertions","Le contrat d'une structure lu du côté de qui écrit le code : la documentation qui le dit, le jeu de tests écrit avant la première ligne, l'assertion qui le garde du dedans.","2ciFsEzpY1AUcbZ9Q6nVymbtaUS-inYLvjdgA6Uk-wc",{"id":141,"title":142,"bo":3310,"body":3311,"description":645,"eval":646,"extension":647,"icon":646,"labo":646,"meta":3632,"navigation":649,"path":650,"publie":651,"quizContext":646,"quizzes":3633,"readingTime":434,"seo":3634,"stem":655,"tp":646,"__hash__":656},[144,145,146],{"type":148,"value":3312,"toc":3625},[3313,3315,3325,3327,3371,3373,3445,3447,3477,3479,3623],[151,3314,154],{"id":153},[156,3316,3317],{},[159,3318,161,3319,166,3321,171,3323,174],{},[163,3320,165],{},[168,3322,170],{},[163,3324,165],{},[151,3326,178],{"id":177},[180,3328,3329,3335,3341,3347,3351,3357,3361],{},[183,3330,3331,188,3333,192],{},[159,3332,187],{},[163,3334,191],{},[183,3336,3337,198,3339,202],{},[159,3338,197],{},[159,3340,201],{},[183,3342,3343,210],{},[159,3344,207,3345],{},[163,3346,165],{},[183,3348,213,3349,216],{},[159,3350,170],{},[183,3352,219,3353,223,3355,227],{},[159,3354,222],{},[159,3356,226],{},[183,3358,3359,233],{},[159,3360,232],{},[183,3362,236,3363,240,3365,244,3367,240,3369,251],{},[159,3364,239],{},[159,3366,243],{},[159,3368,247],{},[159,3370,250],{},[151,3372,255],{"id":254},[257,3374,3375,3383],{},[260,3376,3377],{},[263,3378,3379,3381],{},[266,3380,268],{},[266,3382,271],{},[273,3384,3385,3399,3411,3425,3431,3437],{},[263,3386,3387,3395],{},[278,3388,3389,283,3391,287,3393],{},[163,3390,282],{},[163,3392,286],{},[163,3394,290],{},[278,3396,293,3397,297],{},[159,3398,296],{},[263,3400,3401,3407],{},[278,3402,3403,305,3405],{},[163,3404,304],{},[163,3406,308],{},[278,3408,311,3409,315],{},[159,3410,314],{},[263,3412,3413,3419],{},[278,3414,3415,323,3417],{},[163,3416,322],{},[163,3418,326],{},[278,3420,329,3421,333,3423,337],{},[159,3422,332],{},[163,3424,336],{},[263,3426,3427,3429],{},[278,3428,342],{},[278,3430,345],{},[263,3432,3433,3435],{},[278,3434,350],{},[278,3436,353],{},[263,3438,3439,3443],{},[278,3440,3441],{},[163,3442,360],{},[278,3444,363],{},[151,3446,367],{"id":366},[180,3448,3449,3453,3457,3459,3463,3469,3475],{},[183,3450,372,3451,376],{},[163,3452,375],{},[183,3454,379,3455,383],{},[159,3456,382],{},[183,3458,386],{},[183,3460,3461,392],{},[163,3462,391],{},[183,3464,395,3465,399,3467,403],{},[163,3466,398],{},[163,3468,402],{},[183,3470,406,3471,409,3473,413],{},[163,3472,165],{},[163,3474,412],{},[183,3476,416],{},[151,3478,420],{"id":419},[422,3480,3481],{"className":424,"code":425,"language":426,"meta":427,"style":427},[163,3482,3483,3491,3499,3503,3507,3519,3527,3531,3535,3543,3551,3557,3565,3573,3583,3597,3607,3617],{"__ignoreMap":427},[431,3484,3485,3487,3489],{"class":433,"line":434},[431,3486,438],{"class":437},[431,3488,442],{"class":441},[431,3490,446],{"class":445},[431,3492,3493,3495,3497],{"class":433,"line":449},[431,3494,452],{"class":437},[431,3496,455],{"class":441},[431,3498,458],{"class":445},[431,3500,3501],{"class":433,"line":461},[431,3502,465],{"class":464},[431,3504,3505],{"class":433,"line":468},[431,3506,471],{"class":464},[431,3508,3509,3511,3513,3515,3517],{"class":433,"line":474},[431,3510,477],{"class":437},[431,3512,480],{"class":437},[431,3514,484],{"class":483},[431,3516,487],{"class":445},[431,3518,490],{"class":464},[431,3520,3521,3523,3525],{"class":433,"line":493},[431,3522,496],{"class":437},[431,3524,484],{"class":483},[431,3526,501],{"class":445},[431,3528,3529],{"class":433,"line":504},[431,3530,508],{"emptyLinePlaceholder":507},[431,3532,3533],{"class":433,"line":511},[431,3534,508],{"emptyLinePlaceholder":507},[431,3536,3537,3539,3541],{"class":433,"line":516},[431,3538,519],{"class":437},[431,3540,522],{"class":441},[431,3542,525],{"class":445},[431,3544,3545,3547,3549],{"class":433,"line":528},[431,3546,531],{"class":445},[431,3548,534],{"class":437},[431,3550,537],{"class":445},[431,3552,3553,3555],{"class":433,"line":540},[431,3554,543],{"class":437},[431,3556,546],{"class":445},[431,3558,3559,3561,3563],{"class":433,"line":549},[431,3560,552],{"class":445},[431,3562,555],{"class":483},[431,3564,558],{"class":445},[431,3566,3567,3569,3571],{"class":433,"line":561},[431,3568,552],{"class":445},[431,3570,566],{"class":464},[431,3572,558],{"class":445},[431,3574,3575,3577,3579,3581],{"class":433,"line":571},[431,3576,543],{"class":437},[431,3578,576],{"class":445},[431,3580,579],{"class":437},[431,3582,582],{"class":464},[431,3584,3585,3587,3589,3591,3593,3595],{"class":433,"line":585},[431,3586,543],{"class":437},[431,3588,590],{"class":483},[431,3590,593],{"class":445},[431,3592,579],{"class":437},[431,3594,598],{"class":483},[431,3596,602],{"class":601},[431,3598,3599,3601,3603,3605],{"class":433,"line":605},[431,3600,543],{"class":437},[431,3602,610],{"class":445},[431,3604,579],{"class":437},[431,3606,582],{"class":464},[431,3608,3609,3611,3613,3615],{"class":433,"line":617},[431,3610,543],{"class":437},[431,3612,610],{"class":445},[431,3614,579],{"class":437},[431,3616,626],{"class":483},[431,3618,3619,3621],{"class":433,"line":629},[431,3620,543],{"class":437},[431,3622,546],{"class":445},[635,3624,637],{},{"title":427,"searchDepth":449,"depth":449,"links":3626},[3627,3628,3629,3630,3631],{"id":153,"depth":449,"text":154},{"id":177,"depth":449,"text":178},{"id":254,"depth":449,"text":255},{"id":366,"depth":449,"text":367},{"id":419,"depth":449,"text":420},{},[],{"title":142,"description":654},1791681197070]