Animauxđź”—

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env python3
# coding: utf-8

"""
Exercice: programmation orientée objet, développement dirigé par les tests.
"""

class Animal:
    """
    Classe définissant un `Animal`, caractérisé par son nom et son
    poids.
    """

    def __init__(self, nom, masse):
        """
        MĂ©thode d'instanciation Ă  partir d'un nom (str) et d'un poids (float).
        """

        # Ici, convertir les paramètres pour être sûr qu'il ont le bon
        # type. On utilisera `str` et `float`
        self.nom = str(nom)
        self.masse = float(masse)

        self.vivant = True       # Les animaux sont supposés vivants à l'instanciation
        self.empoisonne = False  # Animal empoisonné ?

    def __str__(self):
        """
        Surcharge de l'opérateur `str`: l'affichage *informel* de l'objet
        dans l'interpréteur, p.ex. `print self` sera résolu comme
        `self.__str__()`

        Retourne une chaîne de caractères.
        """

        return f"{self.nom} ({self.masse:.1f} kg)"

    def estVivant(self):
        """Méthode booléenne, vraie si l'animal est vivant."""

        return self.vivant

    def mourir(self):
        """Change l'Ă©tat interne de l'objet (ne retourne rien)."""

        self.vivant = False

    def __lt__(self, other):
        """
        Surcharge l'opérateur de comparaison '<' uniquement, sur la
        base de la masse des animaux.

        Note: Py3 impose de surcharger *explicitement* tous les opérateurs
        de comparaison: '__lt__' pour '<', __le__ pour '<=', '__eq__'
        pour '==', etc.
        """

        return self.masse < other.masse

    def __call__(self, other):
        """
        Surcharge de l'opérateur '()' pour manger un autre animal (qui
        meurt s'il est vivant) et prendre du poids (mais pas plus que
        la masse de l'autre ou 10 % de son propre poids).  Attention aux
        animaux empoisonnés !

        L'instruction `self(other)` sera résolue comme
        `self.__call__(other).
        """

        other.mourir()
        poids = min(other.masse, self.masse * 0.1)
        self.masse += poids
        other.masse -= poids
        if other.empoisonne:
            self.mourir()


class Chien(Animal):
    """
    Un `Chien` hérite de `Animal` avec des méthodes additionnelles
    (p.ex. l'aboiement et l'odorat).
    """

    def __init__(self, nom, masse=20, odorat=0.5):
        """DĂ©finit un chien plus ou moins fin limier."""

        # Initialisation de la classe parente
        Animal.__init__(self, nom, masse)

        # Attribut propre à la classe dérivée
        self.odorat = float(odorat)

    def __str__(self):

        return f"{self.nom} (Chien, {self.masse:.1f} kg)"

    def aboyer(self):
        """Une méthode bien spécifique aux chiens."""

        print("Ouaf ! Ouaf !")

    def estVivant(self):
        """Quand on vérifie qu'un chien est vivant, il aboie."""

        vivant = Animal.estVivant(self)

        if vivant:
            self.aboyer()

        return vivant

#########################################################
# Il est *INTERDIT* de modifier les tests ci-dessous!!! #
#########################################################

import pytest                   # Module (non standard) de tests

# start-tests
def test_empty_init():
    with pytest.raises(TypeError):
        Animal()


def test_wrong_init():
    with pytest.raises(ValueError):
        Animal('Youki', 'lalala')


def test_init():
    youki = Animal('Youki', 600)
    assert youki.masse == 600
    assert youki.vivant
    assert not youki.empoisonne
# end-tests


def test_str():
    youki = Animal('Youki', 600)
    assert str(youki) == 'Youki (600.0 kg)'


def test_mort():
    youki = Animal('Youki', 600)
    assert youki.estVivant()
    youki.mourir()
    assert not youki.estVivant()


def test_lt():
    medor = Animal('Medor', 600)
    kiki = Animal('Kiki', 20)
    assert kiki < medor
    with pytest.raises(AttributeError):
        medor < 1


def test_mange():
    medor = Animal('Medor', 600)
    kiki = Animal('Kiki', 20)
    medor(kiki)                 # MĂ©dor mange Kiki
    assert medor.estVivant()
    assert not kiki.estVivant()
    assert kiki.masse == 0
    assert medor.masse == 620
    kiki = Animal("Kiki Jr.", 20)
    kiki(medor)                 # Kiki Jr. mange MĂ©dor
    assert not medor.estVivant()
    assert kiki.estVivant()
    assert kiki.masse == 22
    assert medor.masse == 618   # MĂ©dor a perdu du poids en se faisant manger!


def test_init_chien():
    medor = Chien('Medor', 600)
    assert isinstance(medor, Animal)
    assert isinstance(medor, Chien)
    assert medor.odorat == 0.5
    assert str(medor) == 'Medor (Chien, 600.0 kg)'
    assert medor.estVivant()
=========================== test session starts ============================
platform linux2 -- Python 2.7.6 -- py-1.4.24 -- pytest-2.6.2
collected 8 items

animauxSol.py ........

========================= 8 passed in 0.04 seconds =========================

Source: animauxSol.py