• 6 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 04/02/2019

Créez la classe Position

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Pour calculer la densité de population, nous devons connaître la position d'un agent sur une carte. Cela suppose que notre programme connaît déjà ces concepts ! Or pour le moment il ne connaît que le concept Agent (le pion rouge de notre jeu de touché/coulé).

La classe Position

Créons donc une nouvelle classe qui nous servira à calculer les positions à la fois des Agents et des coins de nos futures zones.

class Position:
    def __init__():

Notre classePosition a deux attributs : une longitude et une latitude.

class Position:
    def __init__(self, longitude, latitude):
        self.latitude = latitude
        self.longitude = longitude

Ensuite, créons une nouvelle instancePosition composée de la latitude et de la longitude de chaque agent :

def main():
    for agent_attributes in json.load(open("agents-100k.json")):
        latitude = agent_attributes.pop("latitude")
        longitude = agent_attributes.pop("longitude")
        position = Position(longitude, latitude)
        agent = Agent(position, **agent_attributes)

Enfin, nous mettons à jour la classe Agent pour associer une position à chaque nouvelle instance :

class Agent:
    
    def __init__(self, position, **agent_attributes):
        self.position = position
        for attr_name, attr_value in agent_attributes.items():
            setattr(self, attr_name, attr_value)
            
    ...
    
    
def main():
    ...

Si nous lançons notre programme, nous constatons qu'il fonctionne. Nickel !

Des degrés aux radians : les propriétés

Sauf que... si la vie était simple, cela se saurait ! Les coordonnées de chaque agent sont en degrés. Or, en mathématiques, il est préférable d'utiliser des radians. Il s'agit tout simplement d'une unité de mesure différente qui sera plus pratique à utiliser.

La longitude en radians est égale à sa longitude en degrés * pi divisé par 180. Soit le calcul suivant :

 longitude = longitude_degrees * pi / 180 

Pourquoi ne pas effectuer ce calcul dans notre méthode __init__() ? Car cela reviendrait à y conserver à la fois les données en radians et en degrés ce qui, vous l'avouerez, n'est pas très pratique pour les utiliser ailleurs. 

Dans un monde idéal, j'aimerais effectuer ce calcul dans une nouvelle méthode mais y accéder comme s'il s'agissait d'un attribut. Le dictateur bienveillant à vie ayant pensé à tout, Python nous offre une manière très pratique de faire cela : les propriétés !

Une propriété est une méthode qui est accessible comme un attribut ! Vous ne voyez pas bien ce que je veux dire ? On va faire une démo !

Commençons par écrire une méthode qui effectue le calcul en question.

class Position:
    def __init__(self, longitude, latitude):
        self.latitude = latitude
        self.longitude = longitude

    def longitude(self):
        # Longitude in radians
        pass
        # return self.longitude_degrees * pi / 180

Nous avons besoin de changer le nom des attributs pour les adapter aux besoins de notre nouvelle méthode. L'attribut latitude devient latitude_degrees afin que ce soit plus clair et l'attribut longitude devient longitude_degrees.

Si nous voulons accéder à la longitude, nous devons écrire position.longitude(). Or nous voulons plutôt écrire position.longitude, afin que la longitude soit utilisée comme un attribut et non comme une méthode ! Cela peut vous paraître anodin mais, croyez-moi, c'est important ! En effet, vous ne voulez pas que votre instance fasse une action, ce qui correspond plutôt à une méthode, mais qu'elle vous renvoie une valeur qui lui est propre. Nous utilisons donc une propriété.

Pour créer une propriété nous ajoutons, juste avant la définition de la méthode, le mot-clé @property.

class Position:
    def __init__(self, longitude_degrees, latitude_degrees):
        self.latitude_degrees = latitude_degrees
        self.longitude_degrees = longitude_degrees

    @property
    def longitude(self):
        return self.longitude_degrees * pi / 180

Nous pouvons maintenant y accéder en écrivant position.longitude :

def main():
    for agent_attributes in json.load(open("agents-100k.json")):
        ...
        print(agent.position.longitude)

Bien bien !

Le nombre Pi

Intéressons-nous maintenant au calcul en lui-même. Le nombre pi étant très, très, très long à écrire, nous allons utiliser le module math de Python qui contient la variable pi.

Nous importons le module :

 import math 

Puis utilisons la variable math.pi :

 return self.longitude_degrees * math.pi / 180 

Nous pouvons en faire de même pour la latitude :

    @property
    def latitude(self):
        # Latitude in radians
        return self.latitude_degrees * math.pi / 180

 

Code du chapitre

Retrouvez le code de ce chapitre ici : https://github.com/OpenClassrooms-Student-Center/la_poo_avec_python/tree/03_properties 

Exemple de certificat de réussite
Exemple de certificat de réussite