<?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 __init__, 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 Voiture,<br/>
on peut créer plusieurs objets<br/>
Voiture 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 # 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 Voiture, des<br/>
attributs typiques pourraient<br/>
être : marque, modele,<br/>
couleur, vitesse. 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 nom ou l'age d'une Personne</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 Voiture, des<br/>
méthodes typiques pourraient<br/>
être : accelerer, freiner,<br/>
afficher. Elles agissent<br/>
directement sur l'état de l'objet<br/>
par l'intermédiaire de self.</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 self 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 Voiture<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> (Voiture,<br/>
MaSuperClasse), tandis que les<br/>
noms de fonctions et de variables<br/>
s'écrivent en <strong>snake_case</strong><br/>
(ma_fonction, ma_variable).</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>python<br/>
class Voiture:<br/>
    pass<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise le mot-clé class,<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/>
pass permet de signaler un<br/>
corps vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
new class Voiture {}<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
Voiture = class()<br/>
</code>`</p>]]></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/>
class suivi du nom de la<br/>
classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def Voiture():<br/>
    pass<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le mot-clé def introduit une<br/>
<strong>fonction</strong>, et non une<br/>
classe. Pour une classe, il<br/>
faut utiliser class.</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 Voiture en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une distinction subtile : le nom<br/>
Voiture désigne la classe<br/>
elle-même (un objet de type<br/>
classe), tandis que Voiture()<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 v = new Voiture()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le mot-clé new 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 v = create Voiture</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La syntaxe create 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 v = Voiture</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans les parenthèses, la<br/>
variable v 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 v = Voiture()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On appelle la classe comme<br/>
une fonction. Cet appel<br/>
déclenche le constructeur<br/>
(__init__, 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 v est une instance de la classe<br/>
Voiture possédant un attribut<br/>
marque, 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 v.marque</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/>
v.demarrer().</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la notation v-&gt;marque</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 get(v, marque)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une fonction getattr(v,<br/>
"marque") 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 v["marque"]</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>self</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 this, 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>self 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 self 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 super(). Le<br/>
paramètre self 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 self le premier<br/>
paramètre des méthodes.<br/>
Lorsqu'on écrit<br/>
v.demarrer(), Python<br/>
transmet automatiquement v<br/>
comme paramètre self.</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>__init__</strong> d'une classe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention : les noms encadrés de<br/>
doubles soulignés (__nom__)<br/>
désignent des méthodes spéciales<br/>
en Python, comme __init__,<br/>
__str__ ou __len__. Parmi<br/>
elles, __init__ 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 __del__,<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 __init__ 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 import,<br/>
et n'a aucun rapport avec<br/>
__init__.</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/>
``python<br/>
class Point:<br/>
    def __init__(self, x, y):<br/>
        self.x = x<br/>
        self.y = y</p>
<p>p = Point(3, 4)<br/>
print(p.x, p.y)<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Voici le motif de base d'une<br/>
classe simple : une méthode<br/>
__init__ qui prend les valeurs<br/>
initiales en paramètres et les<br/>
stocke dans self à l'aide<br/>
d'instructions de la forme<br/>
self.attr = ....</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 Point(3, 4)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'instruction print(p.x,<br/>
p.y) 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 3 4</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'expression Point(3, 4)<br/>
crée une instance ; la<br/>
méthode __init__ initialise<br/>
les attributs self.x = 3 et<br/>
self.y = 4. La fonction<br/>
print 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 7</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction print 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/>
distance_origine à la classe<br/>
Point, 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/>
p.distance_origine(). Python<br/>
transmet automatiquement p<br/>
comme paramètre self.</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>`<code>python<br/>
class Point:<br/>
    def distance_origine():<br/>
        return ...<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Il manque le paramètre<br/>
self 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[<p>`<code>python<br/>
def distance_origine(p):<br/>
    return (p.x <strong> 2 + p.y </strong> 2) ** 0.5<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
class Point:<br/>
    ...<br/>
    def distance_origine(self):<br/>
        return (self.x <strong> 2 + self.y </strong> 2) ** 0.5<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode est définie dans le<br/>
corps de la classe, avec<br/>
self comme premier<br/>
paramètre. On accède aux<br/>
attributs de l'instance par<br/>
self.x et self.y.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
class Point:<br/>
    distance_origine = (x <strong> 2 + y </strong> 2) ** 0.5<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette écriture est invalide.<br/>
Les noms x et y 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/>
v1 = Voiture("Renault"),<br/>
v2 = Voiture("Peugeot"), 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 Pile<br/>
(de type LIFO) avec les méthodes<br/>
empiler et depiler. Quel<br/>
__init__ choisir ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le motif standard est le<br/>
suivant : __init__ initialise<br/>
les attributs avec<br/>
self.nom = valeur. Sans le<br/>
préfixe self., 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[<p>`<code>python<br/>
def __init__(self):<br/>
    return []<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode __init__ ne<br/>
renvoie rien (la valeur<br/>
renvoyée est implicitement<br/>
None). On y initialise<br/>
simplement les attributs de<br/>
l'instance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def __init__():<br/>
    elements = []<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le paramètre self manque,<br/>
et elements n'est ici<br/>
qu'une variable locale, qui<br/>
disparaîtra à la fin de<br/>
__init__. Il faudrait<br/>
écrire self.elements = []<br/>
pour stocker la liste dans<br/>
l'instance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def __init__(self):<br/>
    elements = []<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans le préfixe self., le<br/>
nom elements désigne une<br/>
simple variable locale, qui<br/>
ne persiste pas après la fin<br/>
de __init__. Il faut<br/>
écrire self.elements = [].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def __init__(self):<br/>
    self.elements = []<br/>
</code>`</p>]]></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/>
empiler et depiler<br/>
manipuleront ensuite<br/>
self.elements.</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 Pile, par exemple, les<br/>
méthodes empiler et<br/>
depiler 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>__str__</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Exemple typique :<br/>
`<code>python<br/>
def __str__(self):<br/>
    return f"Point({self.x}, {self.y})"<br/>
</code><br/>
L'instruction print(Point(3, 4))<br/>
affichera alors Point(3, 4)`.</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/>
__del__. La méthode<br/>
__str__ 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 __int__.<br/>
La méthode __str__<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 __str__<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 print(obj) et str(obj)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans __str__, l'instruction<br/>
print(p) afficherait<br/>
quelque chose comme<br/>
&lt;__main__.Point object at<br/>
0x...&gt;. Avec une __str__<br/>
bien définie, on peut par<br/>
exemple obtenir<br/>
Point(3, 4).</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 valeur, gauche, droite 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/>
Noeud, 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/>
(enfiler, defiler)<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 type(p)<br/>
lorsque p est une instance de<br/>
Point ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une variante utile :<br/>
isinstance(p, Point)<br/>
renvoie True si p est<br/>
une instance de Point ou<br/>
d'une éventuelle sous-classe.<br/>
Cette forme est plus<br/>
souple que type(p) == Point.</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>&lt;class 'Point'&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction type 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>object</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La classe object est la<br/>
classe ancêtre de toutes<br/>
les classes Python, mais<br/>
ce n'est pas la classe<br/>
précise de p.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Point</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'appel renvoie bien la<br/>
classe Point, mais sa<br/>
représentation textuelle<br/>
dans la console est<br/>
&lt;class 'Point'&gt;. Le<br/>
test type(p) == Point<br/>
renvoie cependant<br/>
True.</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>``python<br/>
class Compteur:<br/>
    def __init__(self):<br/>
        self.n = 0<br/>
    def incrementer(self):<br/>
        self.n += 1</p>
<p>c = Compteur()<br/>
c.incrementer()<br/>
c.incrementer()<br/>
print(c.n)<br/>
``<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 self.attr.</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 2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le constructeur initialise<br/>
l'attribut n à 0.<br/>
Chaque appel à<br/>
incrementer ajoute 1<br/>
à self.n. 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 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette réponse ignore les<br/>
deux appels successifs à<br/>
incrementer, qui<br/>
modifient bien la valeur<br/>
de l'attribut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche 1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode incrementer<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/>
type(42) ou même<br/>
(42).__class__. 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/>
type(42) renvoie<br/>
&lt;class 'int'&gt;, et<br/>
type("a") renvoie<br/>
&lt;class 'str'&gt;. Même<br/>
les classes elles-mêmes<br/>
sont des objets, qui sont<br/>
des instances de la<br/>
métaclasse type.</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 None 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[<p>`<code>python<br/>
def Noeud(val, gauche, droite):<br/>
    return val<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
class Noeud:<br/>
    pass<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
class Noeud:<br/>
    def __init__(self, val, gauche=None, droite=None):<br/>
        self.val = val<br/>
        self.gauche = gauche<br/>
        self.droite = droite<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette classe définit trois<br/>
attributs : val,<br/>
gauche et droite. Les<br/>
fils sont par défaut à<br/>
None (ce qui correspond<br/>
à une feuille). Les fils<br/>
sont eux-mêmes des<br/>
instances de Noeud, ce<br/>
qui produit une structure<br/>
récursive.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
class Noeud:<br/>
    val = 0<br/>
    gauche = None<br/>
    droite = None<br/>
</code>`</p>]]></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>``python<br/>
class Voiture:<br/>
    marques = []<br/>
    def __init__(self, marque):<br/>
        Voiture.marques.append(marque)</p>
<p>v1 = Voiture("Renault")<br/>
v2 = Voiture("Peugeot")<br/>
print(Voiture.marques)<br/>
``<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 ['Peugeot']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La marque « Renault » est<br/>
également ajoutée par le<br/>
premier appel à<br/>
__init__, et reste donc<br/>
dans la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche ['Renault', 'Peugeot']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'attribut marques 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 []</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette réponse ignore les<br/>
deux appels à<br/>
__init__, 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 __init__</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 __init__.</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 compte.solde = -1000 au lieu de passer par une méthode comme compte.deposer(...)</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 __init__ 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 __init__.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le paramètre self doit obligatoirement s'appeler self</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 this, obj 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/>
`<code>python<br/>
class Point:<br/>
    def __init__(self, x, y):<br/>
        self.x = x<br/>
        self.y = y<br/>
    def __eq__(self, autre):<br/>
        return self.x == autre.x and self.y == autre.y<br/>
</code><br/>
Quel est l'effet d'avoir défini la<br/>
méthode __eq__` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quelques méthodes spéciales<br/>
utiles : __init__ (constructeur),<br/>
__str__ (affichage par<br/>
print), __repr__<br/>
(représentation détaillée),<br/>
__eq__ et __lt__<br/>
(comparaisons), __len__<br/>
(longueur via len),<br/>
__getitem__ (accès indexé via<br/>
obj[i]). 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 Point devient<br/>
immuable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la définition de<br/>
__eq__ 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/>
(__nom__) 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 Point(1, 2) ==<br/>
Point(1, 2) renverra True<br/>
(deux points avec mêmes<br/>
coordonnées sont considérés<br/>
égaux), au lieu de False<br/>
comme c'était le cas par défaut</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans __eq__,<br/>
Python compare les objets par<br/>
<strong>identité</strong> (l'opérateur is),<br/>
donc deux instances distinctes<br/>
sont différentes même si elles<br/>
ont les mêmes attributs. En<br/>
définissant __eq__, on<br/>
surcharge l'opérateur == pour<br/>
comparer par <strong>valeur</strong>. C'est<br/>
l'une des nombreuses méthodes<br/>
spéciales (avec __lt__,<br/>
__hash__, __len__,<br/>
__str__, 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 Point ne pourront<br/>
plus être créés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : __eq__ n'a aucun<br/>
effet sur la création d'objets,<br/>
qui reste régie par<br/>
__init__. 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/>
Compte représentant un compte<br/>
bancaire avec un solde, une<br/>
méthode deposer(montant) et<br/>
une méthode retirer(montant)<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 self.solde),<br/>
invariants (vérifications dans<br/>
les méthodes), interface publique<br/>
claire (deposer et retirer<br/>
avec une signification précise),<br/>
gestion des erreurs (renvoyer<br/>
False 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 False.</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>python<br/>
class Compte:<br/>
    def __init__(self, solde_initial=0):<br/>
        self.solde = solde_initial<br/>
    def deposer(self, montant):<br/>
        if montant &gt; 0:<br/>
            self.solde += montant<br/>
    def retirer(self, montant):<br/>
        if 0 &lt; montant &lt;= self.solde:<br/>
            self.solde -= montant<br/>
            return True<br/>
        return False<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le constructeur<br/>
initialise le solde, deposer<br/>
ajoute si le montant est<br/>
positif, retirer vérifie que<br/>
le compte ne devient pas<br/>
négatif et signale l'échec en<br/>
renvoyant False. 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[<p>`<code>python<br/>
class Compte:<br/>
    def __init__(self):<br/>
        self.solde = 0<br/>
    def __retirer__(self, m):<br/>
        self.solde -= m<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : __retirer__ 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 (__init__,<br/>
__str__, etc.). Ici, il<br/>
faut simplement nommer la<br/>
méthode retirer. De plus,<br/>
il n'y a pas de méthode<br/>
deposer ni de vérification<br/>
du solde.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def Compte(solde):<br/>
    return solde<br/>
</code>`</p>]]></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 deposer,<br/>
ni retirer, 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[<p>`<code>python<br/>
class Compte:<br/>
    solde = 0<br/>
    def deposer(montant):<br/>
        solde += montant<br/>
    def retirer(montant):<br/>
        solde -= montant<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Plusieurs erreurs ici. (1) Le<br/>
paramètre self est absent<br/>
dans les méthodes, donc Python<br/>
appellerait avec un mauvais<br/>
nombre de paramètres. (2)<br/>
solde 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 solde += ...<br/>
dans les méthodes<br/>
n'atteindront pas l'attribut<br/>
d'instance sans self..</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
