Sam & Max » sign http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 PYTHON, WHY U NO HAZ A SIGN FUNCTION ? 9 http://sametmax.com/python-why-u-no-haz-a-sign-function/ http://sametmax.com/python-why-u-no-haz-a-sign-function/#comments Sat, 24 Aug 2013 12:36:22 +0000 http://sametmax.com/?p=7165 sign().]]> Bien que Python soit un langage massivement utilisé par la communauté scientifique, la lib standard ne contient pas de fonction aussi simple que sign(). Et on voit ça et là des libs qui contiennent quelque chose comme ça:

def sign(x):
    if x > 0:
        return 1
    if x == 0:
        return 0
    return -1
 
>>> sign(3)
1
>>> sign(-3)
-1
>>> sign(0)
0

Comme d’autres de choix étonnants dans l’architecture de Python, il y a une raison raisonnablement raisonnable : il n’existe aucun standard sur ce que doit faire une telle fonction dans les cas ambigües.

En effet, que doit faire la fonction avec NaN ? Avec un complexe ?

Il y a eu un débat sur ce qu’il faut faire dans ce cas, et un consensus n’a PAS été trouvé.

Par contre, il existe un standard international définissant une autre opération : celle de copier un signe. Elle a donc été implémentée :

>>> from math import copysign
>>> copysign(10, -3)
-10.0
>>> copysign(10, 22)
10.0
>>> copysign(10, float('-NaN'))
-10
>>> copysign(10, -2j)
Traceback (most recent call last):
  File "<ipython-input-13-ece93d1317dc>", line 1, in <module>
    copysign(10, -2j)
TypeError: can't convert complex to float

Copier le signe n’est pas la même chose que de retourner quelque chose selon le signe, et donc sémantiquement, choisir quoi retourner était plus facile. Comme la plupart du temps, on veut récupérer -1 ou 1 pour le multiplier avec quelque chose et justement copier le signe, cela résolvait pas mal de problèmes.

Mais même dans le rare cas où on a besoin du résultat que renverrait sign(), il est très facile à obtenir en une ligne :

>>> mon_nombre = 3
>>> mon_nombre and copysign(1, mon_nombre)
1.0
>>> mon_nombre = -3
>>> mon_nombre and copysign(1, mon_nombre)
-1.0
>>> mon_nombre = 0
>>> mon_nombre and copysign(1, mon_nombre)
0

Et pour ce cas de figure, les retours sur des valeurs ambigües sont laissés à la charge du codeur.

P.S: je sais qu’il y a des exemples sur le net montrant cmp(0, mon_nombre) pour obtenir la même fonctionnalité. Sachez que cmp a été retirée de Python 3, donc faites attention si vous l’utilisez.

]]>
http://sametmax.com/python-why-u-no-haz-a-sign-function/feed/ 9