<?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="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>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>
  <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 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>
</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="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>
  <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 Voiture,<br/>
on peut créer plusieurs objets<br/>
Voiture distincts, chacun avec<br/>
ses propres caractéristiques.</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>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>
  <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>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>
</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="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>
  <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="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 self et<br/>
désigne l'instance sur<br/>
laquelle la méthode est<br/>
appelée.</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>Une définition de classe commence par le mot-clé class, le nom de la classe et deux-points. Le corps indenté contient ensuite les méthodes, comme __init__, ou simplement pass 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="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="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, puis le nom de la classe, suivi de deux-points et d'un corps indenté. L'instruction pass permet de signaler un corps vide.</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>
  <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>
</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 = 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="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>
  <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 = 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>
</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="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>
  <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="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 un appel get(v, marque)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucune fonction get ne lit ainsi un attribut, et marque sans guillemets désignerait une variable inexistante. On accède aux attributs d'un objet avec la notation pointée.</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 fait référence à la classe parente</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le paramètre self 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 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>
  <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>
</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>Les noms encadrés de doubles soulignés, comme __init__, désignent des méthodes que Python appelle de lui-même : __init__ 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="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>Détruire l'objet en fin de vie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode __init__ 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>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>
  <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>
</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/>
`<code>python<br/>
class Point:<br/>
    def __init__(self, x, y):<br/>
        self.x = x<br/>
        self.y = y<br/>
p = Point(3, 4)<br/>
print(p.x, p.y)<br/>
</code>`</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="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>
  <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="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>
</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/>
    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>
  <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="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/>
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>
</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="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>
  <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="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/>
v1 = Voiture("Renault"),<br/>
v2 = Voiture("Peugeot"), et<br/>
ainsi de suite. Chaque<br/>
instance reste indépendante.</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/>
    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="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="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 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>
  <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="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>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>
</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/>
`<code>python<br/>
class Point:<br/>
    def __init__(self, x, y):<br/>
        self.x = x<br/>
        self.y = y<br/>
    def distance(self, autre):<br/>
        return abs(self.x - autre.x) + abs(self.y - autre.y)<br/>
p = Point(1, 2)<br/>
q = Point(4, 6)<br/>
print(p.distance(q))<br/>
</code>`<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 p.distance(q), l'objet placé avant le point devient self, et l'argument entre parenthèses devient 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="100" format="html">
    <text><![CDATA[<p>7</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Dans l'appel p.distance(q), self désigne p et autre désigne q. La méthode calcule |1 - 4| + |2 - 6| = 3 + 4 = 7.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>5</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>5 serait la distance à vol d'oiseau, √3² + 4². 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 une méthode ne peut lire que les attributs de self</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une méthode peut lire les attributs de tout objet qu'elle reçoit : autre.x désigne l'attribut x de q, accessible par la notation pointée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car distance attend deux arguments et n'en reçoit qu'un</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le paramètre self n'est pas à fournir : Python lui donne automatiquement l'objet p. Le seul argument écrit, q, correspond au paramètre autre.</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="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/>
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 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>
  <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>
</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="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/>
(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>
  <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="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>
</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>La fonction type permet de vérifier la classe d'un objet : type(42) == int vaut True, et de même type(p) == Point vaut True lorsque p a été créé par 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>La classe Point</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction type renvoie la classe de l'objet passé en paramètre, ici Point : le test type(p) == Point vaut True.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La classe object</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>type ne renvoie pas une classe générale : il renvoie la classe précise à partir de laquelle l'objet a été créé, ici Point.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car type ne s'applique qu'aux entiers, flottants et chaînes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>type 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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La chaîne "p", nom de la variable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>type 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>
</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>`<code>python<br/>
class Compteur:<br/>
    def __init__(self):<br/>
        self.n = 0<br/>
    def incrementer(self):<br/>
        self.n += 1<br/>
c = Compteur()<br/>
c.incrementer()<br/>
c.incrementer()<br/>
print(c.n)<br/>
</code>`<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="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 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="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, pas 1.</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>
</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 type 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 à sorted pour choisir la clé de tri.</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>
  <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 type(42) renvoie &lt;class 'int'&gt;, et type("a") renvoie &lt;class 'str'&gt;. 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>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>
</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 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/>
class Noeud:<br/>
    def __init__(self, val, gauche=None, droite=None):<br/>
        val = val<br/>
        gauche = gauche<br/>
        droite = droite<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le constructeur affecte des<br/>
variables locales, qui<br/>
disparaissent dès la fin de<br/>
__init__. Sans écrire<br/>
self.val = val, l'objet<br/>
créé ne possède aucun<br/>
attribut : n.val provoque<br/>
une AttributeError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def Noeud(val, gauche=None, droite=None):<br/>
    return {"val": val, "gauche": gauche, "droite": droite}<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette définition est une<br/>
fonction, et non une<br/>
classe : aucun type Noeud<br/>
n'est créé. Le dictionnaire<br/>
renvoyé s'utilise avec<br/>
n["val"] au lieu de<br/>
n.val et n'a aucune<br/>
méthode propre aux nœuds.</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 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>
<p>``python<br/>
class Compteur:<br/>
    def __init__(self):<br/>
        self.valeur = 0</p>
<p>def incrementer(self):<br/>
        self.valeur = self.valeur + 1</p>
<p>a = Compteur()<br/>
b = a<br/>
c = Compteur()<br/>
a.incrementer()<br/>
b.incrementer()<br/>
c.incrementer()<br/>
print(a.valeur, b.valeur, c.valeur)<br/>
``</p>
<p>Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Seul l'appel Compteur() crée un objet. L'affectation b = a 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>1 1 1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'affectation b = a ne copie pas l'objet : a et b désignent le même compteur. Il est donc incrémenté deux fois, par a puis par b.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>2 2 1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>a et b désignent le même objet, incrémenté deux fois : sa valeur est 2, lue par a.valeur comme par b.valeur. c est un autre objet, incrémenté une fois.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2 2 2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque appel à Compteur() crée un nouvel objet : c est un compteur distinct, incrémenté une seule fois. Seuls a et b partagent le même objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car b n'a pas été créé par Compteur()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La variable b désigne l'objet créé pour a ; on peut appeler ses méthodes exactement comme avec a. Le programme s'exécute sans erreur.</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>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="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="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 self, 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>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>
  <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 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>
</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="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/>
class Compte:<br/>
    def __init__(self, solde_initial=0):<br/>
        self.solde = solde_initial<br/>
    def deposer(self, montant):<br/>
        self.solde += montant<br/>
    def retirer(self, montant):<br/>
        self.solde -= montant<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code s'exécute,<br/>
mais retirer 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/>
deposer.</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>
  <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>
</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 File range ses éléments dans la liste self.elements,<br/>
les nouveaux étant ajoutés en fin de liste par append. Quelle<br/>
ligne complète la méthode defiler, 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="0" format="html">
    <text><![CDATA[<p>return self.elements.pop()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans argument, pop retire le dernier arrivé ; ce<br/>
serait une pile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>return self.elements.pop(0)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le plus ancien est en tête de liste, à l'indice<br/>
0 ; pop(0) le retire et le renvoie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>return self.elements.remove(0)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : remove(0) cherche la valeur 0, pas l'indice, et ne<br/>
renvoie rien.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>return self.elements[0]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'élément est lu mais reste dans la file.</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 est_vide d'une<br/>
classe Pile dont les éléments sont dans la liste<br/>
self.elements ?</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="0" format="html">
    <text><![CDATA[<p>return self.elements == None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste vide n'est pas None ; ce test répond<br/>
toujours False.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>return len(self.elements) == 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la comparaison renvoie un booléen, True quand<br/>
la liste est vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>return len(self.elements)</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 True.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>return self.elements.pop() is None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tester ne doit rien retirer, et pop 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 a.plus(b) ?<br/>
``python<br/>
class Rationnel:<br/>
    def __init__(self, n, d):<br/>
        self.n = n<br/>
        self.d = d</p>
<p>def plus(self, autre):<br/>
        return Rationnel(self.n <em> autre.d + autre.n </em> self.d,<br/>
                        self.d * autre.d)</p>
<p>a = Rationnel(1, 2)<br/>
b = Rationnel(1, 3)<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une méthode qui renvoie un nouvel objet au lieu de modifier self<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="0" format="html">
    <text><![CDATA[<p>Rationnel(2, 5), 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>Rationnel(1, 6), 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="100" format="html">
    <text><![CDATA[<p>Rationnel(5, 6), un nouvel objet, a et b 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 × 3 + 1 × 2 = 5 sur<br/>
2 × 3 = 6, sans simplifier, et construit un<br/>
troisième objet.</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 Rationnel(...) 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/>
``python<br/>
class Eleve:<br/>
    def __init__(self, nom, note):<br/>
        self.nom = nom<br/>
        self.note = note</p>
<p>eleves = [Eleve("Ana", 15), Eleve("Bob", 12)]<br/>
print(eleves[1].note)<br/>
``</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="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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Bob, le nom du second élève</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'attribut note qui est affiché, pas nom.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>15, la note du premier élève de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les indices commencent à 0, eleves[1] est le<br/>
second.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>12, la note du second élève de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : eleves[1] est le second objet, et .note lit<br/>
son attribut.</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/>
``python<br/>
class Panier:<br/>
    def __init__(self):<br/>
        self.articles = []</p>
<p>p1 = Panier()<br/>
p2 = Panier()<br/>
p1.articles.append("pain")<br/>
print(len(p2.articles))<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les attributs créés dans __init__ 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>0, chaque appel de __init__ créant une liste distincte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : [] est évalué à chaque construction ; p1 et<br/>
p2 ont chacun leur liste, et seule celle de p1 a reçu un<br/>
article.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, p2.articles n'existant pas encore</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : __init__ a créé l'attribut de p2 à sa<br/>
construction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1, 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 __init__, une fois par objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>None, la liste de p2 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>v est un objet de la classe Voiture, qui possède un attribut<br/>
vitesse. Que fait l'instruction v.vitesse = 50 ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un attribut est une variable attachée à un objet : la notation<br/>
objet.attribut 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 50 à l'attribut vitesse de l'objet v</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 donne la valeur 50 à la vitesse de toutes les voitures</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul l'objet v est concerné.</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 crée une variable globale vitesse valant 50</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le préfixe v. désigne l'attribut de l'objet, pas une<br/>
variable.</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/>
``python<br/>
class Personne:<br/>
    def __init__(self, nom):<br/>
        nom = nom</p>
<p>p = Personne("Ada")<br/>
print(p.nom)<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Dans une méthode, seules les variables préfixées par self.<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 AttributeError, l'attribut nom n'ayant jamais été créé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : nom = nom réaffecte la variable locale du<br/>
constructeur, sans toucher à l'objet. Il fallait écrire<br/>
self.nom = nom.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'affichage de Ada, Python ajoutant self. automatiquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'est automatique, un attribut doit être créé<br/>
explicitement sur self.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'affichage de None, 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>
  <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 : nom = nom est une affectation valide, inutile mais<br/>
valide.</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 Rectangle a une méthode aire qui renvoie le produit<br/>
de la largeur par la hauteur. Que vaut r.aire, sans parenthèses ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>r.aire et r.aire() 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="0" format="html">
    <text><![CDATA[<p>Une erreur, l'attribut aire n'existant pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aire existe bien, c'est une méthode.</p>]]></text>
    </feedback>
  </answer>
  <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 à &lt;bound method ...&gt;.<br/>
r.aire() effectue le calcul.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>None, 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>
  <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>
</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, r.aire vaut-il 40 ?<br/>
``python<br/>
class Rectangle:<br/>
    def __init__(self, largeur, hauteur):<br/>
        self.largeur = largeur<br/>
        self.hauteur = hauteur<br/>
        self.aire = largeur * hauteur</p>
<p>r = Rectangle(2, 4)<br/>
r.largeur = 10<br/>
``</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, aire garde 8, calculé une seule fois à la construction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'attribut aire est une valeur stockée, pas une<br/>
formule ; modifier largeur ne le recalcule pas. Une méthode<br/>
aire() 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, largeur 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 aire a été défini après largeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre dans __init__ 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/>
__init__ ?<br/>
``python<br/>
class Point:<br/>
    pass</p>
<p>p = Point()<br/>
``</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="0" format="html">
    <text><![CDATA[<p>Non, Point() renvoie None faute de constructeur défini</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Point() renvoie bien un objet de type Point.</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="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 : __init__ sert à initialiser, pas à créer ;<br/>
p.x = 3 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, __init__ 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>
</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/>
``python<br/>
class Point:<br/>
    def __init__(self, x, y):<br/>
        self.x = x<br/>
        self.y = y</p>
<p>print(Point(1, 2) == Point(1, 2))<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour que == 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>False, == 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/>
== compare l'identité des objets, comme is. 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>None, 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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>True, les attributs x et y 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, == ne s'appliquant pas aux objets d'une classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : == s'applique à tout, mais avec un sens par défaut<br/>
qui surprend.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
