Un corrigé pédagogique pour comprendre et justifier vos réponses. Les conseils de rédaction ne constituent pas un barème officiel détaillé.
Exercice 1 · 6 points
Compagnie de taxis : objets, durée, tarif et échange de clés
Une application Python gère une compagnie de taxis. Les constructeurs et méthodes suivants sont disponibles ; les noms d’attributs sont conservés exactement.
| Classe | Attributs initialisés |
|---|---|
| Chauffeur | nom (str), prenom (str), neph (str) : les trois paramètres du constructeur. Le NEPH est un identifiant de douze chiffres dans le contexte du sujet. |
| Client | nom (str), prenom (str), adresse (str), nb_personne (int) : les quatre paramètres. nb_personne compte les personnes accompagnant le client. |
| Taxi | immatriculation (str), type_vehicule (str), energie (str), adaptation (bool) : les quatre paramètres ; libre=True ; chauffeur=None. |
| Course | client (Client), taxi (Taxi), depart (str), destination (str) : les quatre paramètres ; date_depart=None et date_arrivee=None, destinées à recevoir des datetime. |
| Méthode | Contrat |
|---|---|
Taxi.est_libre() | Renvoie le booléen libre |
| Taxi.modifier_libre(statut) | Modifie libre, ne renvoie rien |
| Taxi.choix_chauffeur(chauffeur) | Affecte un objet Chauffeur, ne renvoie rien |
Course.distance() | Renvoie la distance du trajet en km (float) |
Course.temps() | Renvoie la durée du trajet en minutes (float) |
Les adresses sont des chaînes comme « 42 rue de l’Informatique, Octet-sur-Mer, France ». La capacité d’un véhicule compte les passagers en plus du conducteur. Les tarifs sont ceux de cet exercice :
vehicules = {
"standard": {
"capacite": 4,
"prix_km": 1.1,
"prise_en_charge": 3,
"tarif_horaire": 38
},
"monospace": {
"capacite": 8,
"prix_km": 1.8,
"prise_en_charge": 9,
"tarif_horaire": 60
},
"minibus": {
"capacite": 19,
"prix_km": 3,
"prise_en_charge": 50,
"tarif_horaire": 100
}
}energie = ["hybride", "électrique", "thermique"]Chaque classe est définie dans chauffeur.py, client.py, taxi.py ou course.py ; les données sont dans donnees.py, l’application dans application.py. Tous ces fichiers sont dans le même répertoire.
Question 1
#Écrire les imports dans application.py pour utiliser les données et les quatre classes.
Indice
Un fichier Python est importé par son nom de module sans extension.
Comprendre la correction
from donnees import vehicules, energie
from chauffeur import Chauffeur
from taxi import Taxi
from client import Client
from course import CourseLe nom du module est celui du fichier sans .py. Les noms des classes conservent leur majuscule. Ces imports permettent d’employer directement Chauffeur, Taxi, etc., sans préfixe de module. Les classes doivent aussi importer dans leur propre module les dépendances qu’elles utilisent : un import dans application.py ne crée pas automatiquement un nom global dans course.py.
Question 2
#Instancier le chauffeur John Doe, NEPH 140159320012.
Indice
Respectez les types et l’ordre du constructeur.
Comprendre la correction
john = Chauffeur("Doe", "John", "140159320012")Le NEPH est une chaîne conformément au contrat, même s’il ne contient que des chiffres. Le nom précède le prénom dans les paramètres. Aucun calcul arithmétique n’a de sens sur cet identifiant.
Question 3
#Créer le taxi HG-818-AV, standard électrique non adapté PMR, et l’attribuer à John Doe.
Indice
La relation taxi/chauffeur est une référence vers un objet, pas une chaîne.
Comprendre la correction
taxi_john = Taxi("HG-818-AV", "standard", "électrique", False)
taxi_john.choix_chauffeur(john)L’objet Chauffeur existant est transmis à la méthode ; on ne transmet pas uniquement son nom. False représente l’absence d’adaptation. La création initialise déjà libre à True.
Question 4
#Écrire l’assertion au début du constructeur de Course pour refuser un taxi occupé.
Indice
Appelez la méthode booléenne sur le taxi reçu en paramètre.
Comprendre la correction
assert taxi.est_libre(), "Ce taxi est déjà occupé"taxi désigne ici le paramètre du constructeur, disponible avant l’affectation éventuelle à self.taxi. Il faut appeler est_libre avec des parenthèses : tester l’objet méthode lui-même ne lirait pas son résultat. L’assertion exprime la précondition pédagogique ; dans un service concurrent réel, l’attribution nécessiterait une opération atomique pour empêcher deux réservations simultanées.
Question 5
#Ajouter l’instruction marquant le taxi occupé lors de la création de la course.
Indice
Le statut libre devient False dès l’affectation à la course.
Comprendre la correction
taxi.modifier_libre(False)Après validation de sa disponibilité, la création de la course réserve ce même objet Taxi. Si self.taxi a déjà été affecté, self.taxi.modifier_libre(False) est équivalent. Ne pas affecter le résultat de la méthode à une variable : son rôle est de modifier l’état et elle ne renvoie rien.
Question 6
#Créer la cliente Jeanne Doe accompagnée de ses deux enfants, puis sa course de 6 rue des ordinateurs, Paris à 211 avenue Jean Jaurès, Paris.
Indice
Relisez si le champ compte les accompagnants ou tous les passagers.
Comprendre la correction
jeanne = Client("Doe", "Jeanne",
"6 rue des ordinateurs, Paris, France", 2)
course_jeanne = Course(jeanne, taxi_john,
jeanne.adresse,
"211 avenue Jean Jaurès, Paris, France")nb_personne vaut 2 accompagnants, et non 3 : le contrat décrit les personnes en plus de la cliente. Il y a donc trois passagers au total, compatibles avec la capacité 4 du véhicule standard. La course référence la cliente et le taxi existants ; les dates ne sont pas encore renseignées.
from datetime import datetime
depart = datetime(2025, 7, 12, 9, 12)
arrivee = datetime(2025, 7, 12, 17, 12)
(arrivee - depart).total_seconds() # 28800.0Question 7
#Écrire Course.temps(), durée entre les deux dates en minutes.
Indice
La méthode datetime fournit des secondes, alors que le contrat demande des minutes.
Comprendre la correction
def temps(self):
return (self.date_arrivee - self.date_depart).total_seconds() / 60La soustraction de datetime produit un timedelta. total_seconds inclut toute la durée, y compris les jours éventuels ; diviser par 60 donne des minutes. L’attribut seconds seul ne représente pas toujours la durée totale. On suppose que les deux dates sont renseignées et que l’arrivée suit le départ.
Exemple : prise en charge 3 €, prix/km 1,10 €, tarif horaire 38 €, trajet 9,1 km en 19 min. Le montant attendu arrondi est 25,04 €.
def tarif(self):
type_vehicule = ...
donnees_tarifaire = vehicules[type_vehicule]
prise_en_charge = ...
tarif_h = ...
prix_km = ...
tarif = ...
tarif = tarif + prix_km * ...
tarif = tarif + tarif_h * ... / 60
return tarifQuestion 8
#Compléter Course.tarif selon la prise en charge, la distance et la durée.
Indice
Vérifiez les unités de chaque produit et distinguez attributs et méthodes.
Comprendre la correction
def tarif(self):
type_vehicule = self.taxi.type_vehicule
donnees_tarifaire = vehicules[type_vehicule]
prise_en_charge = donnees_tarifaire["prise_en_charge"]
tarif_h = donnees_tarifaire["tarif_horaire"]
prix_km = donnees_tarifaire["prix_km"]
tarif = prise_en_charge
tarif = tarif + prix_km * self.distance()
tarif = tarif + tarif_h * self.temps() / 60
return tarifLe type du véhicule permet de choisir le sous-dictionnaire des tarifs. La méthode distance renvoie des kilomètres et temps des minutes. Le terme horaire doit donc diviser ces minutes par 60. Pour 9,1 km et 19 minutes en standard : 3 + 1,10×9,1 + 38×19/60 = 25,0433… €, soit 25,04 € affichés au centime. Le programme demandé renvoie le calcul brut ; une politique d’arrondi monétaire relèverait de l’application.
Le module course.py doit avoir accès à vehicules, par exemple avec from donnees import vehicules. Les méthodes distance et temps doivent être appelées ; multiplier une méthode sans parenthèses serait une erreur de type.
Partie B : communication avec la centrale
L’application doit protéger les messages entre la centrale et les chauffeurs.
Question 9
#Distinguer les fonctionnements des chiffrements symétrique et asymétrique.
Indice
La différence porte sur le secret partagé ou la paire de clés complémentaires.
Comprendre la correction
Le symétrique partage un même secret pour chiffrer et déchiffrer. L’asymétrique utilise une paire de clés : un message chiffré pour un destinataire avec sa clé publique est déchiffré par sa clé privée, qu’il conserve secrète. La clé publique peut être connue de tous, mais son association au bon destinataire doit être authentifiée.
La centrale génère une clé symétrique aléatoire, l’envoie au chauffeur sans traitement, puis l’utilise pour chiffrer les messages.
Question 10
#Quel problème pose l’envoi direct de la clé de session avant les messages chiffrés ?
Indice
Un chiffrement ne protège plus les messages contre quelqu’un qui possède déjà sa clé.
Comprendre la correction
Un observateur qui intercepte la clé envoyée en clair peut ensuite déchiffrer les messages de cette session. Le fait que la clé soit aléatoire ne protège pas sa transmission. Il faut préserver son secret pendant l’établissement de la communication, pas seulement chiffrer les données suivantes.
Question 11
#Proposer une stratégie détaillée pour transmettre la clé de session de façon sûre tout en gardant un chiffrement rapide des échanges.
Indice
Le message chiffré avec la clé publique du chauffeur doit être ouvert uniquement par sa clé privée.
Comprendre la correction
Le chauffeur possède une paire asymétrique et garde sa clé privée secrète. La centrale obtient sa clé publique et vérifie son authenticité, par exemple par un certificat validé. Elle génère la clé symétrique de session et la chiffre avec cette clé publique ; le chauffeur la récupère avec sa clé privée. Les deux parties utilisent ensuite la clé de session pour un chiffrement symétrique authentifié des messages, adapté aux gros volumes.
L’asymétrique sert ainsi à établir ou protéger le secret de session, tandis que le symétrique traite le trafic courant. Sans authentification de la clé publique, un attaquant actif pourrait lui substituer la sienne. En pratique, on s’appuie sur un protocole éprouvé comme TLS plutôt que d’assembler soi-même ce dialogue ; l’exercice décrit le principe hybride.
Lire le détail d’un tarif de courseUn atelier pour expérimenter
Choisissez le véhicule, la distance et la durée. Le modèle sépare la prise en charge, les kilomètres et le temps pour repérer les erreurs de conversion.
Lire le résultat de l’expérience initiale
Montant : 25.04 €
La durée entre dans le calcul horaire sous la forme minutes/60. Les tarifs sont exclusivement ceux de l’exercice.
| Composante | Calcul | Montant (€) |
|---|---|---|
| Prise en charge | 3 | 3.00 |
| Distance | 1.1 × 9.1 | 10.01 |
| Durée | 38 × 19/60 | 12.03 |
La structure objet relie une course à son taxi ; le sous-dictionnaire de tarifs et les unités complètent le calcul.
Exercice 2 · 6 points
VintagePixel : collection relationnelle et choix des routes
Ada restaure des ordinateurs des années 1980 et 1990. Elle gère d’abord la relation ordinateur(id_ordi INT, marque TEXT, modele TEXT, etat TEXT), de clé primaire id_ordi. SQL autorise SELECT, FROM, WHERE, AND, OR, JOIN ... ON, INSERT, UPDATE, DELETE, DISTINCT, ORDER BY et COUNT(*).
| id_ordi | marque | modele | etat |
|---|---|---|---|
| 5 | Atari | 1040 ST | Fonctionnel |
| 6 | Commodore | Commodore 64 | Réparation |
| 7 | Sinclair | ZX Spectrum | Fonctionnel |
| 8 | Commodore | Amiga 500 | Fonctionnel |
| 9 | Apple | Apple IIe | Réparation |
| 10 | Commodore | Vic 20 | Fonctionnel |
| 11 | Sinclair | ZX 81 | Panne |
| 12 | Atari | 800 XL | Fonctionnel |
Question 1
#Lister les modèles en réparation de la collection.
SQLRetrouver les ordinateurs en réparationÉcrivez votre solution et mettez-la à l’épreuve
Renvoyez les modèles des ordinateurs dont l’état est Réparation, d’après la table ordinateur de la partie A. Panne et Fonctionnel sont des états distincts.
SELECT ...
FROM ...
WHERE ...;Les cas de test proposés :
- Collection officielle avant les mises à jour : Ces états sont ceux du premier tableau de l’exercice, avant la réparation ultérieure de l’Apple IIe.
- Cas complémentaire : panne ne veut pas dire réparation : Jeu complémentaire pédagogique, distinct des données officielles. Une seule ligne est en réparation. Le modèle est la colonne à afficher, la marque ne doit pas la remplacer.
Indice
Réparation et Panne sont deux valeurs distinctes du champ état.
Comprendre la correction
SELECT modele FROM ordinateur
WHERE etat = 'Réparation';Le filtre reprend exactement la valeur stockée. Dans l’extrait initial, les modèles sont Commodore 64 et Apple IIe. Le résultat ne contient ni les modèles simplement en panne, ni ceux déjà fonctionnels.
Question 2
#Insérer un Thomson MO5 en panne avec id_ordi 22.
Indice
Utilisez la structure de table en vigueur à cette étape de l’énoncé.
Comprendre la correction
INSERT INTO ordinateur (id_ordi, marque, modele, etat)
VALUES (22, 'Thomson', 'MO5', 'Panne');On renseigne les quatre attributs du schéma de la partie A. id_plat sera ajouté seulement dans la partie suivante.
Question 3
#L’Apple IIe d’identifiant 9 est restauré. Mettre son état à jour.
Indice
Une mise à jour individuelle doit être limitée à la bonne clé.
Comprendre la correction
UPDATE ordinateur
SET etat = 'Fonctionnel'
WHERE id_ordi = 9;La clé primaire cible l’ordinateur exact. Filtrer seulement la marque Apple pourrait modifier plusieurs machines.
SELECT COUNT(*) FROM ordinateur
WHERE marque = 'Commodore' AND etat = 'Fonctionnel';Question 4
#Donner COUNT(*) pour marque Commodore ET état Fonctionnel.
Indice
Les deux conditions doivent être satisfaites sur la même ligne.
Comprendre la correction
2 : Amiga 500 et Vic 20. Commodore 64 est en réparation, donc exclu. La restauration de l’Apple IIe ne change pas ce résultat puisque sa marque n’est pas Commodore.
Partie B : plateformes et jeux
| Ordinateur id_ordi | id_plat | État à cette étape |
|---|---|---|
| 5 | 2 | Fonctionnel |
| 6 | 1 | Réparation |
| 7 | 5 | Fonctionnel |
| 8 | 3 | Fonctionnel |
| 9 | 4 | Fonctionnel |
| 10 | 6 | Fonctionnel |
| 11 | 8 | Panne |
| 12 | 9 | Fonctionnel |
| id_jeu | titre | genre | etat | id_plat |
|---|---|---|---|---|
| 12 | Lemmings | Puzzle | Complet | 3 |
| 13 | Barbarian | Action | Sans notice | 1 |
| 14 | Populous | Stratégie | Complet | 2 |
| 15 | Knight Lore | Aventure | Loose | 5 |
| 16 | Dungeon Master | RPG | Complet | 2 |
| id_plat | nom | bits |
|---|---|---|
| 1 | C64 | 8 |
| 2 | Atari ST | 16 |
| 3 | Amiga | 16 |
| 4 | Apple II | 8 |
| 5 | Spectrum | 8 |
Ce sont des extraits : les plateformes 6,8,9 référencées peuvent exister sans être affichées.
Question 5
#Donner les schémas relationnels avec domaines de jeu et plateforme.
Indice
Déduisez les domaines des valeurs fournies sans oublier les clés.
Comprendre la correction
| Relation | Schéma et domaines | Clé primaire | Clé étrangère |
|---|---|---|---|
| jeu | id_jeu INT, titre TEXT, genre TEXT, etat TEXT, id_plat INT | id_jeu | id_plat → plateforme.id_plat |
| plateforme | id_plat INT, nom TEXT, bits INT | id_plat | - |
id_plat a le même domaine entier dans les tables qui le référencent. Les états des jeux (« Complet », « Sans notice », « Loose ») sont des textes. La relation ordinateur possède désormais elle aussi une clé étrangère id_plat vers plateforme.id_plat.
Question 6
#Lister les titres compatibles avec la plateforme Oric présents dans la collection.
Indice
Reliez le jeu à sa plateforme puis filtrez son nom.
Comprendre la correction
SELECT j.titre
FROM jeu AS j
JOIN plateforme AS p ON j.id_plat = p.id_plat
WHERE p.nom = 'Oric';Le nom de plateforme ne se trouve pas dans jeu, donc la jointure est nécessaire. Oric n’apparaît pas dans l’extrait, mais on ne conclut pas qu’il est absent de la base entière. La requête ne limite pas les jeux à un état particulier.
Question 7
#Lister les titres compatibles avec le modèle Amstrad 6128 de la collection.
Indice
Le lien passe par l’égalité de plateforme, pas par le nom du constructeur.
Comprendre la correction
SELECT DISTINCT j.titre
FROM jeu AS j
JOIN ordinateur AS o ON j.id_plat = o.id_plat
WHERE o.modele = 'Amstrad 6128';La compatibilité est modélisée par une même plateforme : les deux clés étrangères peuvent donc être comparées directement. Une jointure supplémentaire avec plateforme serait correcte mais inutile pour ce résultat. DISTINCT évite les répétitions si Ada possède plusieurs exemplaires du modèle. L’état de fonctionnement de l’ordinateur n’est pas un critère de compatibilité demandé.
Partie C : serveurs de jeux en réseau
VintagePixel relie des serveurs A (arcade, via R1), S (stratégie, via R3), P (plateforme, via R7), C (course, via R4). Ada est reliée au LAN de R6 ; Alan et Grace partagent un switch et le LAN de R8. Grace possède 192.168.208.11 avec masque 255.255.255.240. Les liaisons inter-routeurs du dessin sont :
| Liaison | Technologie |
|---|---|
| R1-R3 | FE |
| R1-R6 | FE |
| R2-R3 | E |
| R2-R6 | F |
| R2-R5 | F |
| R2-R4 | F |
| R6-R5 | F |
| R6-R7 | E |
| R5-R4 | FE |
| R5-R8 | FE |
| R4-R8 | E |
| R7-R8 | FE |
Lire les connexions du schéma
- R1 relié à R3 : FE
- R1 relié à R6 : FE
- R2 relié à R3 : E
- R2 relié à R6 : F
- R2 relié à R5 : F
- R2 relié à R4 : F
- R6 relié à R5 : F
- R6 relié à R7 : E
- R5 relié à R4 : FE
- R5 relié à R8 : FE
- R4 relié à R8 : E
- R7 relié à R8 : FE
F : fibre 1 Gbit/s ; FE : Fast Ethernet 100 Mbit/s ; E : Ethernet 10 Mbit/s. Alan ne parvient d’abord pas à se connecter au réseau local.
Question 8
#Quelle commande Alan doit-il utiliser pour tester la connectivité vers Grace ?
Indice
Le test vise l’adresse IP de la machine de Grace.
Comprendre la correction
ping 192.168.208.11ping envoie des requêtes d’écho vers cette adresse. Des réponses confirment une connectivité IP pour ce test. Une absence de réponse n’identifie pas à elle seule la cause : configuration, liaison, pare-feu ou filtrage ICMP peuvent intervenir.
Question 9
#Convertir 240 en binaire, puis déterminer le nombre de machines encore ajoutables sur ce LAN.
Indice
Comptez les adresses utilisables, puis celles des deux ordinateurs et de la passerelle.
Comprendre la correction
240 = 11110000₂. Le masque fixe 28 bits, donc le réseau 192.168.208.0/28 contient 16 adresses dont 14 utilisables (.1 à .14). Alan et Grace en occupent deux. L’interface LAN du routeur R8 en utilise aussi une pour permettre l’accès aux autres réseaux : il reste donc 11 adresses pour de nouvelles machines, en supposant aucun autre équipement IP sur ce LAN.
Si l’on ne décomptait que les deux ordinateurs, on obtiendrait 12, mais on oublierait l’adresse nécessaire de la passerelle R8 dessinée. Un switch non administré n’a pas besoin d’une adresse IP pour commuter les trames ; un switch administré pourrait en consommer une supplémentaire, ce que le sujet ne précise pas.
La table initiale fournit R5 via R5 en1 saut, R6 via R7 en2 sauts et R7 via R7 en1 saut.
Question 10
#Compléter les quatre premières lignes de la table RIP simplifiée de R8 : destinations R1 à R4.
Indice
La colonne de passerelle indique seulement le premier routeur du chemin.
Comprendre la correction
| Destination | Routeur suivant possible | Sauts |
|---|---|---|
| R1 | R5 ou R7 | 3 |
| R2 | R5 ou R4 | 2 |
| R3 | R5 ou R4 | 3 |
| R4 | R4 | 1 |
| R5 | R5 | 1 |
| R6 | R7 (fourni) ou R5 | 2 |
| R7 | R7 | 1 |
RIP compte uniquement les liaisons. Pour R1, R8-R5-R6-R1 et R8-R7-R6-R1 sont ex æquo. Pour R3, les routes via R5-R2 ou R4-R2 ont trois liens. Le lien lent direct R8-R4 reste le plus court en sauts vers R4.
Question 11
#Donner un chemin possible pour un message d’Alan vers Ada.
Indice
Alan rejoint R8 et Ada est sur le réseau de R6.
Comprendre la correction
Alan → switch local → R8 → R5 → R6 → Ada. Le trajet R8-R7-R6 est aussi un plus court chemin en deux liaisons inter-routeurs sous RIP. Les liens Ethernet/Fast Ethernet/fibre ne modifient pas le nombre de sauts.
OSPF utilise les coûts F=1, FE=10 et E=100.
Question 12
#Avec OSPF, déterminer le chemin de R8 à R3 pour Grace vers le serveur S et son coût.
Indice
Le lien R2-R3 est Ethernet, donc de coût100, contrairement aux fibres autour de R2.
Comprendre la correction
R8 → R5 → R6 → R1 → R3, coût 10 + 1 + 10 + 10 = 31. Le trajet à trois liens R8-R5-R2-R3 coûte 10+1+100 = 111 ; la liaison R2-R3 est donc à éviter. Passer de R5 à R6 directement coûte1, moins que R5-R2-R6 de coût2. L’itinéraire retenu utilise plus de sauts mais minimise leur somme pondérée.
RIP et OSPF sur les serveurs VintagePixelUn atelier pour expérimenter
Choisissez la destination et la métrique. Le modèle compare tous les chemins simples du petit réseau et affiche les meilleures routes, y compris les égalités.
Lire le résultat de l’expérience initiale
Coût minimal : 31
Une ligne correspond à une route ; seules les dix meilleures sont affichées. Le coût RIP est le nombre de liens, le coût OSPF la somme des poids.
| Route | Coût | Statut |
|---|---|---|
| R8 → R5 → R6 → R1 → R3 | 31 | Optimale |
| R8 → R5 → R2 → R6 → R1 → R3 | 32 | Plus coûteuse |
| R8 → R5 → R4 → R2 → R6 → R1 → R3 | 42 | Plus coûteuse |
| R8 → R5 → R2 → R3 | 111 | Plus coûteuse |
| R8 → R5 → R6 → R2 → R3 | 112 | Plus coûteuse |
| R8 → R5 → R4 → R2 → R3 | 121 | Plus coûteuse |
| R8 → R4 → R2 → R6 → R1 → R3 | 122 | Plus coûteuse |
| R8 → R4 → R2 → R5 → R6 → R1 → R3 | 123 | Plus coûteuse |
| R8 → R7 → R6 → R1 → R3 | 130 | Plus coûteuse |
| R8 → R4 → R5 → R6 → R1 → R3 | 131 | Plus coûteuse |
La route optimale dépend de la métrique ; les égalités doivent être reconnues plutôt que cachées.
Revoir les notions de cet exercice
- Comprendre le modèle relationnel
- Clés primaires, clés étrangères et contraintes d’intégrité
- SQL : sélectionner, filtrer et trier des résultats
- SQL : comprendre et écrire des jointures
- SQL : insérer, modifier et supprimer des données
- Comprendre et construire un réseau local
- Tables de routage et protocole RIP
- Le protocole OSPF et le coût des routes
Exercice 3 · 8 points
Architecture, additionneur binaire et mémoire tampon circulaire
Les deux parties sont indépendantes. La première étudie une architecture à programme enregistré, où la RAM contient instructions et données, puis quelques opérations d’assembleur et un circuit logique. La seconde modélise un tampon FIFO par un tableau circulaire. Les règles d’assembleur sont celles du modèle simplifié du sujet.
Question 1
#Quel scientifique donne son nom au modèle d’architecture de 1945 présenté ?
Indice
Le nom attendu est celui de l’architecture à mémoire commune instructions/données.
Comprendre la correction
John von Neumann. Le modèle porte son nom et partage une même mémoire pour le programme et ses données. Cette désignation historique ne signifie pas que toute l’informatique à programme enregistré résulte du travail d’une seule personne.
Figure1 reconstruite par ses blocs : à gauche le bloc1 ; à droite une enveloppe2 contenant le bloc3 au-dessus du bloc4. L’accumulateur est dans4. La RAM échange avec3 et4 ; 3 et4 échangent entre eux ; entrées et sorties rejoignent le bloc4.
[1 : mémoire] ⇄ [2 : processeur]
├─ [3 : contrôle]
└─ [4 : calcul + accumulateur] ⇄ Entrées / SortiesQuestion 2
#Associer Mémoire RAM, Processeur, Unité arithmétique et logique et Unité de contrôle aux numéros1 à4.
Indice
Le processeur est l’ensemble qui contient les deux unités internes.
Comprendre la correction
| Numéro | Composant |
|---|---|
| 1 | Mémoire RAM |
| 2 | Processeur |
| 3 | Unité de contrôle |
| 4 | Unité arithmétique et logique (UAL) |
Le grand bloc2 regroupe l’unité de contrôle et l’UAL. Le bloc4 contient l’accumulateur et réalise les opérations sur les données. La RAM échange instructions et données avec le processeur ; les entrées/sorties sont reliées comme indiqué sur le schéma.
Question 3
#Que signifie RAM volatile ?
Indice
Comparez la conservation des données après arrêt de la machine.
Comprendre la correction
Son contenu est perdu lorsque l’alimentation électrique n’est plus maintenue. Une sauvegarde sur un support non volatil, comme un disque, est nécessaire pour conserver les informations après extinction. Volatile ne signifie pas que le contenu change aléatoirement pendant un fonctionnement normal.
Question 4
#Classer registre, cache, RAM et disque dur du plus rapide au plus lent.
Indice
Le registre est directement dans le processeur.
Comprendre la correction
Registre → mémoire cache → mémoire vive (RAM) → disque dur. Cette hiérarchie rapproche les petites mémoires rapides du processeur et utilise des stockages plus grands mais plus lents pour le reste. Elle décrit l’ordre attendu dans le modèle du cours.
Le processeur n’exécute pas directement le texte Python. Un langage assembleur donne des noms lisibles à des opérations proches du langage machine. Le modèle du sujet dispose de huit registres r1 à r8 et d’étiquettes qui repèrent des instructions.
| Instruction | Effet du modèle |
|---|---|
| addi rA,rB,v | rA ← rB + valeur immédiate v |
| add rA,rB,rC | rA ← rB + rC |
| sub rA,rB,rC | rA ← rB - rC |
| beq rA,rB,label | Saut si rA = rB |
| bne rA,rB,label | Saut si rA ≠ rB |
| bgt rA,rB,label | Saut si rA > rB |
| ble rA,rB,label | Saut si rA ≤ rB |
Exemple : si r7>r6, affecter r2+3 à r5, puis dans tous les cas incrémenter r5 :
ble r7, r6, SUITE
addi r5, r2, 3
SUITE:
addi r5, r5, 1Question 5
#Écrire l’instruction mettant dans r2 la valeur de r5 moins celle de r4.
Indice
La syntaxe est destination, premier terme, second terme.
Comprendre la correction
sub r2, r5, r4Le registre destination est le premier opérande. L’ordre des deux sources compte : r5-r4 n’est pas interchangeable avec r4-r5.
Question 6
#Expliquer l’instruction imprimée add r1 r2 0.
Indice
Distinguez add à trois registres et addi avec une valeur immédiate.
Comprendre la correction
L’intention est de copier la valeur de r2 dans r1, en lui ajoutant zéro. Mais selon la distinction fournie dans le tableau, add attend trois registres et 0 n’est pas un des registres r1 à r8. L’écriture cohérente avec le modèle est addi r1, r2, 0. Si une notation désigne explicitement un registre zéro, une addition avec ce registre peut aussi copier une valeur ; cette convention n’est pas définie dans le sujet.
Question 7
#Échanger r1 et r2 avec r3 temporaire.
Indice
Sauvegardez la valeur qui serait écrasée par la première affectation.
Comprendre la correction
addi r3, r1, 0
addi r1, r2, 0
addi r2, r3, 0La première instruction sauvegarde r1 dans r3 avant qu’il soit écrasé. La seconde copie r2 dans r1 ; la troisième remet l’ancienne valeur de r1 dans r2. r3 est modifié, ce qui est autorisé. Deux copies sans sauvegarde perdraient la première valeur.
La figure2 fournit les portes classiques. NOT inverse un bit. Pour les entrées (a,b) dans l’ordre00,01,10,11 :
| Porte | Sorties pour00,01,10,11 |
|---|---|
AND | 0,0,0,1 |
| NAND | 1,1,1,0 |
OR | 0,1,1,1 |
| NOR | 1,0,0,0 |
| XOR | 0,1,1,0 |
| NXOR | 1,0,0,1 |
Figure3 : E1 et E2 entrent dans un premier XOR ; son résultat et Re entrent dans un second XOR qui donne S. Un AND relie le premier XOR à Re ; un autre AND relie E1 et E2 ; leurs sorties entrent dans un OR qui donne Rs. Cette reconstruction conserve tous les fils utiles du circuit.
AND Re, Z = E1 AND E2Lire les connexions du schéma
- E1 vers X
- E2 vers X
- E1 vers Z
- E2 vers Z
- X vers Y
- Re vers Y
- X vers S
- Re vers S
- Y vers Rs
- Z vers Rs
| E1 | E2 | Re | Rs | S |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | A | B |
| 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 0 | 1 | C | 0 |
| 1 | 1 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | D |
Question 8
#Compléter A,B,C,D dans la table de vérité du circuit.
Indice
La sortie S est un XOR à trois entrées ; Rs vaut1 si au moins deux entrées valent1.
Comprendre la correction
A=0, B=1, C=1, D=1. Posons X = E1 XOR E2. Le schéma calcule S = X XOR Re et Rs = (E1 AND E2) OR (X AND Re). Pour 0,0,1 : X=0, S=1 et Rs=0. Pour 1,0,1 : X=1, S=0 et Rs=1. Pour 1,1,1 : X=0, S=1 et Rs=1.
| E1 | E2 | Re | Rs | S |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
Question 9
#Que fait ce circuit d’après la table complétée ?
Indice
Interprétez le couple (Rs,S) comme un nombre binaire de deux bits.
Comprendre la correction
C’est un additionneur complet d’un bit. Il additionne E1, E2 et une retenue entrante Re. S est le bit de somme et Rs la retenue sortante : E1 + E2 + Re = 2×Rs + S. Par exemple1+1+1=3 s’écrit11 en binaire, donc Rs=1 et S=1. On peut chaîner plusieurs circuits en transmettant la retenue à l’étage du bit suivant.
Partie B : mémoire tampon
Un tampon stocke temporairement des données pour synchroniser deux processus de rythmes différents. Il fonctionne comme une file, en conservant l’ordre d’enregistrement.
Question 10
#FIFO ou LIFO : quel terme correspond à une file ?
Indice
La sortie suit l’ordre chronologique des entrées.
Comprendre la correction
FIFO, First In First Out : premier entré, premier sorti. Un tampon conserve ainsi l’ordre des données reçues même si producteur et consommateur travaillent à des rythmes différents.
Dans le tableau circulaire, fin est l’indice du prochain emplacement d’ajout, exclu de la file actuelle. Après la dernière case, il revient à0. Retirer avance debut sans effacer la case. Le sujet garantit que le tampon n’atteint jamais sa capacité maximale : debut=fin signifie uniquement vide. Figure4, trace complète :
| Opération | Contenu physique | debut | fin | Valeur retirée |
|---|---|---|---|---|
| Initial | [None,None,None,None,None] | 0 | 0 | - |
| Ajouter1 | [1,None,None,None,None] | 0 | 1 | - |
| Ajouter2 | [1,2,None,None,None] | 0 | 2 | - |
| Ajouter3 | [1,2,3,None,None] | 0 | 3 | - |
| Retirer | [1,2,3,None,None] | 1 | 3 | 1 |
| Retirer | [1,2,3,None,None] | 2 | 3 | 2 |
| Retirer | [1,2,3,None,None] | 3 | 3 | 3 |
| Ajouter4 | [1,2,3,4,None] | 3 | 4 | - |
| Ajouter5 | [1,2,3,4,5] | 3 | 0 | - |
| Ajouter6 | [6,2,3,4,5] | 3 | 1 | - |
| Retirer | [6,2,3,4,5] | 4 | 1 | 4 |
| Retirer | [6,2,3,4,5] | 0 | 1 | 5 |
class Tampon:
def __init__(self, capacite):
self.capacite = capacite
self.contenu = [None for i in range(capacite)]
self.debut = 0
self.fin = 0
def ajouter_element(self, element):
self.contenu[self.fin] = element
self.fin += 1
if self.fin == self.capacite:
self.fin = 0
def retirer_element(self):
...
def est_vide(self):
return ...Question 11
#Que vaut memoire.contenu après memoire = Tampon(5) ?
Indice
La capacité fixe la longueur physique, pas le nombre d’éléments en attente.
Comprendre la correction
[None, None, None, None, None]Le tableau physique possède toujours cinq cases. La file logique est vide parce que debut et fin valent tous deux0. Les cases None ne constituent pas les éléments de la file ; ce sont seulement les valeurs initiales de stockage.
Figure 5 : contenu = [4,6,9,None,None], debut=0, fin=3. Les opérations a à g s’enchaînent sur ce même tampon de capacité 5 ; retirer ne supprime jamais la valeur physique de la liste.
Question 12a
#À partir de la figure5, retirer un élément. Donner état et retour.
Indice
Seul debut avance après lecture de la tête.
Comprendre la correction
Retour 4. Contenu inchangé [4,6,9,None,None] ; debut=1, fin=3. La file logique restante est [6,9]. Le4 reste en mémoire mais n’appartient plus à la file.
Question 12b
#Puis ajouter10. Donner le nouvel état.
Indice
On écrit à l’ancien indice fin, puis on avance fin.
Comprendre la correction
Contenu [4,6,9,10,None] ; debut=1, fin=4. La file logique est [6,9,10]. L’ajout n’a pas de valeur de retour utile.
Question 12c
#Puis retirer un élément. Donner état et retour.
Indice
La tête est désormais la case d’indice1.
Comprendre la correction
Retour 6. Contenu [4,6,9,10,None] ; debut=2, fin=4. File logique [9,10].
Question 12d
#Puis retirer un élément. Donner état et retour.
Indice
On avance encore debut sans effacer la case physique.
Comprendre la correction
Retour 9. Contenu [4,6,9,10,None] ; debut=3, fin=4. File logique [10].
Question 12e
#Puis ajouter3. Donner le nouvel état.
Indice
Après l’indice4 dans une capacité5, l’indice suivant est0.
Comprendre la correction
Contenu [4,6,9,10,3] ; debut=3, fin=0. La file logique est [10,3]. Le prochain emplacement d’ajout revient au début du tableau, car l’ancienne fin était l’indice4.
Question 12f
#Puis retirer un élément. Donner état et retour.
Indice
Un indice fin plus petit que debut est normal dans un tableau circulaire.
Comprendre la correction
Retour 10. Contenu [4,6,9,10,3] ; debut=4, fin=0. La file logique contient seulement [3].
Question 12g
#Enfin retirer un élément. Donner état et retour.
Indice
La tête revient à0 et rejoint la fin.
Comprendre la correction
Retour 3. Contenu [4,6,9,10,3] ; debut=0, fin=0. La file est désormais vide même si la liste physique contient cinq nombres. C’est l’égalité des indices, et non les valeurs stockées, qui définit cet état dans le modèle.
memoire = Tampon(5)
memoire.ajouter_element("n")
memoire.ajouter_element("s")
memoire.ajouter_element("i")
memoire.retirer_element()
memoire.ajouter_element("n")
memoire.ajouter_element("f")
memoire.retirer_element()
memoire.ajouter_element("o")Question 13
#Donner contenu après le programme de caractères n,s,i, retrait, n,f, retrait, o.
Indice
La question demande la liste physique contenu, pas seulement la file logique restante.
Comprendre la correction
["o", "s", "i", "n", "f"]Les ajouts remplissent d’abord les indices0,1,2. Le premier retrait avance debut à1. Les ajouts n et f occupent3 et4, puis fin revient à0. Le second retrait avance debut à2. Enfin o remplace l’ancien n à l’indice0 et fin devient1. La file logique est donc ["i","n","f","o"] avec debut=2 et fin=1 ; l’ancien s reste physiquement à l’indice1 mais est hors de la file.
Question 14
#Compléter est_vide.
Indice
Le contenu des cases n’indique pas quelles valeurs appartiennent encore à la file.
Comprendre la correction
return self.debut == self.finCette égalité est suffisante sous l’hypothèse du sujet que la capacité maximale n’est jamais atteinte. Sans cette hypothèse, le même couple d’indices pourrait désigner vide ou plein ; il faudrait un compteur, un indicateur supplémentaire ou garder une case inutilisée.
Question 15
#Écrire retirer_element, file supposée non vide, sans effacer réellement la valeur.
PythonRetirer un élément en avançant dans une mémoire circulaireÉcrivez votre solution et mettez-la à l’épreuve
Complétez retirer_element dans Tampon. La file est supposée non vide et les ajouts des tests ne la saturent jamais : la représentation donnée n’a pas de compteur pour distinguer vide et plein. Renvoyez la valeur en tête, avancez debut avec retour à zéro après la dernière case, et ne modifiez ni contenu ni fin. Il ne faut pas effacer physiquement l’ancienne valeur ni décaler les autres cases.
class Tampon:
def __init__(self, capacite):
self.capacite = capacite
self.contenu = [None for _ in range(capacite)]
self.debut = 0
self.fin = 0
def ajouter_element(self, element):
self.contenu[self.fin] = element
self.fin = (self.fin + 1) % self.capacite
def est_vide(self):
return self.debut == self.fin
def retirer_element(self):
# Lisez la tête, puis avancez debut
passLes cas de test proposés :
- Lire avant d’avancer : La valeur de tête est à l’ancienne position de debut, pas à la nouvelle.
- Respecter FIFO et retrouver une file vide : Trois retraits suivent l’ordre d’arrivée, et debut finit par rejoindre fin.
- Passer de la dernière case à zéro : Le retrait de D à l’indice 3 doit replier debut vers 0, où se trouve E.
- Ne pas effacer la mémoire : La case A devient logiquement libre, mais sa valeur peut rester jusqu’au prochain écrasement.
- La queue ne bouge pas lors d’un retrait : fin désigne le prochain emplacement d’insertion ; seul debut change ici.
Indice
Sauvegardez la valeur de tête, avancez circulairement puis renvoyez la valeur sauvegardée.
Comprendre la correction
def retirer_element(self):
element = self.contenu[self.debut]
self.debut += 1
if self.debut == self.capacite:
self.debut = 0
return elementLa tête est lue avant d’avancer son indice. On replie l’indice après la dernière case. L’écriture équivalente self.debut = (self.debut + 1) % self.capacite exprime le même comportement. Aucun décalage des autres valeurs n’est effectué : l’opération a un coût constant, contrairement à un pop(0) sur une liste Python. Un appel sur file vide devrait être refusé dans une interface complète, mais le sujet garantit la précondition.
Voir le tableau physique et la file logique séparémentUn atelier pour expérimenter
Choisissez l’un des deux programmes du sujet et avancez dans ses opérations. Les valeurs hors de la file restent visibles pour comprendre pourquoi elles ne sont pas forcément effacées.
Lire le résultat de l’expérience initiale
File logique : [4, 6, 9]
Les indices définissent la file de debut inclus à fin exclu en tournant modulo5. Une case hors de cette zone peut conserver une ancienne valeur.
| Indice | Contenu physique | Dans la file ? | Repère |
|---|---|---|---|
| 0 | 4 | Oui | debut |
| 1 | 6 | Oui | |
| 2 | 9 | Oui | |
| 3 | None | Non | fin |
| 4 | None | Non |
Le tampon circulaire retire logiquement par un indice, sans déplacer ni effacer les données. Le rangement physique et l’ordre FIFO sont donc différents.
Du sujet à la méthode
Votre prochaine séance de révision
- Lorsque plusieurs modules interviennent, vérifiez où chaque nom est importé.
- Annoncez ce qui est compté : passagers, accompagnants, adresses IP, sauts ou coûts pondérés.
- Pour les mémoires circulaires, tracez toujours contenu, debut et fin dans trois colonnes distinctes.
Retrouver ces notions dans d’autres sujets
Toutes les annales de NSI · Le guide pour préparer le bac NSI 2027
Énoncé : sujet 26-NSIJ2G11 (PDF). Corrigé et explications pédagogiques proposés par Sofien.
