IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

evaluer une chaine de caratere en operation mathématique


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 196
    Points : 61
    Points
    61
    Par défaut evaluer une chaine de caratere en operation mathématique
    Bonjour je recupere une chaine de charactere de ce type

    x = 3 et y = 1 qui sont des entiers

    res = "(-3+x) - (y*-49)" qui est une chaine de caractere

    je voudrais pouvoir transformer cette chaine en opertation mathématique avec le remplacement des valeurs récupérés de x et y

    avec eval(res) ça ne marche pas pas car x et y n'ont pas pris les valeurs affectés.


    Merci

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    La fonction eval a un paramètre supplémentaire: on peut lui passer un dictionnaire avec des variables et des valeurs qui sont alors utilisés dans le calcul d'expression.

    Mais l'affectation du résultat d'une expression à une variable (genre x=2*3) ne fait pas partie de ce que sait faire eval. Et "exec" fait trop de choses pour être utilisé pour ça.

    Alors, si on veut faire de l'affectation, il faut reconnaître une variable au début d'une chaine, suivi du "=", et la suite est une expression qui peut être calculée avec eval. Ensuite, on ajoute la variable et sa valeur dans le dictionnaire qui sera fourni en argument aux eval suivants.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par djbad Voir le message
    avec eval(res) ça ne marche pas pas car x et y n'ont pas pris les valeurs affectés.
    Ca mériterait que vous montriez comment vous vous y prenez...
    Car çà fonctionne très bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> x = 3
    >>> s = "x + 10"
    >>> eval(s)
    13
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    J'ai l'impression que vous cherchez à faire ce que l'on appel du calcul symbolique. Et il y a un module Python qui fait ça SymPy. Jetez y un œil.

    Julien

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Quelques éclaircissements concernant mon message précédent.

    Quand on connait x et y avant de calculer l'expression:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    dicovars = {'x':3, 'y':1} # <= valeurs de x et y dans un dictionnaire
     
    res = eval("(-3+x) - (y*-49)", dicovars)
     
    print(res)
    49
    Ce qui donne bien le résultat attendu.

    Mais quand on veut calculer la chaine: "res = (-3+x) - (y*-49)", ça ne marche plus parce qu'il s'agit d'une instruction (à cause du "=") et non d'une expression.

    Ce qu'on peut faire avec cette chaine, c'est de reconnaître le nom de la variable suivi du signe "=" afin de calculer l'expression qui suit par eval:

    La reconnaissance de la variable doit tenir compte de la syntaxe des noms de variables. La solution choisie ici est de passer par une expression régulière:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import re
     
    # préparation du test regex
    motif = r"^([a-z_][a-z0-9_]*) *= *(.+)$"
    motifcomp = re.compile(motif)
     
    # calcul
    dicovars = {'x':3, 'y':1} # <= valeurs de x et y dans un dictionnaire
    instruction = "res = (-3+x) - (y*-49)"
    result = motifcomp.match(instruction)
    if result!=None:
        var = result.group(1) # 1ères parenthèses du motif (avant le "=")
        expression = result.group(2) # 2èmes parenthèses du motif (après le "=")
     
        # calcul de l'expression trouvée
        valeur = eval(expression, dicovars)
        print("Variable: '" + var + "' Valeur:", valeur)
     
        # on met la nouvelle variable et sa valeur dans le dictionnaire pour les calculs suivants
        dicovars[var] = valeur
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 196
    Points : 61
    Points
    61
    Par défaut
    Effectivement le = ne doit pas etre évaluer donc si je fas res = eval("(-3+x) - (y*-49)") ca marche.
    Maintenant pour un calcul unique c'est rapide.
    Mais si fais un boucle du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    y=1
    i=0
    while i!=924695:
    	Res = eval("(-3 + x ) - ( y * -49 )")
    	x=Res
    	i=i+1
    	y=y+1
    print Res
    le temps de calcul est beaucoup plus, je comprends que la fonction eval est plus longue qu'une operation mathématique.
    Mais peut t on quand meme à faire en sorte de se rapprocher du temps de calcul de l'opération.
    avec la fonction eval le temps est d'environ 5.869201 sec
    alors que sand le temps de calcul est de 0.153662 sec.
    Est ce que le moduel simpy est capable d'aller dans ce sens, faut il que je cherche ailleurs

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par djbad Voir le message
    le temps de calcul est beaucoup plus, je comprends que la fonction eval est plus longue qu'une operation mathématique.
    Vous devriez pouvoir améliorer les performances en compilant le code et en utilisant exec (au lieu d'eval).

    Est ce que le moduel simpy est capable d'aller dans ce sens, faut il que je cherche ailleurs
    sympy est différent de simpy.
    Le plus simple est d'installer/tester/...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 196
    Points : 61
    Points
    61
    Par défaut
    en fait en recompilant ca le fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    x = y = 1
    i=0
    code = compile("(-3 + x) - (y * -49)", '(expr)', 'eval')
    While i!=924695:
        x = eval(code)
        i+=1
        y += 1
    print x

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. calcule d'une equation sous forme d'une chaine de carateres
    Par 01211983 dans le forum Général Java
    Réponses: 1
    Dernier message: 10/03/2008, 15h53
  2. [Maths] evaluer une chaine de caractère
    Par davyondo dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 06/11/2007, 14h53
  3. Réponses: 15
    Dernier message: 11/09/2007, 18h36
  4. Extraire une chaine de caratere
    Par matthieu5978 dans le forum Langage
    Réponses: 2
    Dernier message: 15/12/2005, 19h52
  5. evaluer une chaine
    Par mereyj dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 11/12/2005, 15h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo