Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 06/01/2015, à 19: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, à 19: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, à 10: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"

Hors ligne

#4 Le 07/01/2015, à 15: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, à 15:02)

Hors ligne

#5 Le 07/01/2015, à 16:39

grim7reaper

Re : Python: conversion string ---> int et pas float

kboo a écrit :

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!

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.

kboo a écrit :

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, à 16:46)

Hors ligne

#6 Le 07/01/2015, à 17: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, à 17:14)

Hors ligne

#7 Le 07/01/2015, à 18:03

grim7reaper

Re : Python: conversion string ---> int et pas float

tiramiseb a écrit :

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, à 22: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...

Hors ligne

#9 Le 07/01/2015, à 22:39

grim7reaper

Re : Python: conversion string ---> int et pas float

tiramiseb a écrit :

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, à 22: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...

Hors ligne

#11 Le 08/01/2015, à 10:52

grim7reaper

Re : Python: conversion string ---> int et pas float

Ok, j’avais dû mal comprendre le premier message kboo

Hors ligne