<?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 décrivant attributs et méthodes d'objets</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 enregistré avec l'extension .py</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 signalée à l'exécution</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 variable ordinaire contenant une valeur 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.</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</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 (nom, âge)</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 de la classe agissant sur l'objet</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>Une définition de classe commence par le mot-clé <code>class</code>, le nom de la classe et deux-points. Le corps indenté contient ensuite les méthodes, comme <code>__init__</code>, ou simplement <code>pass</code> s'il est vide.</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>, puis le nom de la classe, suivi de deux-points et d'un corps indenté. L'instruction <code>pass</code> permet de signaler un 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>Aucune fonction <code>get</code> ne lit ainsi un attribut, et <code>marque</code> sans guillemets désignerait une variable inexistante. On accède aux attributs d'un objet avec la notation pointée.</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>Le paramètre <code>self</code> ne désigne pas une classe : il désigne l'objet sur lequel la méthode est appelée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'instance courante, donnant accès à ses attributs</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>Les noms encadrés de doubles soulignés, comme <code>__init__</code>, désignent des méthodes que Python appelle de lui-même : <code>__init__</code> est exécutée automatiquement à chaque création d'un objet de la 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="100" format="html">
    <text><![CDATA[<p>Initialiser les attributs d'un nouvel objet</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 méthode <code>__init__</code> intervient à la création de l'objet, pas à sa disparition : elle fixe les valeurs initiales de ses attributs.</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 que nécessaire, chacune indépendante</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 sont au plus près des données</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 : Une méthode qui reçoit un autre objet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère le programme suivant :<br/>
<pre><code>class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def distance(self, autre):
        return abs(self.x - autre.x) + abs(self.y - autre.y)
p = Point(1, 2)
q = Point(4, 6)
print(p.distance(q))</code></pre><br/>
Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une méthode peut prendre en paramètre un autre objet de la même classe. Dans l'appel <code>p.distance(q)</code>, l'objet placé avant le point devient <code>self</code>, et l'argument entre parenthèses devient <code>autre</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>7</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Dans l'appel <code>p.distance(q)</code>, <code>self</code> désigne <code>p</code> et <code>autre</code> désigne <code>q</code>. La méthode calcule $|1 - 4| + |2 - 6| = 3 + 4 = 7$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>5</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>$5$ serait la distance à vol d'oiseau, $\sqrt{3^2 + 4^2}$. La méthode écrite ici additionne simplement les deux écarts, $3 + 4$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car <code>distance</code> attend deux arguments et n'en reçoit qu'un</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le paramètre <code>self</code> n'est pas à fournir : Python lui donne automatiquement l'objet <code>p</code>. Le seul argument écrit, <code>q</code>, correspond au paramètre <code>autre</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car une méthode ne peut lire que les attributs de <code>self</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une méthode peut lire les attributs de tout objet qu'elle reçoit : <code>autre.x</code> désigne l'attribut <code>x</code> de <code>q</code>, accessible par la notation pointée.</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>Regrouper données et opérations 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 strictement 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 liste les opérations, l'implémentation les 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>La fonction <code>type</code> permet de vérifier la classe d'un objet : <code>type(42) == int</code> vaut <code>True</code>, et de même <code>type(p) == Point</code> vaut <code>True</code> lorsque <code>p</code> a été créé par <code>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>La classe <code>Point</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction <code>type</code> renvoie la classe de l'objet passé en paramètre, ici <code>Point</code> : le test <code>type(p) == Point</code> vaut <code>True</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La classe <code>object</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>type</code> ne renvoie pas une classe générale : il renvoie la classe précise à partir de laquelle l'objet a été créé, ici <code>Point</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La chaîne <code>"p"</code>, nom de la variable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>type</code> ne s'intéresse pas au nom de la variable : il renvoie la classe de l'objet que cette variable désigne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car <code>type</code> ne s'applique qu'aux entiers, flottants et chaînes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>type</code> s'applique à toute valeur, y compris aux objets créés à partir d'une classe écrite par le programmeur. Le code ne provoque aucune erreur.</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, pas 1.</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 uniformité : la fonction <code>type</code> s'applique à toute valeur, qu'il s'agisse d'un entier, d'une chaîne ou d'un objet créé à partir d'une classe écrite par le programmeur. Ce modèle donne au langage Python une grande cohérence.</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 elles aussi des objets : on peut par exemple les ranger dans une variable ou en donner une en argument à <code>sorted</code> pour choisir la clé de tri.</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, même les classes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Par exemple, l'appel <code>type(42)</code> renvoie <code>&lt;class 'int'&gt;</code>, et <code>type("a")</code> renvoie <code>&lt;class 'str'&gt;</code>. Les entiers, les chaînes, les fonctions et même les classes sont des objets.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune de ces affirmations n'est correcte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'affirmation « en Python, tout est un objet, même les classes » est correcte : entiers, chaînes, listes, fonctions et classes sont tous des objets.</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 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=None, droite=None):
    return {"val": val, "gauche": gauche, "droite": droite}</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette définition est une<br/>
fonction, et non une<br/>
classe : aucun type <code>Noeud</code><br/>
n'est créé. Le dictionnaire<br/>
renvoyé s'utilise avec<br/>
<code>n["val"]</code> au lieu de<br/>
<code>n.val</code> et n'a aucune<br/>
méthode propre aux nœuds.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Noeud:
    def __init__(self, val, gauche=None, droite=None):
        val = val
        gauche = gauche
        droite = droite</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le constructeur affecte des<br/>
variables locales, qui<br/>
disparaissent dès la fin de<br/>
<code>__init__</code>. Sans écrire<br/>
<code>self.val = val</code>, l'objet<br/>
créé ne possède aucun<br/>
attribut : <code>n.val</code> provoque<br/>
une <code>AttributeError</code>.</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 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 — Q23 : Affectation d'un objet à une autre variable</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère le programme suivant :</p>
<pre><code>class Compteur:
    def __init__(self):
        self.valeur = 0

    def incrementer(self):
        self.valeur = self.valeur + 1

a = Compteur()
b = a
c = Compteur()
a.incrementer()
b.incrementer()
c.incrementer()
print(a.valeur, b.valeur, c.valeur)</code></pre>
<p>Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Seul l'appel <code>Compteur()</code> crée un objet. L'affectation <code>b = a</code> donne simplement un second nom au même objet : toute modification faite par l'un des noms est visible par l'autre.</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>1 1 1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'affectation <code>b = a</code> ne copie pas l'objet : <code>a</code> et <code>b</code> désignent le même compteur. Il est donc incrémenté deux fois, par <code>a</code> puis par <code>b</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>2 2 2</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque appel à <code>Compteur()</code> crée un nouvel objet : <code>c</code> est un compteur distinct, incrémenté une seule fois. Seuls <code>a</code> et <code>b</code> partagent le même objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car <code>b</code> n'a pas été créé par <code>Compteur()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La variable <code>b</code> désigne l'objet créé pour <code>a</code> ; on peut appeler ses méthodes exactement comme avec <code>a</code>. Le programme s'exécute sans erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>2 2 1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>a</code> et <code>b</code> désignent le même objet, incrémenté deux fois : sa valeur est $2$, lue par <code>a.valeur</code> comme par <code>b.valeur</code>. <code>c</code> est un autre objet, incrémenté une fois.</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 simple 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>Modéliser une entité avec état et comportements</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 : la syntaxe Python est assez permissive, mais les conventions partagées, comme le nom <code>self</code>, doivent être respectées pour la lisibilité 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 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 — 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>class Compte:
    def __init__(self, solde_initial=0):
        self.solde = solde_initial
    def deposer(self, montant):
        self.solde += montant
    def retirer(self, montant):
        self.solde -= montant</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code s'exécute,<br/>
mais <code>retirer</code> ne vérifie<br/>
rien : le solde peut devenir<br/>
négatif, ce que la<br/>
spécification interdit<br/>
explicitement. Il manque<br/>
aussi le contrôle de<br/>
positivité des montants dans<br/>
<code>deposer</code>.</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>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q28 : La méthode de défilement d'une classe File</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La classe <code>File</code> range ses éléments dans la liste <code>self.elements</code>,<br/>
les nouveaux étant ajoutés en fin de liste par <code>append</code>. Quelle<br/>
ligne complète la méthode <code>defiler</code>, qui retire et renvoie le plus<br/>
ancien élément ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Écrire une structure de données en classe, c'est traduire chaque<br/>
opération de l'interface en une méthode sur l'attribut interne.</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>return self.elements.pop(0)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le plus ancien est en tête de liste, à l'indice<br/>
$0$ ; <code>pop(0)</code> le retire et le renvoie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return self.elements.pop()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans argument, <code>pop</code> retire le dernier arrivé ; ce<br/>
serait une pile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return self.elements[0]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'élément est lu mais reste dans la file.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return self.elements.remove(0)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>remove(0)</code> cherche la valeur $0$, pas l'indice, et ne<br/>
renvoie rien.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q29 : Une méthode qui teste si la pile est vide</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle ligne complète correctement la méthode <code>est_vide</code> d'une<br/>
classe <code>Pile</code> dont les éléments sont dans la liste<br/>
<code>self.elements</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une méthode de test renvoie un booléen et ne modifie pas l'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><code>return len(self.elements) == 0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la comparaison renvoie un booléen, <code>True</code> quand<br/>
la liste est vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return self.elements == None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste vide n'est pas <code>None</code> ; ce test répond<br/>
toujours <code>False</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return len(self.elements)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la méthode renverrait un entier, nul précisément quand<br/>
la pile est vide, soit l'inverse d'un <code>True</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return self.elements.pop() is None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tester ne doit rien retirer, et <code>pop</code> sur une liste<br/>
vide provoque une erreur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q30 : Une méthode qui renvoie un nouvel objet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie <code>a.plus(b)</code> ?<br/>
<pre><code>class Rationnel:
    def __init__(self, n, d):
        self.n = n
        self.d = d

    def plus(self, autre):
        return Rationnel(self.n * autre.d + autre.n * self.d,
                        self.d * autre.d)

a = Rationnel(1, 2)
b = Rationnel(1, 3)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une méthode qui renvoie un nouvel objet au lieu de modifier <code>self</code><br/>
laisse les opérandes inchangés, comme les nombres.</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>Rationnel(5, 6)</code>, un nouvel objet, <code>a</code> et <code>b</code> restant intacts</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la méthode applique la règle d'addition des<br/>
fractions, $1 \times 3 + 1 \times 2 = 5$ sur<br/>
$2 \times 3 = 6$, sans simplifier, et construit un<br/>
troisième objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Rationnel(2, 5)</code>, les numérateurs et dénominateurs s'ajoutant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas ce que calcule le code, ni la règle des<br/>
fractions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Rationnel(1, 6)</code>, le produit des deux fractions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le numérateur calculé est une somme de deux produits,<br/>
pas un seul produit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une méthode ne pouvant créer un objet de sa propre classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une méthode peut appeler <code>Rationnel(...)</code> comme<br/>
n'importe quel code.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q31 : Une liste d'objets</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>class Eleve:
    def __init__(self, nom, note):
        self.nom = nom
        self.note = note

eleves = [Eleve("Ana", 15), Eleve("Bob", 12)]
print(eleves[1].note)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les objets se rangent dans les listes et les dictionnaires comme<br/>
toute autre valeur ; on accède à leurs attributs après l'indexation.</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>12</code>, la note du second élève de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>eleves[1]</code> est le second objet, et <code>.note</code> lit<br/>
son attribut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>15</code>, la note du premier élève de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les indices commencent à $0$, <code>eleves[1]</code> est le<br/>
second.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Bob</code>, le nom du second élève</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'attribut <code>note</code> qui est affiché, pas <code>nom</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une liste ne pouvant contenir des objets</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste contient des valeurs de tout type, objets<br/>
compris.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q32 : Chaque instance a sa propre liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>class Panier:
    def __init__(self):
        self.articles = []

p1 = Panier()
p2 = Panier()
p1.articles.append("pain")
print(len(p2.articles))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les attributs créés dans <code>__init__</code> appartiennent à chaque objet :<br/>
deux instances ne partagent rien par défaut.</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>0</code>, chaque appel de <code>__init__</code> créant une liste distincte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>[]</code> est évalué à chaque construction ; <code>p1</code> et<br/>
<code>p2</code> ont chacun leur liste, et seule celle de <code>p1</code> a reçu un<br/>
article.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>1</code>, la liste étant partagée par toutes les instances</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste n'est pas définie dans la classe mais créée<br/>
dans <code>__init__</code>, une fois par objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, <code>p2.articles</code> n'existant pas encore</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>__init__</code> a créé l'attribut de <code>p2</code> à sa<br/>
construction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>None</code>, la liste de <code>p2</code> n'ayant jamais été remplie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste vide a une longueur, $0$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q33 : Modifier un attribut depuis l'extérieur de la classe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><code>v</code> est un objet de la classe <code>Voiture</code>, qui possède un attribut<br/>
<code>vitesse</code>. Que fait l'instruction <code>v.vitesse = 50</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un attribut est une variable attachée à un objet : la notation<br/>
<code>objet.attribut</code> y accède en lecture comme en écriture.</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>Elle donne la valeur <code>50</code> à l'attribut <code>vitesse</code> de l'objet <code>v</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un attribut se lit et se modifie par la<br/>
notation pointée, depuis la classe ou depuis l'extérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle crée une variable globale <code>vitesse</code> valant <code>50</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le préfixe <code>v.</code> désigne l'attribut de l'objet, pas une<br/>
variable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle provoque une erreur, un attribut ne se modifiant que par une méthode</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python n'impose pas de passer par une méthode, même si<br/>
c'est souvent préférable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle donne la valeur <code>50</code> à la vitesse de toutes les voitures</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul l'objet <code>v</code> est concerné.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q34 : Un `self` oublié dans le constructeur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que se passe-t-il à la dernière ligne ?<br/>
<pre><code>class Personne:
    def __init__(self, nom):
        nom = nom

p = Personne("Ada")
print(p.nom)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Dans une méthode, seules les variables préfixées par <code>self.</code><br/>
appartiennent à l'objet ; les autres disparaissent à la fin de<br/>
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="100" format="html">
    <text><![CDATA[<p>Une <code>AttributeError</code>, l'attribut <code>nom</code> n'ayant jamais été créé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>nom = nom</code> réaffecte la variable locale du<br/>
constructeur, sans toucher à l'objet. Il fallait écrire<br/>
<code>self.nom = nom</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'affichage de <code>Ada</code>, Python ajoutant <code>self.</code> automatiquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'est automatique, un attribut doit être créé<br/>
explicitement sur <code>self</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur de syntaxe dès la définition de la classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>nom = nom</code> est une affectation valide, inutile mais<br/>
valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'affichage de <code>None</code>, l'attribut existant sans valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'attribut n'existe pas du tout.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q35 : Une méthode appelée sans parenthèses</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La classe <code>Rectangle</code> a une méthode <code>aire</code> qui renvoie le produit<br/>
de la largeur par la hauteur. Que vaut <code>r.aire</code>, sans parenthèses ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>r.aire</code> et <code>r.aire()</code> sont deux expressions différentes : la<br/>
seconde seule déclenche l'exécution.</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>La méthode elle-même, pas le résultat du calcul</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans parenthèses, on désigne la méthode sans<br/>
l'appeler ; son affichage ressemble à <code>&lt;bound method ...&gt;</code>.<br/>
<code>r.aire()</code> effectue le calcul.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le résultat du calcul, les parenthèses étant facultatives</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un appel exige des parenthèses, même sans argument.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, l'attribut <code>aire</code> n'existant pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>aire</code> existe bien, c'est une méthode.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>None</code>, la méthode n'ayant pas encore été appelée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'expression a une valeur, la méthode.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q36 : Un attribut qui ne suit pas les autres</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Après ces instructions, <code>r.aire</code> vaut-il $40$ ?<br/>
<pre><code>class Rectangle:
    def __init__(self, largeur, hauteur):
        self.largeur = largeur
        self.hauteur = hauteur
        self.aire = largeur * hauteur

r = Rectangle(2, 4)
r.largeur = 10</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Stocker une valeur dérivée expose à l'incohérence ; la calculer<br/>
dans une méthode garantit qu'elle est toujours à jour.</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>Non, <code>aire</code> garde $8$, calculé une seule fois à la construction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'attribut <code>aire</code> est une valeur stockée, pas une<br/>
formule ; modifier <code>largeur</code> ne le recalcule pas. Une méthode<br/>
<code>aire()</code> qui calcule à la demande évite ce décalage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, Python recalcule les attributs qui dépendent d'autres attributs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun lien n'est conservé entre les attributs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, <code>largeur</code> ne pouvant être modifié après la construction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la modification est permise, c'est son effet qui est<br/>
incomplet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, mais seulement si <code>aire</code> a été défini après <code>largeur</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre dans <code>__init__</code> ne crée aucune dépendance<br/>
durable.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q37 : Une classe sans constructeur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Peut-on créer un objet d'une classe définie sans méthode<br/>
<code>__init__</code> ?<br/>
<pre><code>class Point:
    pass

p = Point()</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le constructeur n'est qu'une méthode appelée juste après la<br/>
création ; sans lui, l'objet naît vide.</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>Oui, l'objet naît sans attribut, on peut lui en ajouter ensuite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>__init__</code> sert à initialiser, pas à créer ;<br/>
<code>p.x = 3</code> ajoute un attribut après coup. Écrire un constructeur<br/>
reste préférable pour que tous les objets aient les mêmes<br/>
attributs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, <code>__init__</code> est obligatoire pour toute classe instanciable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python fournit un constructeur par défaut, sans<br/>
paramètre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, mais l'objet ne pourra jamais recevoir le moindre attribut</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les attributs peuvent être ajoutés à tout moment.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, <code>Point()</code> renvoie <code>None</code> faute de constructeur défini</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>Point()</code> renvoie bien un objet de type <code>Point</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Classes et programmation objet — Q38 : Comparer deux objets avec l'opérateur d'égalité</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

print(Point(1, 2) == Point(1, 2))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour que <code>==</code> compare les attributs, la classe doit définir sa<br/>
propre règle d'égalité ; sinon, seul le même objet est égal à<br/>
lui-même.</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>False</code>, <code>==</code> comparant par défaut l'identité des objets</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans règle d'égalité définie dans la classe,<br/>
<code>==</code> compare l'identité des objets, comme <code>is</code>. Deux<br/>
constructions donnent deux objets différents, malgré des<br/>
attributs identiques.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>True</code>, les attributs <code>x</code> et <code>y</code> ayant les mêmes valeurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python ne compare pas les attributs de lui-même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, <code>==</code> ne s'appliquant pas aux objets d'une classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>==</code> s'applique à tout, mais avec un sens par défaut<br/>
qui surprend.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>None</code>, la comparaison n'étant pas définie pour cette classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la comparaison renvoie un booléen.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
