javascript tome v - tests conditionnels
Transcription
javascript tome v - tests conditionnels
Petit survol des tests conditionnels Po u r D é b u t e r J AVA S C R I P T V O L . I I I J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga +243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818 Les tests conditionnels sont la base de toute programmation intelligente (Intelligence Artificielle = AI, programmation en logique, logique floue ou fuzzy logic, heuristique…). Ils sont aussi souvent la cause de beaucoup des « erreurs de temps d’exécution » associées aux « erreurs de logic ». En effet, il existe plusieurs niveaux d’erreurs en programmation : 1. Quand le problème est mal conçu : « erreur [du temps] de conception ». 2. Quand le problème est mal présenté à l’informaticien ou que ce dernier le comprend de travers : erreur de… 3. Quand le problème est mal analysé : « erreur [du temps] d’analyse ». 4. Le problème est bien présenté et bien compris et bien analysé, mais on utilise une logique inappropriée pour façonner les instructions ou on les positionne mal : « Erreur [du temps] de programmation ». 5. On encode mal : on additionne au lieu par exemple de multiplier, et le test alpha se fait avec pas assez de données représentatifs et on ne dépiste donc pas l’erreur : « Erreur d’encodage » J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV a. 2 + 2 = 2 * 2 = 6 – 2 = 8 / 2 = rac2(16) = log(1e4)… 6. « Erreur du temps d’exécution » = résultats inattendus : a. On divise par zéro ou par une variable ayant la valeur zéro, ou par une expression donnant le résultat zéro, alors la machine ou le programme ... (comportement imprévisible). b. Racine carré d’un nombre négatif… c. « Erreur de branchement » qui à elle seule constitue un type distinct d’erreur… Le branchement peut 1. être erratique ou 2. être intempestif par exemple sans se baser sur le résultat d’un test conditionel préalable. d. Boucles interminables, insortables… 7. « Erreur de logique » : on conclut que quelqu’un est aveugle simplement parce qu’il mandie dans la rue les yeux fermés, ou qu’il est mort tout simplement parcequ’il est en arrêt respiratoire ou cardio-respiratoire... 8. Ainsi de suite, patati patata, etceteri etcetera etcetiroble, buna ye buna, bongo na bongo, and so on… En ce qui concerne les instructions conditrionnelles « if », il n’est pas seulement question de connaître et comprendre leur syntaxe qui du reste est très facile, mais le plus important est de savoir les appliquer à bon escient et dans un contexte précis. Quelques cas pièges très faciles à se figurer : I. Code inaccessible (qui ne sera jamais exécuté) : a. Par suite d’une condition exclusive 1) Conflit de conditions 2) Condition contraire à un « if » englobant 3) Combinaison ambiguë 4) Condition non nécessaire à analyser Tests conditionnels -2/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu 5) 6) II. JavaScript Tome-IV Par instruction bornante : return Par instruction bornante : break Mauvais branchement : a. Si vieillard => retraiter… b. Si vieillard mais encore plus fort et plus compétant que certains jeunes => conserver absolument… Voyns les détails de ce qui précède : I. Code inaccessible. Imaginez que le code inaccessible soit l’essentiel pour lequel vous avez écrit le probramme ¿ Ceci peut arriver par : a. Par suite d’une condition exclusive 1) Conflit de conditions <script type="text/javascript"> "use strict"; for(let age=14;age<=21;age++) { if(age>20 && age<15){ /**/ alert("JAMAIS EXÉCUTÉ!"); } else console.log("TOUJOURS EXÉCUTÉ :",age); } </script> Tests conditionnels -3/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu 2) JavaScript Tome-IV Condition contraire à un « if » englobant <script type="text/javascript"> "use strict"; let age=30; if(age>20 && age<30){ console.log("entre 20 et 30"); if(age>=30)alert("JAMAIS EXÉCUTÉ!"); } else if(age>=30)console.log("Sup == 30!"); </script> 3) Condition ambiguë <script type="text/javascript"> "use strict"; let t=""; for(let age=10;age<=40;age+=5){ if(age>=20 || age<=30){ ///// TOUJOURS EXÉCUTÉ /**/ /**/ t+="TOUJOURS EXÉCUTÉ! "+ /**/ "age>=20 || age<=30 : "+age; Tests conditionnels -4/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV /**/ /**/ if(age>=20 && age<=30)t+=" *"; /**/ t+="\n" /**/ ///// TOUJOURS EXÉCUTÉ } else { // JAMAIS EXÉCUTÉ! if(age<20)console.log(age, "Inf 20!"); if(age>30)console.log(age, "Sup 30!"); } } console.log(t); </script> 4) Condition non nécessaire à analyser <script type="text/javascript"> "use strict"; let mort=true, respire=true; console.log(`mort = ${mort} ; respire = ${respire}`); if(mort || respire){ console.log("Il est Mort!"); } if(respire || mort){ console.log("Il Respire!"); } if(mort)console.log("Il est mort"); if(respire)console.log("Il Respire"); if(!mort)console.log("Il n'est pas mort!"); if(!respire)console.log("Ne Respire pas!"); </script> Tests conditionnels -5/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu 5) JavaScript Tome-IV Par instruction bornante : return <script type="text/javascript"> "use strict"; let f = _ => { return null; console.log("Rescapé!"); } let r=f(); console.log(r); </script> 6) Par instruction bornante : break S’il a 10 ans on n’a pas besoin d’autres informations, S’il a 20 ans on aura beaoin des infos de 20 et de 10 ans ; S’il a 30 ans on aura besoin des infors de 10, 20 et 30 ans. <script type="text/javascript"> "use strict"; let age=30; switch(age) { case(30): console.log("Tous 30 ans et moins"); case(20): console.log("Tous 20 ans et moins"); case(10): Tests conditionnels -6/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log("Tous 10 ans et moins"); } </script> Avec un « break » intempestif () on manquera les informations et les actions des âges inférieurs. <script type="text/javascript"> "use strict"; let age=30; switch(age) { case(30): console.log("Tous 30 ans et moins"); break; console.log("N’exécutera jamais") ; console.log("ni la suite") ; case(20): console.log("Tous 20 ans et moins"); case(10): console.log("Tous 10 ans et moins"); } </script> II. Mauvais branchement : a. Si vieillard => retraiter… b. Si vieillard mais encore plus fort et plus compétant que certains jeunes => conserver absolument… <script type="text/javascript"> "use strict"; let age=70, fort=true; if(age>=70) console.log("Bon pour retraite"); Tests conditionnels -7/25jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV if(age>=70 && fort) console.log("Mais doit continuer"); </script> Un « else » ici change tout le fonctionnement. Le: if(age>=70 && fort) ne sera plus jamais évalué si « âge >= 70 ans » pour savoir s’il est quand-même encore fort. Ça devient une condition absolue. <script type="text/javascript"> "use strict"; let age=70, fort=true; if(age>=70) console.log("Bon pour retraite"); else if(age>=70 && fort) console.log("Mais doit continuer"); </script> Souvent, c’est le mauvais usage du « else » qui conduit au désastre. <script type="text/javascript"> "use strict"; for (let age = 10; age <= 40; age += 5) { if (age >= 20) { console.log('Majeur', age); } else { // Tout age < 20; console.log('age < 20 :', age); if (age > 30) { /*****/ console.log('JAMAIS EXÉCUTÉ'); } } Tests conditionnels -8/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu } </script> JavaScript Tome-IV Si on sort le bloc suivant en dehors du bloc « else » if (age > 25) { /*****/ console.log('age > 30',age); } les âges supérieurs à 25 ans seront vérifiés deux fois : <script type="text/javascript"> "use strict"; for (let age = 10; age <= 40; age += 5) { if (age >= 20) { console.log('Majeur', age); } else { // Tout age < 20; console.log('age < 20 :', age); } if (age > 25) { console.log('... age > 30 :',age); } } </script> Tests conditionnels -9/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV La modification suivante aussi créera une partie de code qui ne sera jamais executée. <script type="text/javascript"> "use strict"; for (let age = 10; age <= 40; age += 5) { if (age >= 20) { console.log('Majeur', age); } else if (age<20) { // Tout age < 20; console.log('age < 20 :', age); } else { /*****/ console.log('JAMAIS EXÉCUTÉ'); } } </script> Les règles d’utilisation du test conditionnel « if » sont les suivantes : 1. L’instruction ou bloc d’instructions liée à la condition « if » (celle qui vient juste après ce test et non séparée par une ponctuation), est exécutée si la condition est vérifiée « true ». Sinon, cette instruction est ignorée et l’exécution passe à la première Tests conditionnels -10/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV autre instruction qui la suit, ou un « else ». Si c’est un criminel, sa place est en prison. Ici on fait abstraction de l’attitude à adopter s’il n’est pas un criminel, la condition étant normale. <script type="text/javascript"> "use strict"; let criminel=true; if (criminel) { console.log( `« criminel = ${criminel} » => `+ `foutre en prison!`); } </script> 2. Si la condition testée avec « if » autorise une alternative, on la fait suivre d’un « else »(« sinon » en français). Dans l’exemple qui suit on considère que quand un criminel n’est pas inoffensif, il est d’office dangereux : quand « criminel » et « dangereux » sont tous les deux cochés, c’est « dangereux » qui prime puisque c’est la condition testée et sa validation exclut l’exécution du « else » associé. S’il n’est pas « dangereux » le « else » est d’office exécuté, qui qualifie l’individu de « inoffensif ». Dans la logique de cet exemple, quand un individu n’est pas coché comme « criminel », même s’il est « dangereux », il est considéré comme « légal » et « loyal », puisque les aspects « dangereux » et « inoffensif » ne sont testés que quand l’individu est coché comme « criminel ». Tests conditionnels -11/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <form name="frm" action="javascript:f()"> Criminel <input name="crm" type="checkbox"><br> Dangereux <input name="dgr" type="checkbox"><br> Inoffensif <input name="ifv" type="checkbox"><br> <input type="submit" value="GO"> </form> <script type="text/javascript"> "use strict"; let f = _ => { const criminel = frm.crm.checked, dangereux = frm.dgr.checked, inoffensif = frm.ifv.checked; if (criminel) { console.log(`criminel = ${criminel}`); if(dangereux) { console.log( `dangereux = ${dangereux}\n=> ` + `foutre en prison!` ); } else { console.log( `inofensif = ${inoffensif}\n=> ` + `Rééduquer!` ); } } else console.log("Individu Légal & loyal"); }; </script> Tests conditionnels -12/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Les deux ici sont identiques Pas tout à fait vrai ! Modifions un tout petit peu ce programme : <form name="frm" action="javascript:f()"> Criminel <input name="crm" type="checkbox"><br> Dangereux <input name="dgr" type="checkbox"><br> Inoffensif <input name="ifv" type="checkbox"><br> <input type="submit" value="GO"> </form> <script type="text/javascript"> "use strict"; let f = _ => { const criminel = frm.crm.checked, dangereux = frm.dgr.checked, inoffensif = frm.ifv.checked; if (criminel || !inoffensif) { /*******/ console.log(`criminel = ${criminel}`); if(dangereux) { console.log( `dangereux = ${dangereux}\n=> ` + Tests conditionnels -13/25jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV `foutre en prison!` ); } else { console.log( `inofensif = ${inoffensif}\n=> ` + `Rééduquer!` ); } } else console.log("Individu Légal & loyal"); }; </script> Quand « inoffensif » n’est pas cochée (peut-être par manque d’information et non pas seulement que la personne est « criminel » ou « dangereux »). Mais dans ce programme, quand la case « inoffensif » n’est pas cochée (ligne 14), la personne est autoùmatiquement mis au rang (alternatif) de « criminel ». Donc même s’il n’est pas dangereux, elle est automatquement assimilée à un « criminel » « à rééduquer ». Vous voyez comment la logique du programme a changé du tout au tout, c’est une des raisons que quand vous lisez le « what’s new » des Tests conditionnels -14/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV logiciels, on vous dit « meilleure prise en charge de… ». Dernière modification que nous étudierons ensemble : On teste explicitement la « inoffensivité » en dehors du test de condition de « criminel », donc « inoffensif » on teste soit que la personne est « criminel », soit qu’elle n’est pas « inoffensif ». Si la case n’est pas explicitement cochée, c’est que la personne n’est pas inoffensive. Et on spécifie une action au cas où la personne est cochée « criminel » mais pas explicitement « dangereux ». <form name="frm" action="javascript:f()"> Criminel <input name="crm" type="checkbox"><br> Dangereux <input name="dgr" type="checkbox"><br> Inoffensif <input name="ifv" type="checkbox"><br> <input type="submit" value="GO"> </form> <script type="text/javascript"> "use strict"; let f = _ => { const criminel = frm.crm.checked, dangereux = frm.dgr.checked, inoffensif = frm.ifv.checked; if (criminel) { console.log(`criminel = ${criminel}`); if(dangereux) { console.log( `dangereux = ${dangereux}\n=> ` + `Foutre en prison!` ); } else console.log ( /**Non dangereux**/ `dangereux = ${dangereux}\n=> ` + `Cachot de longue durée!` ); } else if(!inoffensif) { console.log( `inofensif = ${inoffensif}\n=> ` + `Rééduquer!` ); } else console.log("Individu Légal & loyal"); Tests conditionnels -15/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu }; </script> JavaScript Tome-IV Ici l’individu n’est légal que quand il n’est pas crimiel et qu’il est inoffensif : Tests conditionnels -16/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Toute dernière modification : on supprime le else de else if(!inoffensif) { « inoffensif » n’a donc plus aucun lien avec « criminel » : <form name="frm" action="javascript:f()"> Criminel <input name="crm" type="checkbox"><br> Dangereux <input name="dgr" type="checkbox"><br> Inoffensif <input name="ifv" type="checkbox"><br> <input type="submit" value="GO"> </form> <script type="text/javascript"> "use strict"; let f = _ => { const criminel = frm.crm.checked, dangereux = frm.dgr.checked, inoffensif = frm.ifv.checked; if (criminel) { console.log(`criminel = ${criminel}`); if(dangereux) { console.log( `dangereux = ${dangereux}\n=> ` + `Foutre en prison!` ); } else console.log ( /**Non dangereux**/ `dangereux = ${dangereux}\n=> ` + `Cachot de longue durée!` ); } if(!inoffensif) { /**Non Innffensif**/ console.log( `inofensif = ${inoffensif}\n=> ` + `Rééduquer!` ); } else console.log("Individu Légal & loyal"); Tests conditionnels -17/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu }; </script> JavaScript Tome-IV Ici l’individu est légal à chaque fois qu’il est coché inoffensif : Voyez-bien ci-dessous : Tests conditionnels -18/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Le « else » aussi peut être composé et avoir ses propres alternatives : <form name="frm" action="javascript:f()"> Criminel <input name="crm" type="checkbox"><br> Dangereux <input name="dgr" type="checkbox"><br> Inoffensif <input name="ifv" type="checkbox"><br> Age <input name="age" placeholder="Age" style='width:30pt'><br> <input type="submit" value="GO"> </form> <script type="text/javascript"> "use strict"; let f = _ => { const criminel = frm.crm.checked, dangereux = frm.dgr.checked, inoffensif = frm.ifv.checked, age = frm.age.value; if (criminel) { console.log(`criminel = ${criminel}`); if(dangereux) { console.log( `dangereux = ${dangereux}\n=> ` + `Foutre en prison!` ); } else console.log ( /**Non dangereux**/ `dangereux = ${dangereux}\n=> ` + `Cachot de longue durée!` ); } else if(!inoffensif) { /**Non Innffensif**/ if(age>=50)console.log( `age = ${age} >= 50\n=> ` + `inofensif = ${inoffensif}\n=> ` + `Maison de retraite!` ); else if(age>=20)console.log( Tests conditionnels -19/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV `age = ${age} >= 20\n=> ` + `inofensif = ${inoffensif}\n=> ` + `Travaux forcés!` ); else { console.log(`age = ${age}< 20\n=> ` + `inofensif = ${inoffensif}\n=> ` + `Travaux forcés!` ); } } else console.log("Individu Légal & loyal"); }; </script> Sanction même quand on n’est pas sûr de la non inoffensivité : Tests conditionnels -20/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Il faut donc être très prudent avec les tests conditionnels pour pouvoir respecter la logique initiale de votre programme. La moindre erreur peut conduire à un fonctionnement erroné et erratique du programme, au mnimum égarer l’utilisateur. C’est pour cela qu’il faut plusieurs tests de toutes sortes avant de garantir que le programme fonctionne comme on l’a conçu (encore faut-il qu’il soit bien conçu, de façon claire, univoque et sans ambiguité), comme pour lancer un nouveau médicament sur le marché. C’est le rôle des béta-tests [à large échelle] pour dépister les incohérences. La façon dont vous formulez (d’abord le besoin, et ensuite) le test de condition, mais aussi la position [relative, dans l’ensemble du programme] à laquelle vous placez votre test mais aussi la façon dont les différents tests s’enchaînent, et la façon dont ils sont liés (avec ou sans else, l’un imbriqué dans l’autre ou non)… sont déterminantes et constituent l’art de programmer l’intelligence. La L O GIQ U E FL OU E = FUZZY L O GIC : À ce qui précède, il faut ajouter la logique floue. Par exemple un programme doit utiliser les deux données, à savoir « la personne ne resTests conditionnels -21/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV pire pas » et « elle est morte (absence de tous les autres signes vitaux) », mais on manque l’une des données : Si quelqu’un est mort, on sait qu’elle ne respire pas, on peut donc se passer de la première information pour entreprendre l’action appropriée pour une personne morte et qui ne respire pas (par exemple pas besoin d’apport d’oxygène et préparation à l’inhumation). L’absence ou la disponibilité de cette premièmre information ne modifie rien. Mais si la personne ne respire pas, cela ne sifnifie pas que la personne est décédée, la deuxième information reste donc absolument indispensable pour la conclusion finale. La personne est peut-être seulement en arrêt respiratoire et on peut la réanimer, l’apport d’oxygène est donc indispensable. De même, si la personne respire, alors elle n’est pas décédée, et donc la deuxième information n’est pas utile. Ni besoin d’apport d’oxygène [pour cet exemple didactique seulement], ni besoin de préparer l’inhumation. Kinshasa, le 4 avril 2019 (10:47:07 PM). Mots-clés : logique floue, fuzzy logic portée, tests conditionnels, programmation intelligente, logique, floue, fuzzy, Intelligence Artificielle, Artificial Intelligence, AI, erreurs du temps d’exécution, erreurs de logic, erreur de conception, erreur du temps d’analyse, erreur d’analyse, erreur du temps de conception, Erreur de programmation, Erreur du temps de programmation, Erreur du temps d’encodage, Erreur Tests conditionnels -22/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV d’encodage, Erreur du temps d’exécution, Erreur de branchement, instruction bornante , Conflit de conditions, Combinaison ambiguë, javascript, ecmascript DIASOLUKA Nz. Luyalu Docteur en Médecine, Chirurgie & Accouchements (1977), CNOM : 0866 - Spécialiste en ophtalmologie (1980) Études humanités : Scientifique - Mathématiques & Physique. Informaticien-amateur, Programmeur et WebMaster. Chercheur indépendant, autonome et autofinancé, bénévole, sans aucun conflit d’intérêt ou liens d'intérêts ou contrainte promotionnelle avec qui qu’il soit ou quelqu’organisme ou institution / organisation que ce soit, étatique, paraétatique ou privé, industriel ou commercial en relation avec le sujet présenté. +243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818 [email protected] Autre Lecture : https://www.scribd.com/document/374738470/Le-Plus-Grand-Secret-de-LaCreation D’autres publications pouvant aussi intéresser : • https://www.scribd.com/document/377036251/Le-Dosage-DesMedicaments-en-Cac-Cas • https://www.scribd.com/document/377035454/Le-Hasard-DesThermometres-Non-contact-a-Infrarouge Tests conditionnels -23/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV • https://www.scribd.com/document/376222482/PetiteIntroduction-Aux-Fonctions-JavaScript • https://www.scribd.com/document/376221919/La-Foi-en-JesusChrist-Pour-Quoi-Faire • https://www.scribd.com/document/375689778/Lacuite-visuelleangulaire • https://www.scribd.com/document/375349851/La-variable-This • https://www.scribd.com/document/375024162/FonctionsImbriquees-en-JS • https://www.scribd.com/document/374789297/Format-InterneDes-Objets-JavaScript • https://www.scribd.com/document/374788758/Iterations-enJavaScript • https://www.scribd.com/document/374738470/Le-Plus-GrandSecret-de-La-Creation • https://www.scribd.com/document/374597969/NouvelleFormule-d-IMC-indice-de-doduite-Selon-Dr-Diasoluka • https://www.scribd.com/document/373847209/PropertyDescriptors • https://www.scribd.com/document/373833282/l-Objet-GlobalWindow • https://www.scribd.com/document/372665249/Javascript-TomeII • https://www.scribd.com/document/355291488/motilite-oculaire2 • https://www.scribd.com/document/355291239/motilite-oculaireI • https://www.scribd.com/document/355290248/Script-dAnalyses-Des-Reflexes-Pupillomoteurs • https://www.scribd.com/document/321168468/RenseignementsId-et-Anthropometriques • https://www.scribd.com/document/320856721/Emission-31-Jul2016 • https://www.scribd.com/document/318182982/ComplicationVisuelle-du-Traitement-de-La-Malaria Tests conditionnels -24/25- jeudi, 4. avril 2019 (10:47 ) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV • https://www.scribd.com/document/318180637/Rapport-EntreOxymetrie-Et-Type-Respiration • https://www.scribd.com/document/315746265/ClassificationDes-Medicaments • https://www.scribd.com/document/315745909/IncongruencesHeresies-et-Heterodoxies-de-la-Notion-de-Laboratoire • https://www.scribd.com/document/315745725/Rapport-EntreOxymetrie-Et-Type-Respiration Tests conditionnels -25/25- jeudi, 4. avril 2019 (10:47 )