<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Classes et programmation objet</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Vocabulaire de la programmation objet en Python :<br/>
classes, attributs, méthodes, objets (instances),<br/>
constructeur <code>__init__</code>, accès aux attributs et<br/>
méthodes, premiers exemples (Point, Voiture,<br/>
Pile). Lien avec les structures de données.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q01 : Notion de classe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En programmation orientée objet, qu'est-ce<br/>
qu'une <strong>classe</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une analogie classique : la classe<br/>
est comparable à un moule à<br/>
gâteaux ; les objets, ses instances,<br/>
sont les gâteaux fabriqués avec ce<br/>
moule. Tous les gâteaux partagent<br/>
la même forme (les méthodes), mais<br/>
chacun peut avoir sa propre<br/>
garniture (ses attributs).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un modèle ou « plan » qui décrit la structure (les attributs) et le comportement (les méthodes) d'objets de même nature</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La classe constitue<br/>
l'abstraction. Les objets<br/>
concrets sont les <strong>instances</strong><br/>
de cette classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier source Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un fichier source Python est un<br/>
<strong>module</strong>, pas une classe. Un<br/>
module peut d'ailleurs contenir<br/>
plusieurs classes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type particulier d'erreur Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une classe n'a aucun rapport avec<br/>
une erreur. Les erreurs sont<br/>
plutôt signalées par des<br/>
exceptions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une simple variable du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une classe est bien plus qu'une<br/>
variable : c'est un modèle qui<br/>
décrit la structure et le<br/>
comportement d'objets de même<br/>
nature, comme expliqué dans la<br/>
bonne réponse.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q02 : Notion d'objet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>objet</strong> (ou<br/>
<strong>instance</strong>) d'une classe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En Python, <strong>tout est un objet</strong> :<br/>
les entiers, les chaînes, les<br/>
listes, les fonctions, voire les<br/>
classes elles-mêmes sont des<br/>
instances de classes prédéfinies.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une réalisation concrète d'une classe, possédant ses propres valeurs d'attributs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise indifféremment les<br/>
mots « objet » et « instance ».<br/>
À partir d'une classe <code>Voiture</code>,<br/>
on peut créer plusieurs objets<br/>
<code>Voiture</code> distincts, chacun avec<br/>
ses propres caractéristiques.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un commentaire inséré dans le code source</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les commentaires sont précédés<br/>
du caractère <code>#</code> en Python et<br/>
n'ont aucun effet à<br/>
l'exécution. Un objet, en<br/>
revanche, est manipulé pendant<br/>
l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier de configuration du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un objet est une entité<br/>
créée à l'exécution à partir<br/>
d'une classe, et non un fichier<br/>
stocké sur le disque.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type primitif comme un entier ou un flottant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un objet est créé à partir<br/>
d'une classe, généralement<br/>
définie par le programmeur.<br/>
Cela dit, en Python, les<br/>
entiers et les flottants sont<br/>
eux-mêmes des objets, instances<br/>
de classes prédéfinies.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q03 : Attribut</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>attribut</strong> d'une<br/>
classe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour une classe <code>Voiture</code>, des<br/>
attributs typiques pourraient<br/>
être : <code>marque</code>, <code>modele</code>,<br/>
<code>couleur</code>, <code>vitesse</code>. Chaque<br/>
voiture aura ses propres valeurs<br/>
pour chacun de ces attributs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction définie à l'intérieur de la classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond à<br/>
une <strong>méthode</strong>, et non à un<br/>
attribut. Les méthodes<br/>
définissent le comportement,<br/>
les attributs représentent les<br/>
données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un module de la bibliothèque Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un module est un fichier<br/>
Python, et non un attribut.<br/>
Les attributs appartiennent à<br/>
des objets.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une donnée propre à un objet, par exemple le <code>nom</code> ou l'<code>age</code> d'une <code>Personne</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les attributs caractérisent<br/>
l'<strong>état</strong> d'un objet. Chaque<br/>
instance possède ses propres<br/>
valeurs d'attributs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type particulier de boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les boucles relèvent du<br/>
contrôle de flux, pas des<br/>
objets. Un attribut est un<br/>
composant d'un objet.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q04 : Méthode</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>méthode</strong> d'une<br/>
classe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour la classe <code>Voiture</code>, des<br/>
méthodes typiques pourraient<br/>
être : <code>accelerer</code>, <code>freiner</code>,<br/>
<code>afficher</code>. Elles agissent<br/>
directement sur l'état de l'objet<br/>
par l'intermédiaire de <code>self</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une fonction définie dans la classe, qui peut accéder aux attributs des instances et agir sur eux</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les méthodes définissent le<br/>
<strong>comportement</strong> des objets.<br/>
Par convention, leur premier<br/>
paramètre se nomme <code>self</code> et<br/>
désigne l'instance sur<br/>
laquelle la méthode est<br/>
appelée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier dédié aux tests automatisés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les fichiers de tests<br/>
contiennent typiquement des<br/>
fonctions de test. Une méthode,<br/>
elle, est une fonction définie<br/>
au sein d'une classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un attribut un peu particulier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une méthode est en réalité une<br/>
fonction, et non un attribut.<br/>
Les méthodes définissent le<br/>
comportement des objets, les<br/>
attributs définissent leur<br/>
état.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type de variable particulier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une méthode n'est pas une<br/>
variable, mais une fonction<br/>
attachée à une classe.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q05 : Définir une classe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la syntaxe Python correcte<br/>
pour <strong>définir</strong> une classe <code>Voiture</code><br/>
vide ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Conventions Python : les noms de<br/>
classes s'écrivent en<br/>
<strong>CamelCase</strong> (<code>Voiture</code>,<br/>
<code>MaSuperClasse</code>), tandis que les<br/>
noms de fonctions et de variables<br/>
s'écrivent en <strong>snake_case</strong><br/>
(<code>ma_fonction</code>, <code>ma_variable</code>).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>class Voiture:
    pass</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise le mot-clé <code>class</code>,<br/>
puis le nom de la classe (par<br/>
convention en CamelCase),<br/>
suivi de deux-points et d'un<br/>
corps indenté. L'instruction<br/>
<code>pass</code> permet de signaler un<br/>
corps vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>new class Voiture {}</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe correspond à<br/>
Java ou à C++, mais pas à<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>Voiture = class()</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe n'existe pas en<br/>
Python. La définition d'une<br/>
classe se fait avec le mot-clé<br/>
<code>class</code> suivi du nom de la<br/>
classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def Voiture():
    pass</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le mot-clé <code>def</code> introduit une<br/>
<strong>fonction</strong>, et non une<br/>
classe. Pour une classe, il<br/>
faut utiliser <code>class</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q06 : Créer une instance</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment <strong>crée-t-on une instance</strong> de<br/>
la classe <code>Voiture</code> en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une distinction subtile : le nom<br/>
<code>Voiture</code> désigne la classe<br/>
elle-même (un objet de type<br/>
classe), tandis que <code>Voiture()</code><br/>
désigne une instance qu'on vient<br/>
de créer.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>v = new Voiture()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le mot-clé <code>new</code> n'existe pas<br/>
en Python. Cette syntaxe est<br/>
utilisée en Java, en JavaScript<br/>
ou en C++.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>v = create Voiture</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La syntaxe <code>create</code> n'existe<br/>
pas en Python. La création<br/>
d'une instance se fait<br/>
simplement en appelant la<br/>
classe avec des parenthèses.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>v = Voiture</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans les parenthèses, la<br/>
variable <code>v</code> reçoit la classe<br/>
elle-même, et non une instance.<br/>
Pour créer un objet, il faut<br/>
appeler la classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>v = Voiture()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On appelle la classe comme<br/>
une fonction. Cet appel<br/>
déclenche le constructeur<br/>
(<code>__init__</code>, s'il est défini)<br/>
et renvoie le nouvel objet<br/>
créé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q07 : Accéder à un attribut</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Si <code>v</code> est une instance de la classe<br/>
<code>Voiture</code> possédant un attribut<br/>
<code>marque</code>, comment lit-on la valeur de<br/>
cet attribut ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La notation pointée est la<br/>
syntaxe standard et la plus<br/>
lisible pour accéder aux attributs<br/>
comme aux méthodes d'un objet.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec la notation <code>v.marque</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La notation pointée permet<br/>
d'accéder aux attributs d'un<br/>
objet. Elle est aussi utilisée<br/>
pour appeler les méthodes :<br/>
<code>v.demarrer()</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la notation <code>v-&gt;marque</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est utilisée en<br/>
C++ ou en PHP, mais pas en<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec un appel <code>get(v, marque)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une fonction <code>getattr(v,<br/>
"marque")</code> existe en Python,<br/>
mais on lui préfère<br/>
systématiquement la notation<br/>
pointée, plus simple et plus<br/>
lisible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la notation <code>v["marque"]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe sert à accéder<br/>
à une valeur dans un<br/>
dictionnaire ou à un élément<br/>
d'une liste, et non à un<br/>
attribut d'objet.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q08 : Le paramètre self</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert le paramètre <strong><code>self</code></strong><br/>
dans les méthodes d'une classe Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La convention est forte mais non<br/>
obligatoire. Le paramètre<br/>
pourrait techniquement s'appeler<br/>
autrement, mais ce serait<br/>
vivement déconseillé. En Java ou<br/>
en C++, le rôle équivalent est<br/>
tenu par <code>this</code>, qui est<br/>
implicite.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>C'est une variable globale du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>self</code> est un paramètre local<br/>
à chaque méthode, et non une<br/>
variable globale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il s'agit d'un mot-clé réservé sans signification particulière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nom <code>self</code> n'est pas un<br/>
mot-clé réservé. C'est un<br/>
paramètre comme un autre,<br/>
utilisé par convention pour<br/>
désigner l'instance courante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il fait référence à la classe parente</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour faire référence à la<br/>
classe parente, on utilise la<br/>
fonction <code>super()</code>. Le<br/>
paramètre <code>self</code> désigne<br/>
l'instance, et non une<br/>
classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il représente l'instance courante sur laquelle la méthode est appelée. Il permet d'accéder aux attributs et aux autres méthodes de l'objet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Par convention en Python, on<br/>
nomme <code>self</code> le premier<br/>
paramètre des méthodes.<br/>
Lorsqu'on écrit<br/>
<code>v.demarrer()</code>, Python<br/>
transmet automatiquement <code>v</code><br/>
comme paramètre <code>self</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q09 : La méthode `__init__`</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le rôle de la méthode<br/>
spéciale <strong><code>__init__</code></strong> d'une classe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention : les noms encadrés de<br/>
doubles soulignés (<code>__nom__</code>)<br/>
désignent des méthodes spéciales<br/>
en Python, comme <code>__init__</code>,<br/>
<code>__str__</code> ou <code>__len__</code>. Parmi<br/>
elles, <code>__init__</code> est de loin la<br/>
plus utilisée.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Initialiser les attributs d'un nouvel objet au moment de sa création (rôle de constructeur)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthode est appelée<br/>
automatiquement au moment de<br/>
l'instanciation. C'est dans<br/>
son corps qu'on définit<br/>
l'état initial de l'objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Détruire l'objet en fin de vie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La destruction d'un objet est<br/>
plutôt prise en charge par la<br/>
méthode spéciale <code>__del__</code>,<br/>
rarement utilisée en Python en<br/>
raison du ramasse-miettes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Initialiser l'ensemble du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>__init__</code> est<br/>
locale à la classe : elle ne<br/>
concerne que la création des<br/>
instances de cette classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Importer un module dans le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'import de modules se fait<br/>
avec l'instruction <code>import</code>,<br/>
et n'a aucun rapport avec<br/>
<code>__init__</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q10 : Trace simple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produit ce code ?<br/>
<pre><code>class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)
print(p.x, p.y)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Voici le motif de base d'une<br/>
classe simple : une méthode<br/>
<code>__init__</code> qui prend les valeurs<br/>
initiales en paramètres et les<br/>
stocke dans <code>self</code> à l'aide<br/>
d'instructions de la forme<br/>
<code>self.attr = ...</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>Point(3, 4)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'instruction <code>print(p.x,<br/>
p.y)</code> n'affiche pas l'objet<br/>
tout entier, mais<br/>
uniquement la valeur de ses<br/>
deux attributs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche <code>3 4</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'expression <code>Point(3, 4)</code><br/>
crée une instance ; la<br/>
méthode <code>__init__</code> initialise<br/>
les attributs <code>self.x = 3</code> et<br/>
<code>self.y = 4</code>. La fonction<br/>
<code>print</code> affiche les deux<br/>
valeurs séparées par un<br/>
espace.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>7</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction <code>print</code> n'effectue<br/>
pas d'addition entre les<br/>
arguments qui lui sont<br/>
passés. Elle se contente de<br/>
les afficher tels quels.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il déclenche une erreur de syntaxe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce code est parfaitement<br/>
valide. Aucune erreur n'est<br/>
levée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q11 : Définir une méthode</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment ajouter une méthode<br/>
<code>distance_origine</code> à la classe<br/>
<code>Point</code>, qui renvoie la distance<br/>
du point à l'origine $(0, 0)$ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'appel se fait simplement avec<br/>
<code>p.distance_origine()</code>. Python<br/>
transmet automatiquement <code>p</code><br/>
comme paramètre <code>self</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Point:
    def distance_origine():
        return ...</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Il manque le paramètre<br/>
<code>self</code> en première position.<br/>
Sans lui, la méthode ne peut<br/>
pas accéder aux attributs<br/>
de l'instance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def distance_origine(p):
    return (p.x ** 2 + p.y ** 2) ** 0.5</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette écriture définit une<br/>
fonction externe, et non une<br/>
méthode de la classe. Elle<br/>
fonctionne, mais elle est<br/>
moins idiomatique en<br/>
programmation orientée<br/>
objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>class Point:
    ...
    def distance_origine(self):
        return (self.x ** 2 + self.y ** 2) ** 0.5</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode est définie dans le<br/>
corps de la classe, avec<br/>
<code>self</code> comme premier<br/>
paramètre. On accède aux<br/>
attributs de l'instance par<br/>
<code>self.x</code> et <code>self.y</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Point:
    distance_origine = (x ** 2 + y ** 2) ** 0.5</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette écriture est invalide.<br/>
Les noms <code>x</code> et <code>y</code> ne sont<br/>
pas définis au niveau de la<br/>
classe ; il faut une méthode<br/>
qui s'applique à une<br/>
instance.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q12 : Combien d'instances ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Combien d'instances peut-on créer à<br/>
partir d'une seule classe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une classe sans instance n'a<br/>
aucune utilité. On crée autant<br/>
d'instances que la situation<br/>
l'exige.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Au plus dix instances</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucune limite particulière<br/>
n'est imposée par le langage.<br/>
Le nombre d'instances n'est<br/>
contraint que par la mémoire<br/>
disponible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Autant d'instances que nécessaire, chacune ayant ses propres valeurs d'attributs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La classe est un modèle. On<br/>
peut écrire par exemple<br/>
<code>v1 = Voiture("Renault")</code>,<br/>
<code>v2 = Voiture("Peugeot")</code>, et<br/>
ainsi de suite. Chaque<br/>
instance reste indépendante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une seule instance par classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette limite n'existe pas en<br/>
Python. On peut créer autant<br/>
d'instances que nécessaire à<br/>
partir d'une même classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune instance ne peut être créée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une classe sans instance ne<br/>
servirait à rien. Le rôle<br/>
d'une classe est précisément<br/>
de servir de patron pour<br/>
créer des objets.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q13 : Constructeur pour une classe Pile</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On souhaite écrire une classe <code>Pile</code><br/>
(de type LIFO) avec les méthodes<br/>
<code>empiler</code> et <code>depiler</code>. Quel<br/>
<code>__init__</code> choisir ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le motif standard est le<br/>
suivant : <code>__init__</code> initialise<br/>
les attributs avec<br/>
<code>self.nom = valeur</code>. Sans le<br/>
préfixe <code>self.</code>, on ne crée<br/>
qu'une variable locale, qui ne<br/>
survit pas à l'appel.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def __init__(self):
    return []</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>__init__</code> ne<br/>
renvoie rien (la valeur<br/>
renvoyée est implicitement<br/>
<code>None</code>). On y initialise<br/>
simplement les attributs de<br/>
l'instance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def __init__():
    elements = []</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le paramètre <code>self</code> manque,<br/>
et <code>elements</code> n'est ici<br/>
qu'une variable locale, qui<br/>
disparaîtra à la fin de<br/>
<code>__init__</code>. Il faudrait<br/>
écrire <code>self.elements = []</code><br/>
pour stocker la liste dans<br/>
l'instance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def __init__(self):
    elements = []</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans le préfixe <code>self.</code>, le<br/>
nom <code>elements</code> désigne une<br/>
simple variable locale, qui<br/>
ne persiste pas après la fin<br/>
de <code>__init__</code>. Il faut<br/>
écrire <code>self.elements = []</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def __init__(self):
    self.elements = []</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On initialise une liste vide,<br/>
qui contiendra les éléments<br/>
empilés. Les méthodes<br/>
<code>empiler</code> et <code>depiler</code><br/>
manipuleront ensuite<br/>
<code>self.elements</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q14 : Données et comportements groupés</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est l'intérêt principal de<br/>
regrouper, dans une même classe,<br/>
les <strong>attributs</strong> (les données) et<br/>
les <strong>méthodes</strong> (les<br/>
comportements) qui les manipulent ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une classe regroupe l'état<br/>
(les attributs) et les<br/>
opérations (les méthodes) liés<br/>
à un même concept. Dans une<br/>
classe <code>Pile</code>, par exemple, les<br/>
méthodes <code>empiler</code> et<br/>
<code>depiler</code> manipulent<br/>
directement la liste interne.<br/>
L'utilisateur n'a qu'à<br/>
connaître ces méthodes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le code est plus court mais devient moins lisible</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est en général l'inverse.<br/>
La lisibilité augmente, car<br/>
les opérations sont<br/>
regroupées au plus près des<br/>
données qu'elles<br/>
manipulent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les opérations qui agissent sur une donnée sont placées à côté de cette donnée, ce qui rend le code plus cohérent et plus facile à faire évoluer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On peut alors lire ou<br/>
modifier les attributs<br/>
uniquement par les méthodes<br/>
prévues à cet effet. Cela<br/>
permet de changer<br/>
l'implémentation interne<br/>
sans impacter le code qui<br/>
utilise la classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les données sont automatiquement enregistrées sur le disque</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La programmation orientée<br/>
objet n'a aucun lien direct<br/>
avec la persistance des<br/>
données sur le disque, qui<br/>
relève de mécanismes<br/>
séparés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le programme s'exécute plus rapidement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La performance n'est pas<br/>
l'avantage principal de la<br/>
programmation orientée<br/>
objet. Son intérêt est avant<br/>
tout structurel.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q15 : La méthode `__str__`</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert la méthode spéciale<br/>
<strong><code>__str__</code></strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Exemple typique :<br/>
<pre><code>def __str__(self):
    return f"Point({self.x}, {self.y})"</code></pre><br/>
L'instruction <code>print(Point(3, 4))</code><br/>
affichera alors <code>Point(3, 4)</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À supprimer l'objet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La suppression d'un objet<br/>
relève plutôt de la méthode<br/>
<code>__del__</code>. La méthode<br/>
<code>__str__</code> produit une<br/>
chaîne descriptive.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À convertir l'objet en entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette conversion serait<br/>
plutôt assurée par la<br/>
méthode spéciale <code>__int__</code>.<br/>
La méthode <code>__str__</code><br/>
concerne la représentation<br/>
textuelle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À déclarer une variable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La déclaration d'une<br/>
variable n'a rien à voir<br/>
avec une méthode spéciale.<br/>
La méthode <code>__str__</code><br/>
retourne une chaîne de<br/>
caractères.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À définir la représentation textuelle de l'objet, utilisée par <code>print(obj)</code> et <code>str(obj)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans <code>__str__</code>, l'instruction<br/>
<code>print(p)</code> afficherait<br/>
quelque chose comme<br/>
<code>&lt;__main__.Point object at<br/>
0x...&gt;</code>. Avec une <code>__str__</code><br/>
bien définie, on peut par<br/>
exemple obtenir<br/>
<code>Point(3, 4)</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q16 : Programmation objet et structures de données</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi la programmation orientée<br/>
objet est-elle particulièrement<br/>
utile pour implémenter des<br/>
<strong>structures de données</strong> comme les<br/>
arbres ou les graphes ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le programme officiel de<br/>
Terminale, dans la rubrique<br/>
Structures de données, cite<br/>
explicitement la<br/>
programmation orientée objet<br/>
comme outil possible pour ces<br/>
implémentations.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune raison particulière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La programmation orientée<br/>
objet apporte au contraire<br/>
de réels bénéfices pour<br/>
l'implémentation des<br/>
structures de données,<br/>
comme expliqué dans la<br/>
bonne réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle permet de regrouper proprement les données (par exemple <code>valeur</code>, <code>gauche</code>, <code>droite</code> pour un nœud d'arbre) et les opérations (parcours, recherche, insertion) en une seule entité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette modélisation est<br/>
naturelle. Une classe<br/>
<code>Noeud</code>, par exemple,<br/>
encapsule l'état et les<br/>
comportements d'un nœud<br/>
d'arbre. Le code est plus<br/>
clair et plus<br/>
réutilisable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est plus rapide à exécuter</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La programmation orientée<br/>
objet n'est pas<br/>
systématiquement plus<br/>
rapide. Son intérêt est<br/>
avant tout structurel et<br/>
conceptuel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est obligatoire dans le programme officiel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le programme officiel ne<br/>
rend pas la programmation<br/>
orientée objet obligatoire<br/>
pour l'implémentation de<br/>
ces structures. C'est une<br/>
option, parmi d'autres.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q17 : Interface et implémentation</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre<br/>
l'<strong>interface</strong> et<br/>
l'<strong>implémentation</strong> d'une<br/>
structure de données ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette distinction est<br/>
cruciale en programmation<br/>
modulaire. On programme<br/>
contre l'<strong>interface</strong> ; on<br/>
peut alors changer<br/>
l'implémentation sans<br/>
conséquence pour les<br/>
utilisateurs du module.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune différence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La distinction est au<br/>
contraire fondamentale en<br/>
programmation, comme<br/>
expliqué dans la bonne<br/>
réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'implémentation est aujourd'hui une notion obsolète</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'implémentation reste une<br/>
notion absolument<br/>
centrale. Tout programme<br/>
implémente concrètement<br/>
une ou plusieurs<br/>
interfaces.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'interface désigne l'ensemble des opérations disponibles (les signatures des méthodes). L'implémentation désigne la manière dont ces opérations sont effectivement réalisées en code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On peut, par exemple,<br/>
implémenter une file (de<br/>
type FIFO) avec une seule<br/>
liste, ou bien avec deux<br/>
piles. L'interface<br/>
(<code>enfiler</code>, <code>defiler</code>)<br/>
reste la même, mais les<br/>
implémentations sont<br/>
différentes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'interface s'exécute plus rapidement que l'implémentation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette comparaison n'a pas<br/>
de sens. L'interface n'est<br/>
pas exécutée<br/>
indépendamment ; elle<br/>
décrit simplement les<br/>
opérations disponibles.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q18 : La fonction type appliquée à une instance</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie l'appel <code>type(p)</code><br/>
lorsque <code>p</code> est une instance de<br/>
<code>Point</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une variante utile :<br/>
<code>isinstance(p, Point)</code><br/>
renvoie <code>True</code> si <code>p</code> est<br/>
une instance de <code>Point</code> ou<br/>
d'une éventuelle sous-classe.<br/>
Cette forme est plus<br/>
souple que <code>type(p) == Point</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>&lt;class 'Point'&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction <code>type</code> renvoie<br/>
la classe de l'objet<br/>
passé en paramètre. Elle<br/>
permet de connaître la<br/>
nature exacte d'un objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>object</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La classe <code>object</code> est la<br/>
classe ancêtre de toutes<br/>
les classes Python, mais<br/>
ce n'est pas la classe<br/>
précise de <code>p</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Point</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'appel renvoie bien la<br/>
classe <code>Point</code>, mais sa<br/>
représentation textuelle<br/>
dans la console est<br/>
<code>&lt;class 'Point'&gt;</code>. Le<br/>
test <code>type(p) == Point</code><br/>
renvoie cependant<br/>
<code>True</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code est parfaitement<br/>
valide et ne lève aucune<br/>
exception.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q19 : Une méthode qui modifie l'objet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>class Compteur:
    def __init__(self):
        self.n = 0
    def incrementer(self):
        self.n += 1

c = Compteur()
c.incrementer()
c.incrementer()
print(c.n)</code></pre><br/>
Que produit ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le <strong>changement d'état</strong> des<br/>
objets est l'un des piliers<br/>
de la programmation orientée<br/>
objet. Les méthodes<br/>
modifient les attributs en<br/>
réaffectant <code>self.attr</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il déclenche une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code est parfaitement<br/>
valide et s'exécute sans<br/>
erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche <code>2</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le constructeur initialise<br/>
l'attribut <code>n</code> à $0$.<br/>
Chaque appel à<br/>
<code>incrementer</code> ajoute $1$<br/>
à <code>self.n</code>. Après deux<br/>
appels, l'attribut vaut<br/>
donc $2$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette réponse ignore les<br/>
deux appels successifs à<br/>
<code>incrementer</code>, qui<br/>
modifient bien la valeur<br/>
de l'attribut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>incrementer</code><br/>
est appelée deux fois<br/>
successives, et non une<br/>
seule.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q20 : Tout est objet en Python</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Laquelle des affirmations<br/>
suivantes est correcte au sujet<br/>
des objets en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une conséquence de cette<br/>
uniformité : on peut écrire<br/>
<code>type(42)</code> ou même<br/>
<code>(42).__class__</code>. Ce modèle<br/>
« tout est objet » donne au<br/>
langage Python une grande<br/>
cohérence et autorise des<br/>
constructions puissantes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les fonctions ne sont pas des objets</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les fonctions Python sont<br/>
des <strong>objets de première<br/>
classe</strong> : elles peuvent<br/>
être passées en<br/>
paramètre, stockées dans<br/>
une variable, ou<br/>
renvoyées par d'autres<br/>
fonctions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Seules les classes définies par l'utilisateur produisent des objets</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>En Python, les entiers,<br/>
les chaînes et les listes<br/>
sont eux aussi des objets.<br/>
Ils sont des instances de<br/>
classes prédéfinies par<br/>
le langage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>En Python, tout est un objet : les entiers, les chaînes, les listes, les fonctions et même les classes sont des instances de classes prédéfinies</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Par exemple, l'appel<br/>
<code>type(42)</code> renvoie<br/>
<code>&lt;class 'int'&gt;</code>, et<br/>
<code>type("a")</code> renvoie<br/>
<code>&lt;class 'str'&gt;</code>. Même<br/>
les classes elles-mêmes<br/>
sont des objets, qui sont<br/>
des instances de la<br/>
métaclasse <code>type</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des affirmations précédentes n'est correcte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La deuxième proposition<br/>
est précisément correcte,<br/>
comme expliqué dans la<br/>
bonne réponse.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q21 : Une classe Noeud</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour représenter un <strong>nœud<br/>
d'arbre binaire</strong> comportant une<br/>
valeur, un sous-arbre gauche et<br/>
un sous-arbre droit, quelle<br/>
définition de classe est<br/>
correcte ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette modélisation<br/>
récursive est typique des<br/>
arbres binaires : chaque<br/>
nœud porte une valeur et<br/>
possède au plus deux fils,<br/>
qui sont eux-mêmes des<br/>
nœuds (ou <code>None</code> lorsqu'ils<br/>
sont absents).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def Noeud(val, gauche, droite):
    return val</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette définition est une<br/>
fonction, et non une<br/>
classe. De plus, elle ne<br/>
renvoie que la valeur,<br/>
sans construire de<br/>
structure d'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Noeud:
    pass</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette classe est vide :<br/>
elle ne permet pas de<br/>
stocker la valeur, le<br/>
sous-arbre gauche ni le<br/>
sous-arbre droit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>class Noeud:
    def __init__(self, val, gauche=None, droite=None):
        self.val = val
        self.gauche = gauche
        self.droite = droite</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette classe définit trois<br/>
attributs : <code>val</code>,<br/>
<code>gauche</code> et <code>droite</code>. Les<br/>
fils sont par défaut à<br/>
<code>None</code> (ce qui correspond<br/>
à une feuille). Les fils<br/>
sont eux-mêmes des<br/>
instances de <code>Noeud</code>, ce<br/>
qui produit une structure<br/>
récursive.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Noeud:
    val = 0
    gauche = None
    droite = None</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ces attributs sont<br/>
déclarés au niveau de la<br/>
classe, et seraient donc<br/>
<strong>partagés par toutes les<br/>
instances</strong>, au lieu<br/>
d'être propres à chacune.<br/>
Il s'agit d'un bug subtil<br/>
mais important.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q22 : Attribut de classe et attribut d'instance</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>class Voiture:
    marques = []
    def __init__(self, marque):
        Voiture.marques.append(marque)

v1 = Voiture("Renault")
v2 = Voiture("Peugeot")
print(Voiture.marques)</code></pre><br/>
Que produit ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinction essentielle :<br/>
les attributs de <strong>classe</strong><br/>
sont partagés entre toutes<br/>
les instances, alors que<br/>
les attributs<br/>
d'<strong>instance</strong> appartiennent<br/>
à un objet particulier. La<br/>
confusion est fréquente,<br/>
surtout avec des listes<br/>
mutables placées en<br/>
attribut de classe.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>['Peugeot']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La marque « Renault » est<br/>
également ajoutée par le<br/>
premier appel à<br/>
<code>__init__</code>, et reste donc<br/>
dans la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche <code>['Renault', 'Peugeot']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'attribut <code>marques</code> est<br/>
déclaré au niveau de la<br/>
<strong>classe</strong>, et non d'une<br/>
instance : il est donc<br/>
partagé par toutes les<br/>
voitures. Les ajouts<br/>
successifs s'accumulent<br/>
dans la même liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>[]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette réponse ignore les<br/>
deux appels à<br/>
<code>__init__</code>, qui ajoutent<br/>
chacun une marque à la<br/>
liste partagée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il déclenche une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code est parfaitement<br/>
valide et s'exécute sans<br/>
erreur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q23 : Pratique déconseillée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle pratique est<br/>
<strong>déconseillée</strong> en programmation<br/>
orientée objet ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le principe est le<br/>
suivant : on interagit avec<br/>
un objet à travers son<br/>
<strong>interface publique</strong>. Les<br/>
détails internes peuvent<br/>
ainsi évoluer sans affecter<br/>
le code utilisateur, tant<br/>
que l'interface reste<br/>
stable.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Utiliser des méthodes pour modifier les attributs d'un objet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est au contraire une<br/>
bonne pratique. Les<br/>
méthodes encapsulent les<br/>
modifications et peuvent<br/>
y ajouter des<br/>
vérifications.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Définir un constructeur <code>__init__</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est au contraire une<br/>
bonne pratique standard<br/>
que de définir<br/>
explicitement les<br/>
attributs d'un objet<br/>
dans <code>__init__</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Donner un nom en CamelCase à la classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le CamelCase est<br/>
précisément la<br/>
convention recommandée<br/>
en Python pour les noms<br/>
de classes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Modifier directement les attributs internes d'un objet depuis l'extérieur, par exemple en écrivant <code>compte.solde = -1000</code> au lieu de passer par une méthode comme <code>compte.deposer(...)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce contournement<br/>
court-circuite les<br/>
vérifications éventuelles<br/>
(par exemple, garantir<br/>
que le solde reste<br/>
positif). On préfère<br/>
exposer des méthodes qui<br/>
maintiennent les<br/>
invariants de l'objet.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q24 : Quand utiliser une classe ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans quel cas est-il <strong>judicieux</strong><br/>
d'utiliser une classe plutôt<br/>
qu'une simple fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une maxime utile : « une<br/>
classe quand il y a un état<br/>
et un ensemble de<br/>
comportements ; une<br/>
fonction sinon ». Une<br/>
classe ne contenant qu'une<br/>
seule méthode est souvent<br/>
le signe qu'une simple<br/>
fonction aurait suffi.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Jamais, les classes ne servent à rien en pratique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette position est tout<br/>
aussi catégorique. Les<br/>
classes apportent de<br/>
réels bénéfices dans de<br/>
nombreuses situations,<br/>
comme expliqué dans la<br/>
bonne réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour calculer la somme d'une liste de notes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une fonction simple suffit<br/>
pour ce calcul. Définir<br/>
une classe serait<br/>
disproportionné.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours, car c'est l'approche la plus moderne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette position est trop<br/>
dogmatique. Aucun<br/>
paradigme n'est<br/>
universellement<br/>
supérieur ; le choix<br/>
dépend du problème<br/>
traité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour modéliser une entité avec un état qui change au cours du temps et plusieurs comportements liés : par exemple un compte bancaire, une voiture, ou une structure de données comme une pile</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La programmation orientée<br/>
objet est particulièrement<br/>
adaptée pour modéliser des<br/>
entités du monde réel, ou<br/>
des structures de données<br/>
complexes. Pour des<br/>
calculs simples sans<br/>
état, une fonction est<br/>
plus directe.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes<br/>
sur la programmation orientée<br/>
objet en Python, laquelle est<br/>
<strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention contre règle :<br/>
la syntaxe Python est<br/>
assez permissive, mais les<br/>
conventions (comme le<br/>
style PEP $8$ ou les<br/>
idiomes communs) doivent<br/>
être respectées pour la<br/>
lisibilité et la<br/>
maintenabilité du code.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La méthode <code>__init__</code> est appelée automatiquement à la création d'une instance</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. C'est le rôle<br/>
de constructeur joué<br/>
par <code>__init__</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le paramètre <code>self</code> doit obligatoirement s'appeler <code>self</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
fausse (donc c'est la<br/>
bonne réponse). Il<br/>
s'agit d'une <strong>convention<br/>
forte</strong> en Python, mais<br/>
pas d'une obligation<br/>
syntaxique. On pourrait<br/>
écrire <code>this</code>, <code>obj</code> ou<br/>
tout autre nom, même si<br/>
c'est très vivement<br/>
déconseillé pour la<br/>
lisibilité du code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En Python, toutes les valeurs (entiers, chaînes, listes, fonctions, classes) sont des objets</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. C'est l'une<br/>
des caractéristiques<br/>
fondamentales du modèle<br/>
de Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une classe est un modèle ; une instance est une réalisation concrète</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. C'est la<br/>
distinction essentielle<br/>
entre les deux notions.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q26 : Méthodes spéciales</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On définit la classe suivante :<br/>
<pre><code>class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __eq__(self, autre):
        return self.x == autre.x and self.y == autre.y</code></pre><br/>
Quel est l'effet d'avoir défini la<br/>
méthode <code>__eq__</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quelques méthodes spéciales<br/>
utiles : <code>__init__</code> (constructeur),<br/>
<code>__str__</code> (affichage par<br/>
<code>print</code>), <code>__repr__</code><br/>
(représentation détaillée),<br/>
<code>__eq__</code> et <code>__lt__</code><br/>
(comparaisons), <code>__len__</code><br/>
(longueur via <code>len</code>),<br/>
<code>__getitem__</code> (accès indexé via<br/>
<code>obj[i]</code>). Elles permettent à<br/>
Python de manipuler les objets<br/>
personnalisés comme des objets<br/>
natifs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La classe <code>Point</code> devient<br/>
immuable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la définition de<br/>
<code>__eq__</code> ne rend pas la classe<br/>
immuable. Pour cela, il<br/>
faudrait écrire des méthodes<br/>
spécifiques qui empêchent la<br/>
modification des attributs<br/>
(par exemple en utilisant des<br/>
<em>property</em> en lecture seule).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun effet : Python ignore les<br/>
méthodes commençant par un<br/>
double soulignement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est exactement<br/>
l'inverse. Les méthodes encadrées<br/>
de doubles soulignements<br/>
(<code>__nom__</code>) sont les <strong>méthodes<br/>
spéciales</strong> que Python appelle<br/>
automatiquement dans certaines<br/>
situations (création d'objet,<br/>
comparaison, affichage, etc.).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La comparaison <code>Point(1, 2) ==<br/>
Point(1, 2)</code> renverra <code>True</code><br/>
(deux points avec mêmes<br/>
coordonnées sont considérés<br/>
égaux), au lieu de <code>False</code><br/>
comme c'était le cas par défaut</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans <code>__eq__</code>,<br/>
Python compare les objets par<br/>
<strong>identité</strong> (l'opérateur <code>is</code>),<br/>
donc deux instances distinctes<br/>
sont différentes même si elles<br/>
ont les mêmes attributs. En<br/>
définissant <code>__eq__</code>, on<br/>
surcharge l'opérateur <code>==</code> pour<br/>
comparer par <strong>valeur</strong>. C'est<br/>
l'une des nombreuses méthodes<br/>
spéciales (avec <code>__lt__</code>,<br/>
<code>__hash__</code>, <code>__len__</code>,<br/>
<code>__str__</code>, etc.) qui permettent<br/>
de personnaliser le<br/>
comportement des objets.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les objets <code>Point</code> ne pourront<br/>
plus être créés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>__eq__</code> n'a aucun<br/>
effet sur la création d'objets,<br/>
qui reste régie par<br/>
<code>__init__</code>. Elle agit<br/>
uniquement sur la comparaison<br/>
d'égalité.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q27 : Classe Compte bancaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On souhaite implémenter une classe<br/>
<code>Compte</code> représentant un compte<br/>
bancaire avec un solde, une<br/>
méthode <code>deposer(montant)</code> et<br/>
une méthode <code>retirer(montant)</code><br/>
qui refuse l'opération si le<br/>
solde devient négatif. Quel<br/>
code est correct ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cet exemple illustre les principes<br/>
essentiels de la programmation<br/>
orientée objet : encapsulation<br/>
(état dans <code>self.solde</code>),<br/>
invariants (vérifications dans<br/>
les méthodes), interface publique<br/>
claire (<code>deposer</code> et <code>retirer</code><br/>
avec une signification précise),<br/>
gestion des erreurs (renvoyer<br/>
<code>False</code> plutôt que de laisser le<br/>
solde devenir négatif). Une<br/>
version plus avancée pourrait<br/>
lever une exception explicite<br/>
au lieu de renvoyer <code>False</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>class Compte:
    def __init__(self, solde_initial=0):
        self.solde = solde_initial
    def deposer(self, montant):
        if montant &gt; 0:
            self.solde += montant
    def retirer(self, montant):
        if 0 &lt; montant &lt;= self.solde:
            self.solde -= montant
            return True
        return False</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le constructeur<br/>
initialise le solde, <code>deposer</code><br/>
ajoute si le montant est<br/>
positif, <code>retirer</code> vérifie que<br/>
le compte ne devient pas<br/>
négatif et signale l'échec en<br/>
renvoyant <code>False</code>. Les<br/>
contraintes sont vérifiées<br/>
dans les méthodes, ce qui<br/>
garantit l'invariant « solde<br/>
≥ 0 » sans avoir à faire<br/>
confiance au code utilisateur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Compte:
    def __init__(self):
        self.solde = 0
    def __retirer__(self, m):
        self.solde -= m</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>__retirer__</code> n'est<br/>
pas une méthode spéciale<br/>
reconnue par Python. Les<br/>
doubles soulignements sont<br/>
réservés aux méthodes spéciales<br/>
du langage (<code>__init__</code>,<br/>
<code>__str__</code>, etc.). Ici, il<br/>
faut simplement nommer la<br/>
méthode <code>retirer</code>. De plus,<br/>
il n'y a pas de méthode<br/>
<code>deposer</code> ni de vérification<br/>
du solde.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def Compte(solde):
    return solde</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code définit une<br/>
fonction, pas une classe. Il<br/>
n'y a ni méthode <code>deposer</code>,<br/>
ni <code>retirer</code>, ni encapsulation<br/>
de l'état. C'est juste une<br/>
fonction qui renvoie son<br/>
paramètre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Compte:
    solde = 0
    def deposer(montant):
        solde += montant
    def retirer(montant):
        solde -= montant</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Plusieurs erreurs ici. (1) Le<br/>
paramètre <code>self</code> est absent<br/>
dans les méthodes, donc Python<br/>
appellerait avec un mauvais<br/>
nombre de paramètres. (2)<br/>
<code>solde</code> est un attribut de<br/>
classe partagé entre toutes<br/>
les instances, pas un attribut<br/>
d'instance (bug subtil). (3)<br/>
Aucune vérification du<br/>
montant. (4) Les <code>solde += ...</code><br/>
dans les méthodes<br/>
n'atteindront pas l'attribut<br/>
d'instance sans <code>self.</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
