Bibm@th

Forum de mathématiques - Bibm@th.net

Bienvenue dans les forums du site BibM@th, des forums où on dit Bonjour (Bonsoir), Merci, S'il vous plaît...

Vous n'êtes pas identifié(e).

#1 28-11-2011 20:11:57

math@
Membre
Inscription : 28-11-2011
Messages : 13

[Python] Manipulation des polynomes

bonjour,
Je suis débutante en python et j'aurai besoin de votre aide svp. Mon problème est le suivant: je dois ecrire une fonction qui a comme paramètre une chaine de caractère 'un polynome' je dois afficher seulement les coefficients de ce polynome dans une liste
exemple
ploy('1+2*x^2+3*x^3')
elle renvoie [1,2,3]
je pense que je fais ça avec la fonction 'split' mais je ne sais pas exactement comment faire.
je serai vraiment reconnaissante si vous pourriez m'aider et merci d'avance

Hors ligne

#2 29-11-2011 00:50:14

totomm
Membre
Inscription : 25-08-2011
Messages : 1 093

Re : [Python] Manipulation des polynomes

Bonsoir,

Il faut déjà bien définir la syntaxe propre au polynôme : signes utilisés, espaces, parenthèses...
puis les règles de précédence éventuelles...
Savoir aussi si toutes les puissances de x sont présentes ou si certaines peuvent être omises (coefficient nul ?)
Savoir aussi si les puissances de x sont ordonnées...
Donc on sait alors reconnaitre les coefficients et les affecter à une puissance de x : le choix de l'implémentation d'un petit analyseur peut alors se faire.
un split se fait entre "séparateurs", il faut donc les avoir bien définis...
Il faut en tous cas bien définir comment on reconnait les unités lexicales (tokens).

Etes-vous débutante en programmation ou seulement en Python?

A+. cordialement

Hors ligne

#3 29-11-2011 10:36:37

thadrien
Membre
Lieu : Grenoble
Inscription : 18-06-2009
Messages : 526
Site Web

Re : [Python] Manipulation des polynomes

Bonjour,

Est-ce pour l'honneur de l'esprit humain ou est-ce un exercice donné par un professeur ? Dans ce dernier cas, pouvez-vous nous poster le sujet tel que donné par le professeur ? "Un polynôme", c'est en effet un peu vague.

Pour un problème simple de ce type, un split avec comme séparateur "+" est suffisant pour séparer les monomes. On l'utilise de la manière suivante :


monomes = chaine.split("+")
 

Ensuite, un for sur la liste de monômes pour évaluer chaque monôme est suffisant :


for a in monomes :
    CODE
 

Cependant, pour des problèmes de ce type plus complexes, il faut utiliser un vrai moteur d'analyse syntaxique comme pyparsing. On peut aussi le coder à la main, mais c'est plus dur : apprends déjà à te servir de split.

A+

Hors ligne

#4 03-12-2011 14:59:01

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Bonjour,

Me voilà enfin de retour aux manettes...
J'ai beaucoup réfléchi au problème qui n'est pas si simple que cela...
Je me suis fixé comme objectif d'avoir les coefficients négatifs, 1 ou -1 selon que l'on a +x ou -x et pas de puissance...
J'ai aussi voulu que les puissances de x absentes soient indiquées par des 0 dans l'ordre croissant.

Je n'ai pas trouvé de méthode permettant de "splitter" avec "+" ou "-" selon le cas, à la "volée".
Je me suis résolu à le faire en 2 fois..
Enfin, le .split("-") fait logiquement disparaître le - qu'il faut rétablir.
J'établis donc la liste des puissances de dix présentes dans l'ordre croissant et grâce à l'exposant maximum je constitue une liste des coefficients des monômes valant tous 3.14, ceci m'ayant permis de détecter d'éventuelles erreurs.
Je teste ensuite la position des exposants : un exposant 2 en position 0 me signalant que l'exposant 0 (constante) et l'exposant 1 monôme de degré 1 ne sont pas présents et qu'il convient de le noter dans la liste Coeff_monomes par des 0 en position 0 et 1.
D'où la nécessité de gérer un décalage (dcl+=1) tant que l'index en cours, corrigé du décalage, n'est pas égal à l'exposant correspondant.
Pour l'instant, je dois dire que ce n'est pas un beau programme, que je ne suis pas satisfait du tout, mais qu'il fonctionne à condition d'entrer le polynôme avec la variable x dans l'ordre des puissances croissantes de x...

Je vais m'atteler maintenant à une autre version plus aboutie.

Voilà le programme :


#!/usr/bin/env python
# -*- coding: cp1252 -*-

def titre():
    print
    print "             *******************************************"
    print "             *   -+  Coefficients d'un polynôme +-+    *"
    print "             *                v 1.0                    *"
    print "             *******************************************"
    print


def AvecSansMult(Coeff_Monomes,aster,i,dcl,mono):
    if aster==-1:
        Coeff_Monomes[i+dcl]=[-1,1][1-(mono[0]=="-")]
    else:
        Coeff_Monomes[i+dcl]=int(mono[:aster])
    return Coeff_Monomes

chaine='2-x^2+3*x^4'
L_chaine=chaine.split('+')
Liste_Monomes=[]

titre()

for bloc in L_chaine:
    if bloc==bloc.split("-"):
       Liste_Monomes.append(bloc)
    else:
        decoupe=bloc.split('-')
        for mono in decoupe:
            if mono!="":
                Liste_Monomes.append(mono)

for num,mono in enumerate(Liste_Monomes):
    i=chaine.find(mono)
    if i>0:
        if chaine[i-1]=="-":
            Liste_Monomes[num]="-"+Liste_Monomes[num]

Expos=[]
for mono in Liste_Monomes:
    if "x" not in mono:
        Expos.append(0)
    else:
        i=mono.find("x")
        if "^" not in mono:
            Expos.append(1)
        else:
            Expos.append(int(mono[i+2:]))
           
expo_max,dcl=max(Expos),0
Coeff_Monomes=[3.14]*(expo_max+1)
for i,expo in enumerate(Expos):
    mono=Liste_Monomes[i]
    while i+dcl!=expo:
        Coeff_Monomes[i+dcl]=0
        dcl+=1
    if "x" not in mono:
        Coeff_Monomes[i+dcl]=int(mono)
    else:
        aster=mono.find("*")
        if "^" not in mono:
            Coeff_Monomes=AvecSansMult(Coeff_Monomes,aster,i,dcl,mono)
        else:
            Coeff_Monomes=AvecSansMult(Coeff_Monomes,aster,i,dcl,mono)
               
print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
print "                ",chaine
print "                      sont :"
print "               ",Coeff_Monomes

Quelques sorties :


>>> ================================ RESTART ================
>>>

             *******************************************
             *   -+  Coefficients d'un polynôme +-+    *
             *                v 1.0                    *
             *******************************************

Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 2-x^2+3*x^4
                      sont :
                [2, 0, -1, 0, 3]


>>> ================================ RESTART =================
>>>

             *******************************************
             *   -+  Coefficients d'un polynôme +-+    *
             *                v 1.0                    *
             *******************************************

Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -1+x-3*x^4+2*x^5
                      sont :
                [-1, 1, 0, 0, -3, 2]

>>> ================================ RESTART ================
>>>

             *******************************************
             *   -+  Coefficients d'un polynôme +-+    *
             *                v 1.0                    *
             *******************************************

Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -3*x^3+2*x^5
                      sont :
                [0, 0, 0, -3, 0, 2]
>>>

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#5 03-12-2011 17:07:45

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

RE,

Non, je n'ai pas encore modifié le programme précédent, seulement modifié le programme écrit pour razorb et qui était la problématique réciproque, partir des coeff et écrire le polynôme. Ce petit programme je l'ai ajouté à la suite en retirant la ligne de déclaration de la liste des coeff et la recherche de la longueur de la liste des coeff...
Voilà le morceau que j'ai rajouté à la suite :


# Ajout du programme modifié écrit pour razorb
if len(Coeff_Monomes)==0:
    Poly="0"
else:
    Poly=""
    for i,cof in enumerate(Coeff_Monomes):
        if cof!=0:
            expo=""
            if i==0:
                Poly+=str(cof)
            else:
                sgn="+-"[cof<0]
                if sgn=="+" and Poly=="":
                    sgn=""              
                if abs(cof)==1:
                    cof=""
                else:
                    cof=str(abs(cof))
                if i>1:
                    expo="^"+str(i)
                Poly+=sgn+cof+"x"+expo
    print
    print
    print "           Polynôme reconstruit :"
    print "             ",Poly
 

Quelques résultats :


             *******************************************
             *   -+  Coefficients d'un polynôme +-+    *
             *                v 1.0                    *
             *******************************************

Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -1-3*x^3+2*x^5
                      sont :
                [-1, 0, 0, -3, 0, 2]


           Polynôme reconstruit :
              -1-3x^3+2x^5


            *******************************************
             *   -+  Coefficients d'un polynôme +-+    *
             *                v 1.0                    *
             *******************************************

Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -3*x^3+2*x^4
                      sont :
                [0, 0, 0, -3, 2]


           Polynôme reconstruit :
             -3x^3+2x^5

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#6 03-12-2011 23:54:04

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Bonsoir,

Nouveau code : j'ai bien raccourci la découpe en monômes (avec signes - éventuels):


#!/usr/bin/env python
# -*- coding: cp1252 -*-

from textwrap import wrap

def titre():
    print
    print "             *******************************************"
    print "             *   -+  Coefficients d'un polynôme +-+    *"
    print "             *                v 1.1                    *"
    print "             *******************************************"
    print


def AvecSansMult(Coeff_Monomes,aster,i,dcl,mono):
    if aster==-1:
        Coeff_Monomes[i+dcl]=[-1,1][1-(mono[0]=="-")]
    else:
        Coeff_Monomes[i+dcl]=int(mono[:aster])
    return Coeff_Monomes

chaine='x-3*x^3+2*x^4'
L_chainewp=wrap(chaine,1) # découpe de la chaîne caractère par caractère
L_chaine,Liste_Monomes=[],[]
titre()

# Insertion d'un > avant chaque signe :
# * à partir du 2e signe si le polynôme commence par un -
# * à partir du 1er signe dans le cas contraire
for i, carac in enumerate(L_chainewp):
    symb=""
    if carac in "+-" and i>0:
        symb=">"
        if carac=="+":
            carac=""
    L_chaine.append(symb+carac)

# Reconstruction de la chaine via "".join(), puis découpe selon >    
Liste_Monomes=("".join(L_chaine)).split(">")

Expos=[]
for mono in Liste_Monomes:
    if "x" not in mono:
        Expos.append(0)
    else:
        i=mono.find("x")
        if "^" not in mono:
            Expos.append(1)
        else:
            Expos.append(int(mono[i+2:]))
           
expo_max,dcl=max(Expos),0
Coeff_Monomes=[3.14]*(expo_max+1)
for i,expo in enumerate(Expos):
    mono=Liste_Monomes[i]
    while i+dcl!=expo:
        Coeff_Monomes[i+dcl]=0
        dcl+=1
    if "x" not in mono:
        Coeff_Monomes[i+dcl]=int(mono)
    else:
        aster=mono.find("*")
        if "^" not in mono:
            Coeff_Monomes=AvecSansMult(Coeff_Monomes,aster,i,dcl,mono)
        else:
            Coeff_Monomes=AvecSansMult(Coeff_Monomes,aster,i,dcl,mono)
               
print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
print "                ",chaine
print "                      sont :"
print "               ",Coeff_Monomes

Il reste maintenant à simplifier la suite...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#7 04-12-2011 12:35:26

karlun
Membre
Inscription : 05-05-2010
Messages : 216

Re : [Python] Manipulation des polynomes

Bonjour,

Mais qu'est-ce que j'ai chipoté...
Pourquoi faire simple quand on peut faire compliqué?

Voici ma proposition:


# -*- coding: cp1252 -*-
from textwrap import wrap
def a(polynome):
    "le polynome en traitement"
    a,indice,sol,solut,ind,ind2,ind3,solut2=[],[],[],[],[],[],[],[]
    ix,x,y,d=0,-1,0,0
    cliv=wrap(polynome,1)
    # séparation des éléments du polynome.
    cliv.reverse()
    #inverse l'ordre du polynôme
    for u in cliv:
        a.append(ord(u))
    #transformation de la chaine inversée du polynôme en chiffre
    xt=a.count(120)
    if xt>0:
        x=a.index(120)
        for i in xrange(0,len(a),1):
            if a[i]>47:
                if a[i]<58:
                    indice.append(a[i])
                else:
                    break
        indice.append(44)
    else:
        print 'vous avez introduit '
        print polynome
        print "qui n'est pas un polynôme."


    while ix<xt:

        try:
            plus=a.index(43,x+1)
        except:
            plus=1000
        try:
            moins=a.index(45,x+1)
        except:
            moins=1100
        if min(plus,moins)<1000:
            y=min(plus,moins)
        else:
            y=x
        #Un plus ou un moins après x
       
       
        try:
            x1=a.index(120,x+1)
            #x1= index du x suivant s'il existe
            if a[x1-1]==94:                
                for i in xrange(y,x1,1):
                    if a[i]>47:
                        if a[i]<57:
                            indice.append(a[i])
            else:
                indice.append(49)
                    #indice suivant si un autre x existe
            indice.append(44)
            for q in xrange(x+1,y+1,1):
                sol.append(a[q])
            sol.append(44)

        except:
            x1=0
            for q in xrange(x+1,y+1,1):
                sol.append(a[q])
            sol.append(44)
            indice.append(48)
            for q in xrange(y+1,len(a),1):
                sol.append(a[q])  
        # Au cas où il n'y aurait pas de x.
        x=x1
        ix+=1
    indice.reverse()
    sol.reverse()
   
    if xt>0:
        for m in indice:
            ind+=chr(m)
        ind=''.join(ind)
        ind=ind.split(',')
        ind.reverse()
        for t in ind:
            ind2.append(int(t))
        ind2.append(0)
        for b in xrange(0,len(ind2)-1,1):
            c=ind2[b]-ind2[b+1]
            ind3.append(c)
        for n in sol:
            solut+=chr(n)
        for u in xrange(0,solut.count('+'),1):
            solut.remove('+')
        if solut[len(solut)-1]==',':
            solut.remove(',')
        if solut[0]==',':
            solut.remove(',')
        solut="".join(solut)
        solut=solut.split(',')
        solut.reverse()
        for p in xrange(0,len(solut),1):
            solut2.append(solut[p])
            for m in xrange(0,ind3[p],1):
                solut2.append('0')
        solut2.reverse()
        print 'polynome= ',polynome
        print
        print 'est transfomé en : '
        print solut2

   
   

polyome='3+4x+2x^4-36x^15'
a(polyome)
print
print
polyome='3+4x^2-21x^4-36x^9'
a(polyome)
print
print
polyome='3569'
a(polyome)
print
print
polyome='3x^2'
a(polyome)
print
print
polyome='-53x^12'
a(polyome)
 

pour donner:


polynôme=  3+4x+2x^4-36x^15

est transformé en :
['3', '0', '4', '0', '0', '0', '2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '-36']


polynôme=  3+4x^2-21x^4-36x^9

est transformé en :
['3', '0', '0', '4', '0', '0', '-21', '0', '0', '0', '0', '0', '-36']


vous avez introduit
3569
qui n'est pas un polynôme.


polynôme=  3x^2

est transformé en :
['0', '0', '3']


polynôme=  -53x^12

est transformé en :
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '-53']

Autre approche donc à partir de la fonction "try" et "except"...

Bel exercice pas facile (pour moi).

A+-*/

PS: Je relis et je trouve des erreurs dans quelques résultats (des zéros de trop...)
bigre!  faudra que je me replonge dedans.

Dernière modification par karlun (04-12-2011 12:51:44)


Qui trouve, cherche.

Hors ligne

#8 04-12-2011 22:02:45

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Bonsoir,

Je n'ai guère avancé (pas pu travailler aujourd'hui), si ce n'est que j'ai écrit une autre version de la mise en monômes, cette fois réellement plus "simple" puisque n'usant que de fonctions ou méthodes de base.


#!/usr/bin/env python
# -*- coding: cp1252 -*-

def titre():
    print
    print "             *******************************************"
    print "             *   +-+  Coefficients d'un polynôme +-+   *"
    print "             *                v 1.2                    *"
    print "             *******************************************"
    print


def AvecSansMult(Coeff_Monomes,aster,i,dcl,mono):
    if aster==-1:
        Coeff_Monomes[i+dcl]=[-1,1][1-(mono[0]=="-")]
    else:
        Coeff_Monomes[i+dcl]=int(mono[:aster])
    return Coeff_Monomes

chaine='1+x-3*x^3+2*x^4'
Liste_Monomes,mono,i=[],"",0
titre()
for carac in chaine:
    i+=1
    if i==1:
        mono=carac
    else:
        if carac in "+-":
            Liste_Monomes.append(mono)
            mono="-"*(carac=="-")
        else:
            mono+=carac
Liste_Monomes.append(mono)

Expos=[]
for mono in Liste_Monomes:
    if "x" not in mono:
        Expos.append(0)
    else:
        i=mono.find("x")
        if "^" not in mono:
            Expos.append(1)
        else:
            Expos.append(int(mono[i+2:]))
           
expo_max,dcl=max(Expos),0
Coeff_Monomes=[3.14]*(expo_max+1)

for i,expo in enumerate(Expos):
    mono=Liste_Monomes[i]
    while i+dcl!=expo:
        Coeff_Monomes[i+dcl]=0
        dcl+=1
    if "x" not in mono:
        Coeff_Monomes[i+dcl]=int(mono)
    else:
        aster=mono.find("*")
        if "^" not in mono:
            Coeff_Monomes=AvecSansMult(Coeff_Monomes,aster,i,dcl,mono)
        else:
            Coeff_Monomes=AvecSansMult(Coeff_Monomes,aster,i,dcl,mono)
               
print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
print "                ",chaine
print "                      sont :"
print "               ",Coeff_Monomes

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#9 05-12-2011 14:56:04

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Bonjour,

Changement de version (majeure) v. 2.0...
J'ai réellement créé une fonction et non un script.
Je me passe des exposants, je construis une 2e version de la liste des monômes, chacun occupant la case dont l'index est son exposant (ne marche pas avec des exposants négatifs, donc... Saura-t-on un jour quel était le cahier des charges exact qui était fixé).
Il faut impérativement entrer un polynôme ordonné selon les puissances croissantes de x, et matérialiser les multiplications par un astérisque.


def Poly(chaine):
    chaineb,Liste_Monomes,mono,expo_max=chaine+"+",[],"",-10**20
    for i,carac in enumerate(chaineb):
        if i==0:
            mono=carac
        else:
            if carac in "+-":
                Liste_Monomes.append(mono)
                if "^" in mono:
                    expo_max=max(expo_max, int(mono[mono.find("^")+1:]))
                else:
                    expo_max=max(expo_max, ("x" in mono))
                mono="-"*(carac=="-")
            else:
                mono+=carac

    ListeMonomes=[None]*(expo_max+1)
    Coeff_Monomes=[0]*(expo_max+1)

    for mono in Liste_Monomes:
        if "x" not in mono:
            ListeMonomes[0]=mono
        else:
            if "^" not in mono:
                ListeMonomes[1]=mono
            else:
                i=mono.find("^")
                puiss=int(mono[i+1:])
                ListeMonomes[puiss]=mono
           
    for i,mono in enumerate(ListeMonomes):
        if mono!=None:
            if i ==0:
                Coeff_Monomes[i]=int(mono)
            else:
                aster=mono.find("*")
                if aster==-1:
                    Coeff_Monomes[i]=int("-"*(mono[0]=="-")+"1")
                else:
                    Coeff_Monomes[i]=int(mono[:aster])
    print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
    print "                ",chaine
    print "                      sont :"
    print "               ",Coeff_Monomes
 


>> ================================ RESTART ==========================
>>>
>>> Poly('1+x-3*x^3+2*x^10')
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 1+x-3*x^3+2*x^10
                      sont :
                [1, 1, 0, -3, 0, 0, 0, 0, 0, 0, 2]
>>> Poly("-1+2*x^2-3*x^3+x^5")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -1+2*x^2-3*x^3+x^5
                      sont :
                [-1, 0, 2, -3, 0, 1]
>>> Poly("x^3-2*x^5-x^7")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 x^3-2*x^5-x^7
                      sont :
                [0, 0, 0, 1, 0, -2, 0, -1]
>>>
 

Je dois pouvoir faire plus court encore

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#10 06-12-2011 23:02:21

math@
Membre
Inscription : 28-11-2011
Messages : 13

Re : [Python] Manipulation des polynomes

Bonjour tout le monde,
merci beaucoup pour votre aide et excusez moi car j'ai pas répondu j'étais en pleine révision pour les examens.
je suis débutante en programmation et en python mais je dois l'apprendre car la programmation est un outil indéspensable pour ma spécialité. En fait pour la fonction polyno je dois donner des arguments arbitrairessoit (1) des coefficients d'un polynome (2) une chaine de caractère( un polynome) et le résultat sera tjr la liste des coefficients j'ai réussi à faire la 1ère partie le problème c que comment je vais faire ces deux chose en une seule fonction ce que je veux dire c que
je défini une fonction dont les arguments sont arbitraie :def poly(*arg):
pour le 1er cas j'ai réussi à le faire mais pour le second je ne sais pas comment dire que 'arg' est un polynome et faire le teste pour avoir seulement les coefficients de ce polynome.
Je m'excuse une autre fois et merci beaucoup pour votre aide à la prochainne

Hors ligne

#11 06-12-2011 23:12:48

thadrien
Membre
Lieu : Grenoble
Inscription : 18-06-2009
Messages : 526
Site Web

Re : [Python] Manipulation des polynomes

math@ a écrit :

le problème c que comment je vais faire ces deux chose en une seule fonction ce que je veux dire c que
je défini une fonction dont les arguments sont arbitraie :def poly(*arg):

Bonjour,

Cela me semble un peu risqué. Le mieux est de bien séparer les fonctions, au contraire : un emploi, une fonction, point barre. En particulier si tu débutes en programmation : tu risques de te noyer dans les détails d'implantation au lieu de te concentrer sur l'essentiel : l'algorithme.

Hors ligne

#12 07-12-2011 11:25:13

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Bonjour,

En fait pour la fonction polyno je dois donner des arguments arbitraires, soit
(1) des coefficients d'un polynome
(2) une chaine de caractère (un polynome)
et le résultat sera tjr la liste des coefficients.

Là, je dois avouer que je comprends pas ton point (1)
Si, en entrée, tu as les coefficients d'un polynôme et qu'en sortie tu as les mêmes coefficients de ce polynôme : il n'y a rien à faire... ????

Tu ne veux pas dire plutôt :
(1) Entrée : coefficients du Polynôme --> sortie écriture du polynôme
2) Entrée : le polynôme (chaine de caractères) --> Sortie les coefficients du polynôme.
Tu veux réaliser  ça en une seule fonction ?
Si oui, alors je rejoins thadrien...
Sauf, si c'est un exercice imposé, je te déconseille de procéder ainsi : ce n'est pas "propre". Tant que tu te débats avec un programme de moins de 100 lignes, c'est gérable, après... gare !

Ta fonction demande que tu lui passes des paramètres qui sont dans un sens une liste de coefficients, dans l'autre une chaîne de caractères... Soit deux objets de natures différentes et qui sont les deux extrémités d'un cheminement :
sauf à questionner l'utilisateur sur ce qu'il veut faire (1) ou (2) et de lui demander de fournir le point de départ, je ne vois pas comment ça peut fonctionner.
Après recherche (une idée m'est venue), Python peut déterminer de lui-même (si tu l'aides) si un objet est du type string ou list...


>>> a='x^2-3x^5'
>>> if isinstance(a,list):
  print "a est du type liste"
elif isinstance(a,str):
  print "a est du type string"

 
a est du type string
>>>

Donc
1. appeler Poly(........)
2. à l'intérieur de ta fonction : traiter les 2 cas ci-dessus.
En gros comme ça :


def poly(objet):
    if isinstance(objet,list):
        ....
        traitement de l'objet liste pour afficher une chaine de caractères (le Polynôme)
        ....
    elif isinstance(objet,str):
        ....
        traitement de l'
objet chaine pour afficher la liste des coefficients (du poynôme)
        ....
 

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#13 07-12-2011 13:39:17

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Re,

Je savais bien qu'il était possible de faire court.
Je construis les monômes un par un sans les stocker.
Les + ou - sont les tests de fin de monôme, c'est pourquoi j'en rajoute un à la fin de la chaîne.
Le 1er caractère de la chaîne n'est jamais un +, donc je stocke ce 1er caractère dans mon monôme.
Si ce n'est pas le 1er alors je teste s'il s'agit de + ou -
    Si c'est le cas, je teste la présence de x : si non, c'est un terme indépendant que je stocke converti en entier, si oui je vais chercher la position éventuelle de * et de ^ : les 2 variables valent -1 en cas de non présence.
Le nombre de zéros (différence entre nouvel expo et ancien expo corrigé de 1 de temps en temps) nécessaire doit être stocké avant de stocker à son tour le coefficient.
Pour d'autres explications, demande...
Pour Python 2.5, 2.6, 2.7.
Pour Python 3.x, remplacer print "... ", par print("..."), : print est devenu la fonction print().


def Poly(chaine):
    chaineb,Coeff,mono,expo,expo1=chaine+"+",[],"",0,0
    for i,carac in enumerate(chaineb):
        if i==0:
            mono=carac
        else:
            if carac in "+-":
                if "x" not in mono:
                    Coeff.append(int(mono))
                else:
                    puiss,aster=mono.find("^"),mono.find("*")
                    if puiss==-1:
                        expo,dcl=1,1-(expo1==0 and Coeff!=[])
                    else:
                        expo=int(mono[puiss+1:]) #  nouvel exposant
                        dcl=expo-expo1-(Coeff!=[]) # nb zéros ajoutés
                    for j in range(dcl):  # boucle d'ajout des zéros
                        Coeff.append(0)
                    if aster==-1:  # Pas d'étoile
                        Coeff.append(int("-"*(mono[0]=="-")+"1"))
                    else:  # On stocke du début du monôme à l'*
                        Coeff.append(int(mono[:aster]))
                    expo1=expo
                mono="-"*(carac=="-")
            else:
                mono+=carac

    print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
    print "                ",chaine
    print "                      sont :"
    print "               ",Coeff

               
Ça fonctionne :


>>> Poly("1+x^2-3*x^4+5*x^5")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 1+x^2-3*x^4+5*x^5
                      sont :
                [1, 0, 1, 0, -3, 5]
>>> Poly("-x^2+3*x^4+5*x^5-x^8")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -x^2+3*x^4+5*x^5-x^8
                      sont :
                [0, 0, -1, 0, 3, 5, 0, 0, -1]
>>>

J'ai testé l'astuce avec isinstance() : ça marche.
J'ai ajouté le morceau destiné à razorb et je tape Poly(objet) où objet est soit une chaine soit une liste, et, en sortie, j'ai bien le résultat attendu.
Pour des coefficients non entiers "en virgule flottante", remplacer int() par float()
Cette fonction complète avec isinstance() intéresse-t-elle quelqu'un dans l'immédiat ? Je vais attendre le passage de math@ et je posterai après sa réflexion...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#14 08-12-2011 20:08:25

math@
Membre
Inscription : 28-11-2011
Messages : 13

Re : [Python] Manipulation des polynomes

yoshi a écrit :

Re,

Je savais bien qu'il était possible de faire court.
Je construis les monômes un par un sans les stocker.
Les + ou - sont les tests de fin de monôme, c'est pourquoi j'en rajoute un à la fin de la chaîne.
Le 1er caractère de la chaîne n'est jamais un +, donc je stocke ce 1er caractère dans mon monôme.
Si ce n'est pas le 1er alors je teste s'il s'agit de + ou -
    Si c'est le cas, je teste la présence de x : si non, c'est un terme indépendant que je stocke converti en entier, si oui je vais chercher la position éventuelle de * et de ^ : les 2 variables valent -1 en cas de non présence.
Le nombre de zéros (différence entre nouvel expo et ancien expo corrigé de 1 de temps en temps) nécessaire doit être stocké avant de stocker à son tour le coefficient.
Pour d'autres explications, demande...
Pour Python 2.5, 2.6, 2.7.
Pour Python 3.x, remplacer print "... ", par print("..."), : print est devenu la fonction print().


def Poly(chaine):
    chaineb,Coeff,mono,expo,expo1=chaine+"+",[],"",0,0
    for i,carac in enumerate(chaineb):
        if i==0:
            mono=carac
        else:
            if carac in "+-":
                if "x" not in mono:
                    Coeff.append(int(mono))
                else:
                    puiss,aster=mono.find("^"),mono.find("*")
                    if puiss==-1:
                        expo,dcl=1,1-(expo1==0 and Coeff!=[])
                    else:
                        expo=int(mono[puiss+1:]) #  nouvel exposant
                        dcl=expo-expo1-(Coeff!=[]) # nb zéros ajoutés
                    for j in range(dcl):  # boucle d'ajout des zéros
                        Coeff.append(0)
                    if aster==-1:  # Pas d'étoile
                        Coeff.append(int("-"*(mono[0]=="-")+"1"))
                    else:  # On stocke du début du monôme à l'*
                        Coeff.append(int(mono[:aster]))
                    expo1=expo
                mono="-"*(carac=="-")
            else:
                mono+=carac

    print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
    print "                ",chaine
    print "                      sont :"
    print "               ",Coeff

               
Ça fonctionne :


>>> Poly("1+x^2-3*x^4+5*x^5")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 1+x^2-3*x^4+5*x^5
                      sont :
                [1, 0, 1, 0, -3, 5]
>>> Poly("-x^2+3*x^4+5*x^5-x^8")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -x^2+3*x^4+5*x^5-x^8
                      sont :
                [0, 0, -1, 0, 3, 5, 0, 0, -1]
>>>

J'ai testé l'astuce avec isinstance() : ça marche.
J'ai ajouté le morceau destiné à razorb et je tape Poly(objet) où objet est soit une chaine soit une liste, et, en sortie, j'ai bien le résultat attendu.
Pour des coefficients non entiers "en virgule flottante", remplacer int par float000
Cette fonction complète avec isinstance() intéresse-t-elle quelqu'un dans l'immédiat ? Je vais attendre le passage de math@ et je posterai après sa réflexion...


@+

bonjour yoshi,
j'espère que vous allez bien ainsi les autres membres, merci pour le programme. En fait je suis actuellement entraine de faire cette fonction la vérité c un projet que je dois le faire et je dois le rendre demain. Dans le programme comme la ligne 16 et 13 j'espère que vous allez m'aider à terminer mon projet sinon c pas grave en tout cas je vous remercie vous m'avez déja aider énormement et les autres membres aussi merci.

Hors ligne

#15 08-12-2011 21:07:42

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Re,

Je veux bien t'aider, mais il faudrait que je comprenne, moi, ce que veut dire :

Dans le programme comme la ligne 16 et 13

A tout hasard, je vais expliquer les lignes 13 et 16.
Donc je veux ajouter le nombre de zéros nécessaires...
En Python comme dans beaucoup de langages les boucles commencent à 0...
Donc : for i in range(3) teste les valeurs 0, 1 et 2. 3 est la valeur d'arrêt...
Dans le programme, ce n'est pas 3 ni 2 le test d'arrêt mais la variable dcl (pour décalage).
La variable puiss donne la position -éventuelle- du symbole ^ dans le monôme en cours et vaut -1 si ce symbole est absent : dans ce cas, l'exposant en cours vaut 1.
Quant au décalage dcl, il vaut là soit 0, soit 1.
Il se trouve que j'ai des manies de programmation dont l'usage des booleens. : True vaut 1, False vaut 0
Donc
dcl =1- (expo1==0 and Coeff!=[]), c'est à dire :
si expo1 (le précédent exposant= vaut 0 et que la liste des coefficients n'est pas vide, cela signifie que le monôme en cours est du premier degré et qu'il y a déjà eu un  monôme (de degré 0, une constante donc), avant) il n'y a pas lieu de stocker un 0 avant le coefficient en cours.
La condition entre parenthèses est vraie et vaut 1 --> dcl = 1 -1 =0, la boucle commence à 0 et s'arrête au 0 : elle ne démarre pas.
Je pourrais écrire à la place de dcl =1- (expo1==0 and Coeff !=[]) -->
if expo1==0 and Coeff !=[]:
    dcl =0
else:
    dcl=1
C'est clair ?

Supposons que la liste des monômes commence à 2x^3 (par exemple) donc expo=3 : je dois donc, avant d'inscrire le 2, commencer par inscrire 0,0,0 dans la liste correspondant à 0x^0, x^1 et 0^2 donc une boucle allant de 0 à 3 d'où dcl qui vaut 3.
expo1 a été initialisé à 0, d'où dcl = expo-expo1=3-0 = 3, ça colle.
Mais supposons que mon polynôme ait été 1+2x^3..
J'ai bien déjà stocké 1 dans Coff, en passant au monôme suivant j'ai expo1=expo donc expo1 = 0 quand même et expo-expo1 = 3 ce qui est faux : je n'ai besoin de rajouter que deux 0
Donc si Coff!=[] est vrai (Coff non vide)  --> (Coff !=[]) vaut 1 et dcl vaut alors expo - expo1 - 1 = 3 - 0 - 1 = 2.
Voilà pour la ligne 146.
Je poste déjà ça et je continue ensuite...

@tout de suite


Arx Tarpeia Capitoli proxima...

Hors ligne

#16 08-12-2011 21:45:25

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Re,

Je reprends donc.
Ligne 20 : Coeff.append(int("-"*(mono[0]=="-")+"1"))
"-"*(mono[0]=="-") 
si mono[0]=="-"  <===>  si le monôme commence par un "-" alors (mono[0]=="-") vaut 1 et va ajouter 1 signe "-" à "1" pour donner "-1"
Et s'il commence par un "+" ? Alors  (mono[0]=="-") vaut 0 et va ajouter 0 signe "-" à "1" pour donner "1".
Là, on est dans le cas où  le symbole * est absent prouvant que le coeff de x est +1 (où on n'écrit pas le +) ou -1...

Ligne 15 :
mono[puiss+1:] signifie mono depuis la position qui suit  ^ à la fin : ce qui m'évite d'aller chercher la longueur du nombre exposant. C'est Python qui se débrouille seul : je lui donne le top départ et il parcourt le monôme jusqu'à sa fin.

Ligne 22. C'est l'autre cas
mono[:aster] on parcourt mono du début et on s'arrête à la position de *, position non comprise...

C'est bon ?

A titre indicatif.


def Poly(objet):
    if isinstance(objet,str):
        chaine,chaineb,mono=objet,objet+"+",""
        expo1,expo,Coeff=0,0,[]
        for i,carac in enumerate(chaineb):
            if i==0:
                mono=carac
            else:
                if carac in "+-":
                    if "x" not in mono:
                        Coeff.append(int(mono))
                    else:
                        puiss,aster=mono.find("^"),mono.find("*")
                        if puiss==-1:
                            expo,dcl=1,1-(expo1==0 and Coeff!=[])
                        else:
                            expo=int(mono[puiss+1:]) # valeur du nouvel exposant
                            dcl=expo-expo1-(Coeff!=[]) # nombre de zéros à rajouter
                        for j in range(dcl):  # boucle d'ajout des zéros
                            Coeff.append(0)
                        if aster==-1:  # Pas d'étoile
                            Coeff.append(int("-"*(mono[0]=="-")+"1"))
                        else:          # Il y a une étoile
                                   # On stocke du début du monome jusqu'à l'étoile
                            Coeff.append(int(mono[:aster]))                    
                        expo1=expo
                    mono="-"*(carac=="-")
                else:
                    mono+=carac

        print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
        print "                ",chaine
        print "                      sont :"
        print "               ",Coeff
    elif isinstance(objet,list):
        Coeff,sgn=objet,""
        if len(Coeff)==0:
            Poly="0"
        else:
            Poly=""
            for i,cof in enumerate(Coeff):
                if cof!=0:
                    expo=""
                    if i==0:
                        Poly+=str(cof)
                    else:
                        sgn="+-"[cof<0]
                        if sgn=="+" and Poly=="":
                            sgn=""
                        if abs(cof)==1:
                            cof=""
                        else:
                            cof=str(abs(cof))+"*"
                        if i>1:
                            expo="^"+str(i)
                        Poly+=sgn+cof+"x"+expo

        print "Le polynôme correspondant à la liste de coefficients :"
        print "                ",Coeff
        print "                      est :"
        print "               ",poly

Exemples de sorties.

>>> ================================ RESTART ====================
>>>
>>> Poly("1+x^2-3*x^4+5*x^5")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 1+x^2-3*x^4+5*x^5
                      sont :
                [1, 0, 1, 0, -3, 5]
>>> Poly([1, 0, 1, 0, -3, 5])
Le polynôme correspondant à la liste de coefficients :
                 [1, 0, 1, 0, -3, 5]
                      est :
                1+x^2-3*x^4+5*x^5
>>>
>>> Poly("-x^2+3*x^4+5*x^5-x^8")
Les Coefficients du polynôme (ordre des puissances croissantes de x) :
                 -x^2+3*x^4+5*x^5-x^8
                      sont :
                [0, 0, -1, 0, 3, 5, 0, 0, -1]
>>> Poly([0, 0, -1, 0, 3, 5, 0, 0, -1])
Le polynôme correspondant à la liste de coefficients :
                 [0, 0, -1, 0, 3, 5, 0, 0, -1]
                      est :
                -x^2+3*x^4+5*x^5-x^8
>>>

@+

[EDIT] for i, carac in enumerate(Objet): est un mix entre in range(len(Objet)) et in Objet...
Ça évite de devoir
- soit gérer un compteur dans le cas de -->  for carac in Objet:  puis i+=1
- soit extraire carac à partir de son index dans le cas de --> for i in range(len(Objet)): puis carac = Objet[ i ]


Arx Tarpeia Capitoli proxima...

Hors ligne

#17 10-12-2011 12:39:57

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

RE,

Et je continue encore et encore..
Retour de la méthode .split().

def Poly(objet):
    if isinstance(objet,str):
        chaine,Coeff,expo1,expo=objet,[],0,0
        ListeMonomes=(chaine[0]+chaine[1:].replace("-","+-")).split("+")
        for i,mono in enumerate(ListeMonomes):
            aster,ix,puiss=mono.find('*'),mono.find('x'),mono.find('^')
            if ix==-1:
                Coeff.append(int(mono))
            else:
                if puiss==-1:
                    expo,dcl=1,1-(expo1==0 and Coeff!=[])
                else:
                    expo=int(mono[puiss+1:]) # valeur du nouvel exposant
                    dcl,expo1=expo-expo1-(Coeff!=[]),expo # nb de zéros
                for j in range(dcl):  # boucle d'ajout des zéros
                    Coeff.append(0)
                if aster==-1:  # Pas d'étoile
                    Coeff.append(int("-"*(mono[0]=="-")+"1"))
                else:  # On stocke du début du monome jusqu'à l'étoile
                    Coeff.append(int(mono[:aster]))
                    expo1=expo

        print "Les Coefficients du polynôme (ordre des puissances croissantes de x) :"
        print "                ",chaine
        print "                      sont :"
        print "               ",Coeff
    elif isinstance(objet,list):
        Coeff,sgn=objet,""
        if len(Coeff)==0:
            poly="0"
        else:
            poly=""
            for i,cof in enumerate(Coeff):
                if cof!=0:
                    expo=""
                    if i==0:
                        poly+=str(cof)
                    else:
                        sgn="+-"[cof<0]
                        if sgn=="+" and poly=="":
                            sgn=""
                        if abs(cof)==1:
                            cof=""
                        else:
                            cof=str(abs(cof))+"*"
                        if i>1:
                            expo="^"+str(i)
                        poly+=sgn+cof+"x"+expo

        print "Le polynôme correspondant à la liste de coefficients :"
        print "                ",Coeff
        print "                      est :"
        print "               ",poly

Plus court, plus rapide...
Puisque split('+") fait sauter les +, j'ai imaginé, à partir de la position 1, de remplacer via la méthode .replace(), "-" par "+-" et d'appliquer split().


@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#18 15-12-2020 13:07:06

Vincent2
Invité

Re : [Python] Manipulation des polynomes

bonjour
je suis débutant en programmation python et j'ai un problème avec ce que j'ai.
il m'a été demandé de réaliser en python un package qui implémente efficacement toutes les opérations réalisable sur
les polynômes
Et je connais pas comment je vais procéder.

#19 18-12-2020 11:18:26

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 988

Re : [Python] Manipulation des polynomes

Bonjour,

l m'a été demandé de réaliser en python un package qui implémente efficacement toutes les opérations réalisable sur les polynômes

Sur des polynômes Y Y compris du 5e ou 6e degré ou seulement des trinômes ?  Ce n'est pas la même musique...
Très exactement, ces opérations comprennent quoi ?
Recherche des racines ?
Factorisations ?
Calcul discriminant ?
Signe ?
Tableau de variation ?
Dérivée ?

Selon, ce que tu vas décider  cela demandera plus ou moins de capacités techniques en matière de programmation.
Et c'est à un débutant qu'on demande ça ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

Pied de page des forums