#1 Le 06/01/2015, à 18:12
- kboo
Python: conversion string ---> int et pas float
Bonjour
Lors de la lecture d'un fichier xls il arrive d'avoir une valeur entière, par exemple 7.
En lisant cette valeur, celle-ci est converti par xlrd en '7.0' et pas '7' or afin de valider des donnés dans le fichier xls je doit lire l'entier 7 et pas le flottant 7.0
value_to_check = '7.0' #value_to_check est lu d'un fichier donc toujours une chaine de caractères
selectableoptions = "1;2;3;4;5;6;7;8;9" #selectableoptions est lu d'un autre fichier donc toujours une chaine de caractères
options = selectableoptions.split(';')
if not all(value_to_check in s for s in options):
print "Error"
Comment faire?
merci bien
Hors ligne
#2 Le 06/01/2015, à 18:48
- kboo
Re : Python: conversion string ---> int et pas float
Trouvé: avec modulo 1:
7.0 % 1 = 0
lavaleur = '7.0'
if float(lavaleur) % 1 == 0:
lavaleur = str(int(float(lavaleur)))
mais c'est moche!
Hors ligne
#3 Le 07/01/2015, à 09:27
- tiramiseb
Re : Python: conversion string ---> int et pas float
Salut,
Ton code vérifie que les entrées (séparées par les ";") sont toutes égales à la valeur value_to_check et affiche "Erreur" si la moindre des entrées n'est pas égale, c'est bien ce que tu veux ?
Si c'est bien le cas, je te propose l'approche suivante :
value_to_check = float('7.0') # convertir en float dès la lecture dans le fichier
selectableoptions = "1;2;3;4;5;6;7;8;9" #selectableoptions est lu d'un autre fichier donc toujours une chaine de caractères
options = [float(i) for i in selectableoptions.split(';')] # convertir en float dès l'éclatement en plusieurs éléments
if not all(value_to_check == s for s in options):
print "Error"
Ou alors, si tu veux vérifier qu'au moins l'une des entrées est égale, alors c'est plutôt ça que tu veux :
value_to_check = float('7.0') # convertir en float dès la lecture dans le fichier
selectableoptions = "1;2;3;4;5;6;7;8;9" #selectableoptions est lu d'un autre fichier donc toujours une chaine de caractères
options = [float(i) for i in selectableoptions.split(';')] # convertir en float dès l'éclatement en plusieurs éléments
if not value_to_check in options:
print "Error"
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#4 Le 07/01/2015, à 14:01
- kboo
Re : Python: conversion string ---> int et pas float
Merci tiramiseb,
En effet c'est bien la seconde solution qui correspond à mon problème!
C'est bien mieux, mais cette nouvelle solution apporte un nouveau problème:
File "launch.py", line XXX, in check_value_matches_selectableoptions
options = [float(i) for i in selectableoptions.split(';')]
ValueError: invalid literal for float(): No
En effet j'ai oublié de préciser que l'on peut avoir ceci:
selectableoptions = "Yes;No"
La solution la plus crade de mon point de vu est de faire un try/except, qu'en pensez vous
Merci encore!
Dernière modification par kboo (Le 07/01/2015, à 14:02)
Hors ligne
#5 Le 07/01/2015, à 15:39
- grim7reaper
Re : Python: conversion string ---> int et pas float
Trouvé: avec modulo 1:
7.0 % 1 = 0lavaleur = '7.0' if float(lavaleur) % 1 == 0: lavaleur = str(int(float(lavaleur)))
mais c'est moche!
En effet, il y a mieux : la méthode is_integer
In [1]: x = 7.0
In [2]: x.is_integer()
Out[2]: True
In [3]: x = 3.14
In [4]: x.is_integer()
Out[4]: False
Avec ça tu peux tester si le nombre flottant est bien un entier avant de faire la conversion.
La solution la plus crade de mon point de vu est de faire un try/except, qu'en pensez vous
Si tes nombres seront toujours de la forme XXX.YYYY, alors tu peux faire un simple test avec une regexp ("\d+(\.\d+)?") avant de faire la conversion.
Pour conclure, c’est quasiment toujours une mauvaise idée de comparer des nombres flottants avec ==
Petit exemple :
In [1]: 0.20-0.15 == 0.05
Out[1]: False
Donc attention…
Dernière modification par grim7reaper (Le 07/01/2015, à 15:46)
Hors ligne
#6 Le 07/01/2015, à 16:11
- tiramiseb
Re : Python: conversion string ---> int et pas float
Allez, pour mettre tout le monde d'accord, un code un peu moins pythonesque mais a priori tout à fait fonctionnel :
from decimal import Decimal
def is_in_selectableoptions(value, selectableoptions):
try:
value = Decimal(value)
except:
return False
for i in selectableoptions.split(';'):
try:
if Decimal(i) == value_to_check:
return True
except decimal.InvalidOperation:
pass
return False
value_to_check = '7.0'
selectableoptions = "1;2;3;4;5;6;7;8;9"
if not is_in_selectableoptions(value_to_check, selectableoptions):
print "Error"
Cela étant dit, tant qu'on ne fait pas d'opération et qu'on ne fait que comparer deux valeurs, alors on peut toujours rester sur un float, car 0.20 sera toujours égal à 0.20, même si en réalité ça vaut 0.200000000000000011102230246251565404236316680908203125....
Donc la chose suivante devrait fonctionner aussi :
def is_in_selectableoptions(value, selectableoptions):
try:
value = float(value)
except ValueError:
return False
for i in selectableoptions.split(';'):
try:
if float(i) == value_to_check:
return True
except ValueError:
pass
return False
value_to_check = '7.0'
selectableoptions = "1;2;3;4;5;6;7;8;9"
if not is_in_selectableoptions(value_to_check, selectableoptions):
print "Error"
Dernière modification par tiramiseb (Le 07/01/2015, à 16:14)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#7 Le 07/01/2015, à 17:03
- grim7reaper
Re : Python: conversion string ---> int et pas float
Cela étant dit, tant qu'on ne fait pas d'opération et qu'on ne fait que comparer deux valeurs, alors on peut toujours rester sur un float, car 0.20 sera toujours égal à 0.20
C’est pas garanti.
Il faut que les algo’ qui convertissent les chaînes de caractères en nombre à virgule flottante soient les même de chaque côté.
Bon en pratique c’est quasiment toujours le cas vu que l’algo est particulièrement touffu, quasiment tout le monde utilise l’implémentation de David M. Gay.
Hors ligne
#8 Le 07/01/2015, à 21:04
- tiramiseb
Re : Python: conversion string ---> int et pas float
Il faut que les algo’ qui convertissent les chaînes de caractères en nombre à virgule flottante soient les même de chaque côté.
La conversion étant effectuée dans la fonction is_in_selectableoptions() en utilisant la fonction float() de Python, on est assuré que c'est le même algo...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#9 Le 07/01/2015, à 21:39
- grim7reaper
Re : Python: conversion string ---> int et pas float
Il faut que les algo’ qui convertissent les chaînes de caractères en nombre à virgule flottante soient les même de chaque côté.
La conversion étant effectuée dans la fonction is_in_selectableoptions() en utilisant la fonction float() de Python, on est assuré que c'est le même algo...
Dans ton code oui, mais dans le cas kboo, c’est pas lui qui converti mais une bibliothèque (« En lisant cette valeur, celle-ci est converti par xlrd en '7.0' et pas '7' ») donc il pourrait y avoir une différence (mais comme je le dit, il n’y en a vraisemblablement aucune).
Hors ligne
#10 Le 07/01/2015, à 21:40
- tiramiseb
Re : Python: conversion string ---> int et pas float
Dans ton code oui, mais dans le cas kboo, c’est pas lui qui converti mais une bibliothèque
Sauf que xlrd sort une chaîne de caractères, c'est elle qui est ensuite convertie en float. Donc la conversion en float, c'est bien "ma" fonction qui la fait...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#11 Le 08/01/2015, à 09:52
- grim7reaper
Re : Python: conversion string ---> int et pas float
Ok, j’avais dû mal comprendre le premier message kboo
Hors ligne