Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 517 minIntermédiaire

Situation A : méthode et sujet corrigé

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • organiser ton heure de préparation et tes 20 minutes d'oral ;
  • vérifier ton travail avec les huit critères du référentiel ;
  • traiter un sujet complet, du pseudo-code au jeu d'essai ;
  • préparer les questions de l'entretien.

3 exercices corrigés1 schéma

La situation A est l'épreuve pratique d'algorithmique de l'E3 en CCF : une heure de préparation, 30 minutes sur table puis 30 minutes sur machine, suivie de 20 minutes d'oral avec le professeur qui t'a formé, pour un coefficient 1 sur 3. Ce chapitre résume la méthode en une page, puis la met en œuvre sur un sujet complet et corrigé, construit comme ceux de l'épreuve. Le cours d'algorithmique détaille chaque phase et chaque critère et propose trois autres sujets.

Le déroulement en bref

PhaseDuréeCe que tu faisCe qui est regardé
Préparation sur table30 minLire le sujet, écrire les algorithmes, préparer un jeu d'essaiTa trace écrite, que la commission peut examiner
Préparation sur machine30 minProgrammer, tester, corriger ; l'aide syntaxique de l'environnement est permiseTon programme et tes tests
Présentation10 min au plusExpliquer ta démarche, ton code, faire tourner les testsLa clarté, la pertinence de la solution
Entretien10 min au plusRépondre aux questions de la commissionTa compréhension, ta capacité à corriger

Les huit critères en une liste de contrôle

Le référentiel évalue la situation A sur huit critères. Avant de rendre ta trace écrite et avant de présenter, coche chaque ligne.

  1. Connaissances du module : les bonnes structures (boucle, condition, fonction, tableau) au bon endroit.
  2. Efficacité et pertinence de la solution : elle répond à la question posée, sans détour.
  3. Formalisme cohérent : mêmes conventions du début à la fin (affectation, indices, mots-clés).
  4. Lisibilité : indentation, noms parlants, commentaires, en-tête de chaque fonction.
  5. Efficacité de l'implémentation : pas de calcul répété inutilement, pas de boucle de trop.
  6. Composants fournis : tu les utilises au lieu de les réécrire, en respectant leurs paramètres.
  7. Tests de validation : un jeu d'essai avec des cas normaux et des cas limites, résultats attendus calculés à la main.
  8. Éléments de correction : tu sais expliquer et corriger une erreur, la tienne ou celle d'un algorithme fourni.

La méthode express

  • Minutes 0 à 5. Lis tout le sujet. Souligne entrées, sorties et contraintes. Lis l'interface des composants fournis (nom, paramètres, valeur renvoyée).
  • Minutes 5 à 25. Pour chaque question : une ligne « entrées → traitement → sortie », puis l'algorithme, proprement. Reconnais le motif : parcours, comptage, recherche, accumulation, conversion.
  • Minutes 25 à 30. Le jeu d'essai, avec les résultats attendus calculés à la main.
  • Minutes 30 à 55. Sur machine, une fonction à la fois : tu tapes, tu exécutes, tu testes. Garde tes tests dans le fichier.
  • Minutes 55 à 60. Relis : noms, commentaires, en-têtes. Note les erreurs trouvées : ce sont d'excellents sujets pour l'oral.

Sujet type : à quel VLAN appartient cette adresse ?

Sujet d'entraînement construit sur le modèle de la situation A ; ce n'est pas un sujet officiel.

Contexte. Le réseau du siège de Sorbier Logistique est découpé en VLAN. Chaque VLAN a une adresse de réseau et un masque (cours de réseaux, TP d'adressage IP). Le technicien veut un petit programme qui dit à quel VLAN appartient une adresse IPv4, pour contrôler les adresses relevées dans les journaux.

Une adresse appartient à un réseau quand le ET bit à bit entre l'adresse et le masque, octet par octet, redonne l'adresse du réseau.

1286432168421Octet de l'adresse0100011171Octet du masqueET11000000192Octet du réseau0100000064192.168.10.71 ET 255.255.255.192 = 192.168.10.64 (VLAN 10)
Le ET bit à bit entre l'adresse et le masque : 71 ET 192 = 64, donc 192.168.10.71 est dans le réseau 192.168.10.64/26

Composants fournis.

python
def octets(adresse):
    """Renvoie la liste des quatre entiers d'une adresse IPv4 écrite '192.168.10.71'."""
    return [int(x) for x in adresse.split(".")]


VLANS = [
    (10, "POSTES", "192.168.10.64", "255.255.255.192"),
    (20, "SERVEURS", "192.168.10.176", "255.255.255.240"),
    (21, "APPLIS", "192.168.21.0", "255.255.255.0"),
    (30, "ENTREPOT", "192.168.10.128", "255.255.255.224"),
    (40, "VISITEURS", "192.168.10.0", "255.255.255.192"),
    (50, "TELEPHONIE", "192.168.10.160", "255.255.255.240"),
    (60, "DMZ", "192.168.10.224", "255.255.255.240"),
    (99, "ADMIN", "192.168.10.208", "255.255.255.240"),
]

Chaque élément de VLANS est un tuple (numéro, nom, adresse du réseau, masque). L'opérateur & de Python calcule le ET bit à bit de deux entiers : 71 & 192 vaut 64.

Sur table (30 minutes).

  1. Écris une fonction binaire8(n) qui renvoie l'écriture binaire sur 8 bits d'un entier n compris entre 0 et 255, sous forme de chaîne, par divisions successives par 2 (sans utiliser bin ni format).
  2. Écris une fonction reseau(adresse, masque) qui renvoie l'adresse du réseau, sous forme de chaîne, en faisant le ET bit à bit octet par octet.
  3. Écris une fonction vlan_de(adresse) qui renvoie le numéro du VLAN qui contient l'adresse, ou 0 si aucun VLAN ne la contient.
  4. Prépare un jeu d'essai pour vlan_de : au moins six adresses, dont des cas limites, avec le résultat attendu.

Sur machine (30 minutes).

  1. Programme et teste les trois fonctions.
  2. Écris une fonction hors_plan(adresses) qui reçoit une liste d'adresses et renvoie la liste de celles qui n'appartiennent à aucun VLAN du siège.
  3. Pour aller plus loin. Écris une fonction prefixe(masque) qui renvoie la longueur du préfixe d'un masque (26 pour 255.255.255.192), en réutilisant binaire8.

Corrigé

Question 1. On divise par 2 huit fois ; chaque reste est un bit, que l'on place devant les bits déjà obtenus, puisque le premier reste est le bit de poids faible.

text
Fonction binaire8(n : entier) : chaîne
    // n entre 0 et 255 ; renvoie ses 8 bits, poids fort à gauche
    bits ← ""
    Pour i allant de 1 à 8 faire
        bits ← chaîne(n mod 2) + bits
        n ← n div 2
    Fin Pour
    Renvoyer bits
Fin Fonction

La boucle « Pour » tourne exactement 8 fois : c'est ce qui garantit les zéros de tête (5 donne 00000101, pas 101).

Questions 2 et 3.

text
Fonction reseau(adresse : chaîne, masque : chaîne) : chaîne
    a ← octets(adresse)
    m ← octets(masque)
    resultat ← ""
    Pour i allant de 0 à 3 faire
        resultat ← resultat + chaîne(a[i] ET m[i])
        Si i < 3 alors
            resultat ← resultat + "."
        Fin Si
    Fin Pour
    Renvoyer resultat
Fin Fonction

Fonction vlan_de(adresse : chaîne) : entier
    Pour chaque (numero, nom, adresse_reseau, masque) de VLANS faire
        Si reseau(adresse, masque) = adresse_reseau alors
            Renvoyer numero
        Fin Si
    Fin Pour
    Renvoyer 0
Fin Fonction

Le parcours s'arrête dès qu'un VLAN correspond : c'est une recherche, pas un comptage. Le Renvoyer 0 est après la boucle : le placer dans un « Sinon » à l'intérieur arrêterait la recherche au premier VLAN qui ne correspond pas.

Question 4. Le jeu d'essai, avec le calcul qui justifie chaque résultat attendu :

AdressePourquoi ce testCalculAttendu
192.168.10.71Cas normal, masque /2671 ET 192 = 6410
192.168.10.180Masque /28180 ET 240 = 17620
192.168.21.37Troisième octet différent21.37 ET 255.0 = 21.021
192.168.10.140Masque /27140 ET 224 = 12830
192.168.10.64Limite : l'adresse du réseau elle-même64 ET 192 = 6410
192.168.10.63Limite : dernière adresse du VLAN 4063 ET 192 = 040
192.168.10.200Trou du plan d'adressage200 ET 240 = 192, aucun VLAN0
192.168.20.10Autre site (entrepôt de Mâcon)aucun réseau du siège0

Questions 5, 6 et 7 : le programme complet.

python
# Composants fournis par le sujet
def octets(adresse):
    """Renvoie la liste des quatre entiers d'une adresse IPv4 écrite '192.168.10.71'."""
    return [int(x) for x in adresse.split(".")]


VLANS = [
    (10, "POSTES", "192.168.10.64", "255.255.255.192"),
    (20, "SERVEURS", "192.168.10.176", "255.255.255.240"),
    (21, "APPLIS", "192.168.21.0", "255.255.255.0"),
    (30, "ENTREPOT", "192.168.10.128", "255.255.255.224"),
    (40, "VISITEURS", "192.168.10.0", "255.255.255.192"),
    (50, "TELEPHONIE", "192.168.10.160", "255.255.255.240"),
    (60, "DMZ", "192.168.10.224", "255.255.255.240"),
    (99, "ADMIN", "192.168.10.208", "255.255.255.240"),
]


def binaire8(n):
    """Écriture binaire de n (0 <= n <= 255) sur 8 bits, par divisions successives."""
    bits = ""
    for _ in range(8):
        bits = str(n % 2) + bits
        n = n // 2
    return bits


def reseau(adresse, masque):
    """Adresse du réseau de adresse avec ce masque : ET bit à bit, octet par octet."""
    a = octets(adresse)
    m = octets(masque)
    resultat = []
    for i in range(4):
        resultat.append(str(a[i] & m[i]))
    return ".".join(resultat)


def vlan_de(adresse):
    """Numéro du VLAN du siège qui contient adresse, ou 0 si aucun."""
    for numero, nom, adresse_reseau, masque in VLANS:
        if reseau(adresse, masque) == adresse_reseau:
            return numero
    return 0


def hors_plan(adresses):
    """Liste des adresses qui n'appartiennent à aucun VLAN du siège."""
    resultat = []
    for adresse in adresses:
        if vlan_de(adresse) == 0:
            resultat.append(adresse)
    return resultat


def prefixe(masque):
    """Longueur du préfixe d'un masque : nombre de bits à 1."""
    total = 0
    for octet in octets(masque):
        total = total + binaire8(octet).count("1")
    return total


# Jeu d'essai
assert binaire8(0) == "00000000"
assert binaire8(5) == "00000101"
assert binaire8(255) == "11111111"
assert reseau("192.168.10.71", "255.255.255.192") == "192.168.10.64"
essais = {
    "192.168.10.71": 10, "192.168.10.180": 20, "192.168.21.37": 21,
    "192.168.10.140": 30, "192.168.10.64": 10, "192.168.10.63": 40,
    "192.168.10.200": 0, "192.168.20.10": 0,
}
for adresse, attendu in essais.items():
    assert vlan_de(adresse) == attendu, adresse
assert hors_plan(["192.168.10.71", "192.168.10.200", "192.168.20.10"]) == ["192.168.10.200", "192.168.20.10"]
assert prefixe("255.255.255.192") == 26
assert prefixe("255.255.255.240") == 28
print("Tous les tests passent.")

Les assert gardent les tests dans le fichier : devant la commission, tu relances le programme et tout le jeu d'essai s'exécute en une seconde. Si un test échoue, Python affiche l'adresse en cause.

Les questions de l'entretien

Question de la commissionCe qu'on attend
« Pourquoi ajoutez-vous le bit devant la chaîne dans binaire8 ? »Le premier reste obtenu est le bit de poids faible : il doit finir à droite.
« Que renvoie vlan_de("192.168.10.255") ? Pourquoi ? »0 : 255 ET 240 = 240, et aucun VLAN n'a le réseau 192.168.10.240. Le plan d'adressage s'arrête à .239.
« Que se passe-t-il avec l'adresse "192.168.10" ? »octets renvoie trois entiers et a[3] provoque une erreur d'indice. Correction : vérifier qu'il y a quatre octets entre 0 et 255 avant le calcul.
« Combien de calculs de réseau faites-vous au pire ? »Un par VLAN, soit 8, quand l'adresse n'appartient à aucun : le parcours va jusqu'au bout.
« Comment renvoyer le nom du VLAN au lieu du numéro ? »Renvoyer nom dans la boucle, et une chaîne comme "HORS PLAN" après la boucle ; changer les tests en conséquence.
« Pourquoi 192.168.10.64 est-il dans le VLAN 10, alors que ce n'est pas une adresse de machine ? »Le calcul dit seulement qu'elle appartient au réseau ; c'est son adresse de réseau. Pour la refuser, il faudrait comparer aussi l'adresse au réseau et à la diffusion.

Exercices

Exercice 1 sur 3 Faire la trace de binaire8 Réussi À revoir

Fais la trace de binaire8(13) : donne les valeurs de n et de bits après chacun des 8 tours de boucle.

Voir la réponseMasquer la réponse de l'exercice 1
Tourn % 2bits après le tourn après le tour
1116
20013
311011
4111010
50011010
600011010
7000011010
80000011010

Résultat : 00001101, et 8 + 4 + 1 = 13. Les tours 5 à 8 ajoutent les zéros de tête.

Tu avais trouvé ?

Exercice 2 sur 3 Corriger un algorithme fourni Réussi À revoir

Un collègue a écrit cette version de vlan_de. Trouve l'erreur, donne une adresse qui la révèle, puis corrige-la.

python
def vlan_de(adresse):
    for numero, nom, adresse_reseau, masque in VLANS:
        if reseau(adresse, masque) == adresse_reseau:
            return numero
        else:
            return 0
Voir la réponseMasquer la réponse de l'exercice 2

Le return 0 est dans la boucle : dès le premier VLAN de la liste (le VLAN 10), la fonction renvoie un résultat, et les autres VLAN ne sont jamais examinés. L'adresse 192.168.10.180 le révèle : elle est dans le VLAN 20, mais la fonction renvoie 0. Correction : supprimer le else et placer return 0 après la boucle, au même niveau que le for.

Tu avais trouvé ?

Exercice 3 sur 3 Compter par VLAN Réussi À revoir

Écris une fonction compter(adresses, numero) qui renvoie le nombre d'adresses de la liste qui appartiennent au VLAN numero. Donne un jeu d'essai de trois cas.

Voir la réponseMasquer la réponse de l'exercice 3
python
def compter(adresses, numero):
    """Nombre d'adresses de la liste qui appartiennent au VLAN numero."""
    total = 0
    for adresse in adresses:
        if vlan_de(adresse) == numero:
            total = total + 1
    return total


liste = ["192.168.10.71", "192.168.10.100", "192.168.10.180", "192.168.20.10"]
assert compter(liste, 10) == 2      # .71 et .100 sont dans 192.168.10.64/26
assert compter(liste, 99) == 0      # aucune adresse d'administration
assert compter([], 10) == 0         # liste vide

C'est le motif du comptage : un compteur initialisé à 0, incrémenté sous condition, renvoyé après la boucle. Le cas de la liste vide vérifie l'initialisation.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Réussir l'écrit : situation B (55 min) et écrit ponctuel (2 h)Revoir le sommaire du cours