Makina Blog

Le blog Makina-corpus

Mesures et unités avec Python


La gestion des unités et mesures est un besoin récurrent lors du développement d'applications métiers. La problématique est de savoir associer une valeur numérique à une unité de mesure (mono ou bi-dimentionnelle) et de réaliser des conversions et opérations. Cet article est une introduction au module python-measurement qui répond à cette problématique.

Python-mesurement

python-mesurement est disponible sur Github et s'installe tout simplement avec pip:

pip install measurement

Le module offre par défaut les mesures les plus courantes: Aire, Distance, Énergie, Poids, Vitesse, Température, Temps, et Volume. En lisant le code source ont y retrouve également des mesures utiles aux électriciens: Capacité, Intensité, Fréquence, Résistance, Voltage. Une de ses forces est la possibilité de créer facilement ses propres mesures, qu'elles soient mono ou bi-dimensionnelles.

La documentation est disponible sur Read The Docs.

Exemple d'utilisation

Création d'un volume de 10m3:

>>> from measurement.measures import Volume
>>> v = Volume(cubic_meter=10)

Conversion en litres:

>>> v.l
10000.0

Ajout de 2m3 à notre volume : 

>>> v += Volume(cubic_meter=2)
>>> v
Volume(cubic_meter=12.0)

Retrait de 500 litres à notre volume :

>>> v -= Volume(l=500)
>>> v
Volume(cubic_meter=11.5)

Et avec les mesures bi-dimensionnelles telles que la vitesse ?

>>> from measurement.measures import Speed
>>> speed = Speed(km__hr=110) # notez l'utilisation de 2 underscores
>>> speed.m__hr # mètres/heure
110000.0
>>> speed.m__min # mètres/minute
1833.3333333333333
>>> speed.mi__hr # miles/heure
68.35083114610673

Décortiquons la mesure Poids 

class Weight(MeasureBase):
    STANDARD_UNIT = 'g'
    UNITS = {
        'g': 1.0,
        'tonne': 1000000.0,
        'oz': 28.3495,
        'lb': 453.592,
        'stone': 6350.29,
        'short_ton': 907185.0,
        'long_ton': 1016000.0,
    }
    ALIAS = {
        'mcg': 'ug',
        'gram': 'g',
        'ton': 'short_ton',
        'metric tonne': 'tonne',
        'metric ton': 'tonne',
        'ounce': 'oz',
        'pound': 'lb',
        'short ton': 'short_ton',
       'long ton': 'long_ton',
    }
    SI_UNITS = ['g']

STANDARD_UNIT

STANDARD_UNIT est l'unité utilisée en interne par le module pour stocker la valeur de la mesure. 

UNITS

UNITS défini la liste des unités en précisant son nom et son facteur de conversion par rapport à l'unité standard. On y voit par exemple que 1 tonne = 1000000 g.

Dans certaines situations, les facteurs de conversion sont plus complexes et prennent la forme de formules mathématiques. C'est le cas par exemple de la température où 1° kelvin = 1° celcius - 273,15. Il est conseillé pour cela d'utiliser le module sympy (bibliothèque spécialisée dans le calcul formel). Consultez l'exemple de la classe Temperature.

ALIAS

ALIAS définit des alias pour les noms d'unité. Exemple : 

>>> from measurement.measures import Weight
>>> Weight(g=2)
Weight(g=2.0)
>>> Weight(gram=2)
Weight(g=2.0)

Les alias qui ne peuvent être utilisés en tant qu'argument nommé sont utilisables via la fonction guess

>>> from measurement.utils import guess
>>> guess(2, 'metric tonne')
Weight(tonne=2.0)

SI_UNITS

SI_UNITS définit la liste des unités SI (Système International d'unités). Le module mets alors automatiquement à disposition toutes les unités correspondantes, dans notre cas : yg (yottagrams), zg (zeptograms), ag (attograms), fg (femtograms), pg (picograms), ng (nanograms), ug (micrograms), mg (milligrams), kg (kilograms), Mg (megagrams), Gg (gigagrams), Tg (teragrams), Pg (petagrams), Eg (exagrams), Zg (zetagrams), Yg (yottagrams).

Décortiquons la mesure Vitesse 

class Speed(BidimensionalMeasure):
    PRIMARY_DIMENSION = Distance
    REFERENCE_DIMENSION = Time
    ALIAS = {
        'mph': 'mi__hr',
        'kph': 'km__hr',
    }

On peut difficilement faire plus simple ! Il suffit d'hériter de la classe BidimensionalMeasure et de préciser la composition de la mesure : 

  • PRIMARY_DIMENSION : la dimension variable de la mesure, ici la Distance
  • REFERENCE_DIMENSION : la dimension de référence de la mesure, ici le Temps

Et si je ne sais pas par avance ce que j'ai en entrée ?

Imaginons que vous ayez en base de données des mesures de Volume, par exemple dans une table ayant pour colonnes value et unit. Comment créer mon objet Volume à partir de ces données ?
 
L'astuce consiste à passer la valeur et l'unité via un dictionnaire:
 
>>> from measurement.measures import Volume
>>> value, unit = get_from_database()  # return (5, 'cubic_meter')
>>> Volume(**{unit: value})
Volume(cubic_meter=5.0)
Et pour faire une conversion depuis une unité provenant de la base de données:
 
>>> v = Volume(cubic_meter=1)
>>> unit = get_from_database()  # return 'l'
>>> getattr(v, unit)
1000.0

Messieurs de l'Agence Spatiale Européenne, passez votre chemin !!!

Le stockage des valeurs et les conversions sont réalisées avec des nombres à virgule flottante, donc avec une certaine dose d'inexactitude. À ne pas utiliser pour envoyer des satellites en orbite ou explorer de nouvelles galaxies !

Envie d'en savoir plus sur le langage de programmation Python, découvrez nos formations !

Formations associées

Formations Python

Formation Python

À distance (FOAD) Du 29 janvier au 2 février 2024

Voir la formation

Formations Python

Formation Python avancé

Nantes Du 8 au 12 avril 2024

Voir la formation

Formations IA / Data Science

Formation Python scientifique

Nantes Du 22 au 26 janvier 2024

Voir la formation

Actualités en lien

Image
Python
26/07/2023

La formation Python éligible au CPF est enfin arrivée

Makina Corpus propose un nouvelle formation Python éligible au CPF. Grâce à cette certification, cette formation peut être entièrement financée par votre compte Compte Personnel de Formation.

Voir l'article
Image
Canari
20/07/2023

CANARI Europe, un service climatique innovant pour adapter l'agriculture européenne

Après un lancement réussi de CANARI l'application de projections climatiques dédiée à l'agriculture en France, CANARI s’étend à toute L’Europe et au nord du Maghreb.

Voir l'article
Image
Encart Reference Rencontres R
14/06/2023

Makina Corpus sponsorise les 9èmes Rencontres R

Du 21 au 23 juin 2023, Makina Corpus est sponsor argent des 9èmes Rencontres R à l'Université d'Avignon. Retrouvez notre équipe sur notre stand et participez aux conférences de nos experts.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus