# -*- coding: utf-8 -*- """ Corrigé Python - Bac NSI 2026 - Épreuve pratique - Sujet 7 Thème : coccinelles et régulation des pucerons Le module random est utilisé par le modèle pour simuler des comportements aléatoires. """ from __future__ import annotations import random class Coccinelle: """ Représente une coccinelle dans le modèle de simulation. """ def __init__(self, sexe: str, age: int, niv_nutrition: int) -> None: self.age = age self.esperance_de_vie = random.randint(200, 350) self.sexe = sexe self.niv_nutrition = niv_nutrition # ------------------------------------------------------------------------- # Question 3 : documentation et commentaires de la méthode chasser # ------------------------------------------------------------------------- def chasser(self, nb_proies: int, nb_coccinelles: int) -> int: """ Simule la chasse d'une coccinelle pendant une journée. Paramètres : - nb_proies : nombre de pucerons disponibles avant la chasse ; - nb_coccinelles : nombre de coccinelles en concurrence pour ces proies. La quantité consommée dépend du nombre moyen de proies disponibles par coccinelle. Le niveau de nutrition augmente si la coccinelle mange assez, sinon il diminue sans devenir négatif. La fonction renvoie le nombre de proies restantes après la chasse. """ if nb_coccinelles == 0: return nb_proies # Nombre moyen de proies disponibles par coccinelle. proies_par_cocci = nb_proies / nb_coccinelles # Plus il y a de proies disponibles, plus la coccinelle peut en consommer. if proies_par_cocci > 20: consomme = random.randint(12, 20) elif proies_par_cocci > 10: consomme = random.randint(8, 15) else: consomme = random.randint(3, 8) # On ne peut pas consommer plus de proies qu'il n'en reste. consomme = min(consomme, nb_proies) # Mise à jour de l'état nutritionnel. if consomme >= 10: self.niv_nutrition += 1 else: self.niv_nutrition = max(0, self.niv_nutrition - 1) return nb_proies - consomme # ------------------------------------------------------------------------- # Question 4 : maturité sexuelle # ------------------------------------------------------------------------- def reproduction(self) -> list["Coccinelle"]: """ Renvoie les descendants produits par la coccinelle. Une femelle peut se reproduire seulement si : - elle a au moins 20 jours ; - son niveau de nutrition est au moins égal à 2. Elle engendre alors deux descendants : un mâle et une femelle. """ descendants = [] if self.sexe == "femelle" and self.age >= 20 and self.niv_nutrition >= 2: descendants.append(Coccinelle("male", 0, 0)) descendants.append(Coccinelle("femelle", 0, 0)) self.niv_nutrition = 0 return descendants # ------------------------------------------------------------------------- # Question 4 : mortalité liée au manque de nourriture # ------------------------------------------------------------------------- def a_survecu(self) -> bool: """ Met à jour l'âge de la coccinelle et indique si elle survit à la journée. Une coccinelle meurt si elle atteint son espérance de vie. De plus, si son niveau de nutrition est égal à 0, elle a une chance sur 3 de mourir. """ self.age += 1 if self.age >= self.esperance_de_vie: return False if self.niv_nutrition == 0 and random.random() < 1 / 3: return False return True def __repr__(self) -> str: return ( f"Coccinelle {self.sexe}, âge: {self.age}/{self.esperance_de_vie}, " f"niv_nutrition: {self.niv_nutrition}" ) def evolution(population: list[Coccinelle], nb_proies: int) -> tuple[list[Coccinelle], int]: """ Simule une journée dans l'écosystème. La fonction effectue successivement : - la chasse ; - le vieillissement et la mortalité ; - la reproduction des survivantes ; - la croissance naturelle des pucerons. """ population_suivante = [] nouveau_nes = [] nb_coccinelles = len(population) for coccinelle in population: nb_proies = coccinelle.chasser(nb_proies, nb_coccinelles) if coccinelle.a_survecu(): population_suivante.append(coccinelle) nouveau_nes += coccinelle.reproduction() # Croissance naturelle des pucerons : augmentation de 20 % par jour. nb_proies = int(nb_proies * 1.2) # Les nouveau-nés sont ajoutés en fin de journée. population_suivante += nouveau_nes return population_suivante, nb_proies # ----------------------------------------------------------------------------- # Question 1 # ----------------------------------------------------------------------------- def exemple_question_1() -> None: """ Simule l'évolution d'une petite population pendant 5 jours. """ population = [ Coccinelle("femelle", 10, 2), Coccinelle("femelle", 10, 2), Coccinelle("male", 10, 2), ] nb_proies = 200 for jour in range(1, 6): population, nb_proies = evolution(population, nb_proies) print( f"Jour {jour} : {len(population)} coccinelle(s), " f"{nb_proies} puceron(s)" ) # ----------------------------------------------------------------------------- # Question 2 # ----------------------------------------------------------------------------- def simulation_simple( population: list[Coccinelle], nb_proies: int, duree_max: int = 30 ) -> tuple[int, int, int]: """ Simule l'écosystème pendant au plus duree_max jours. La simulation s'arrête avant 30 jours si la population de coccinelles tombe à zéro ou si le nombre de pucerons tombe à zéro. La fonction renvoie le triplet : (nombre final de coccinelles, nombre final de pucerons, nombre de jours simulés). """ nb_jours = 0 while nb_jours < duree_max and len(population) > 0 and nb_proies > 0: population, nb_proies = evolution(population, nb_proies) nb_jours += 1 return len(population), nb_proies, nb_jours # ----------------------------------------------------------------------------- # Tests # ----------------------------------------------------------------------------- def population_initiale() -> list[Coccinelle]: """Crée la population initiale utilisée dans les questions 1 et 2.""" return [ Coccinelle("femelle", 10, 2), Coccinelle("femelle", 10, 2), Coccinelle("male", 10, 2), ] def test_reproduction() -> None: """Teste la règle de maturité sexuelle.""" jeune = Coccinelle("femelle", 10, 2) adulte = Coccinelle("femelle", 20, 2) male = Coccinelle("male", 20, 2) assert jeune.reproduction() == [] assert male.reproduction() == [] assert len(adulte.reproduction()) == 2 def test_a_survecu() -> None: """Teste les cas simples de survie et de mortalité.""" coccinelle = Coccinelle("femelle", 349, 2) coccinelle.esperance_de_vie = 350 assert coccinelle.a_survecu() is False coccinelle = Coccinelle("femelle", 10, 0) coccinelle.esperance_de_vie = 350 random.seed(1) assert coccinelle.a_survecu() is False coccinelle = Coccinelle("femelle", 10, 0) coccinelle.esperance_de_vie = 350 random.seed(2) assert coccinelle.a_survecu() is True def test_simulation_simple() -> None: """Teste le format du résultat renvoyé par la simulation.""" random.seed(0) resultat = simulation_simple(population_initiale(), 1000) assert isinstance(resultat, tuple) assert len(resultat) == 3 assert resultat[2] <= 30 if __name__ == "__main__": test_reproduction() test_a_survecu() test_simulation_simple() print("Tous les tests du sujet 7 sont réussis.\n") random.seed(0) print("Simulation de la question 1 :") exemple_question_1() random.seed(0) resultat = simulation_simple(population_initiale(), 1000) print("\nRésultat de la simulation simple :", resultat)