Correction D.S. 1#

Exercice 1#

On peut définir un polynôme de la façon suivante

from math import sqrt
class Polynome:
    def __init__(self,a,b,c):
        self.a = a
        self.b = b
        self.c = c
    def __repr__(self):
        if self.c != abs(self.c):
            sc = "-"
        else:
            sc = "+"
        if self.b != abs(self.b):
            sb = "-"
        else:
            sb = "+"
        return f"{self.a}X^2 {sb} {abs(self.b)}X {sc} {abs(self.c)}"
    def racines(self):
        a,b,c = self.a,self.b,self.c
        if a == 0:
            if b == 0:
                return (None,)
            else:
                return (-c/b,)
        else:
            d = b**2 - 4*a*c < 0
            if d:
                return (None,)
            elif d > 0:
                return (-b - sqrt(d))/(2*a),(-b + sqrt(d))/(2*a)
            else:
                return (-b/(2*a),)
    def add(self,Q):
        return Polynome(self.a + Q.a, self.b + Q.b, self.c + Q.c)
P1 = Polynome(1,1,1)
P1
1X^2 + 1X + 1
P2 = Polynome(1,0,0)
P2.racines()
(0.0,)
P3 = Polynome(0,0,1)
P2.add(P1)
2X^2 + 1X + 1
P1.add(P2)
2X^2 + 1X + 1

Exercice 2#

  1. Une liste est définie par les primitives suivantes :

    • creer_liste_vide()

    • est_vide()

    • ajouter_tete

    • renvoyer_queue

  2. On peut proposer l’implémentation ci-dessous, avec un objet.

class Liste:
    def __init__(self, liste=None):
        if liste is None:
            self.liste = []
        else:
            self.liste = liste
    def est_vide(self):
        return self.liste == []
    def ajouter_tete(self, valeur):
        self.liste = [valeur] + self.liste
    def renvoyer_queue(self):
        return (self.liste[0], Liste(self.liste[1:]))
    def __repr__(self):
        return f"Liste({self.liste})"

On peut vérifier les interfaces.

liste = Liste()
liste
Liste([])
liste.ajouter_tete(1)
liste
Liste([1])
liste.renvoyer_queue()
(1, Liste([]))

On peut aussi n’utiliser que des fonctions externes à la liste.

def ajoute_tete(liste, valeur):
    liste.append(valeur)
    return liste
def est_vide(liste):
    return liste == []
def renvoie_queue(liste):
    tete = liste.pop(0)
    return tete,liste
l = []
est_vide(l)
True
ajoute_tete(l, 1)
[1]
est_vide(l)
False
ajoute_tete(l,2)
[1, 2]
l
[1, 2]
renvoie_queue(l)
(1, [2])
l
[2]
renvoie_queue(l)
(2, [])
renvoie_queue(l)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[27], line 1
----> 1 renvoie_queue(l)

Cell In[17], line 2, in renvoie_queue(liste)
      1 def renvoie_queue(liste):
----> 2     tete = liste.pop(0)
      3     return tete,liste

IndexError: pop from empty list

Exercice 3#

On donnait le code suivant :

class Chien:
    def __init__(self, nom, race, sexe, annee):
        """
        Parameters
        ----------
        nom : str
            nom du chien
        race : tuple
            une seule race si le chien est pure race
            deux ou plusieurs races si le chien est issu d'une croisement
            les races sont des chaines de caractères (str)
        sexe : str
            "male" ou "femelle"
        annee : int
            année de naissance du chien
        """
        self._nom = nom
        self._race = race
        self._annee = annee
        self._sexe = sexe
        
    def nom(self):
        return self._nom

    def race(self):
        return self._race
    
    def sexe(self):
        return self._sexe

    

Certains chiens ont été initialisés :

medor = Chien("Médor", ("Berger allemand",), 'male', 2018)
loula = Chien("Loula", ("Caniche","Cocker"), 'femelle', 2019)

On peut obtenir le sexe de Loula :

loula.sexe()
'femelle'

On peut écrire une méthode pour l’age des chiens :

import time
def age(self):
    return time.gmtime().tm_year - self._annee
setattr(Chien, 'age', age)
medor.age()
6

On peut écrire une méthode pour savoir si le chien est de race pure.

def pure_race(self):
    return len(self._race) == 1
setattr(Chien, 'pure_race', pure_race)
medor.pure_race()
True
loula.pure_race()
False

On peut écrire une fonction qui créé un nouveau chien.

import random
def bebe(chien1: Chien, chien2: Chien, nom: str) -> Chien:
    if chien1.sexe() == chien2.sexe():
        raise Exception("Les chiens doivent être de sexe opposé")
    sexe = ["male","femelle"][random.randint(0,1)]
    race = tuple(set(list(chien1.race())+list(chien2.race())))
    annee = time.gmtime().tm_year
    return Chien(nom, race, sexe, annee)
rantanplan = bebe(medor,loula,"Rantanplan")

On peut d’abord chercher si deux chiens sont compatibles

def compatible(chien1: Chien, chien2: Chien) -> bool:
    if chien1.sexe() == chien2.sexe():
        return False
    races = []
    for race in chien1.race():
        races.append(race in chien2.race())
    return (True in races)

On peut enfin écrire une fonction cherche_partenaire

def cherche_partenaires(chien: Chien, chiens: list) -> Chien:
    """
    Parameters
    ----------
    chien : Chien
        chien pour lequel on cherche un partenaire dans la liste
    chiens : list
        liste de chiens (instances de Chien) dans laquelle on cherche un partenaire

    Returns
    -------
    une liste d'instances de la classe Chien
    la liste renvoyée est la liste des partenaires possibles pour chien parmi la liste des chiens
    Un partenaire est un chien de sexe opposé et 'compatible'
    """
    return [canidé for canidé in chiens if compatible(chien,canidé)]
    

Pour la dernière question, on peut affiner la recherche dans la liste des partenaires avec les deux critères suivants :

  • tri par différence d’age (un meilleur partenaire à une plus petite différence)

  • affecter un poids supérieur si les deux races sont identiques (et non une seule)