Partage
  • Partager sur Facebook
  • Partager sur Twitter

unsupported operand type

Appel d'une fonction

    19 mars 2018 à 12:00:35

    Bonjour,
    J'ai écrit un petit code python (level débutant) mais quand je compile ce dernier me renvoie des erreurs,
    Je vous mets le code ici
    import math 
     
    def SQ(x):
        return x**2
    def funx1(x1,x2,x3):
        return 8*(x2-x1)
    def funx2(x1,x2,x3):
        return x1*x3+0.5*x1-(1+0.5)*x2
    def funx3(x1,x2,x3):
        return 50*(1-(1+0.5)*x2+0.5*x2*x2)-0.5*x3
    def rk4(f, dt, x1, x2, x3,i):
        k1 = dt * f(x1,x2,x3)
        k2 = dt * f(x1 + 0.5*k1,x2 + 0.5*k1,x3 + 0.5*k1)
        k3 = dt * f(x1 + 0.5*k2,x2 + 0.5*k2,x3 + 0.5*k2)
        k4 = dt * f(x1 + k3,x2 + k3,x3 + k3)
        if i==1 :
            return x1 + (k1 + 2 * k2 + 2 * k3 + k4) /6.0
        if i==2 :
            return x2 + (k1 + 2 * k2 + 2 * k3 + k4) /6.0
        if i==3 :
            return x3 + (k1 + 2 * k2 + 2 * k3 + k4) /6.0
    def transpose(X):
        return map(list, zip(*X))
     
    def Addvector(X,Y):
        #X=[]
        #Y=[]
        K=[0,0,0]
        for i in range(len(X)):
            K[i]=X[i] + Y[i]
            return K
    def Subvector(X,Y):
        #X=[]
        #Y=[]
        K=[0,0,0]
        for i in range(len(X)):
            K[i]=X[i] - Y[i]
        return K
    def ScalarProd(X,Y):
        if len(K)==len(L) and len(K)!=0:
                return sum([K[n]*L[n] for n in range(len(K))])
            else:
                return 0
         
    def ScalarMul(X , p):
        res =[0,0,0]
        for i in range(len(X)):
            res[i]= X[i]*p
        return res
    def MatrixMulti(X,Y):
        res=[[0,0,0],[0,0,0],[0,0,0]]
        for i in range(len(X)):
            for j in range(len(Y[0])):
                for k in range(len(Y)):
                    res [i][j] += X[i][k]*Y[k][j]
        return res
     
    def NormalizeVecto(X):
        res = [0,0,0]
        for i in range(len(X)):
            suma += X[i]*X[x]
        for i in range(len(X)):
            res [i] = X[x]/math.sqrt(suma)
        return res
         
    def Modvecto(X):
        suma = 0
        for i in range(len(X)):
            suma += X[i]**2
        return math.sqrt(suma)
    def SQ(x):
        return x*x
     
    def Orthogonalization(X):
        out = [[0,0,0],[0,0,0],[0,0,0]]
        suma = [0,0,0]
        out = X
        for i in range(len(X)):
            for j in range(i-1):
                suma = Addvector(suma,ScalarMul(out[j],ScalarProd(out[j],X[i])/SQ(Modvecto(out[j]))))
            out[i] = Subvector(X[i],suma)
        for k0 in range(len(X)):
            if math.fabs(out[i][k0])< 1e-10 :
                out[i][k0] = 0
        return out
             
     
    if __name__ == '__main__':
        raw_input('rikitake system')
        dimension = 3
        xc1 = 0.0
        xc2 = 0.0
        xc3 = 0.0   
        N0 = 1e6
        r=8
        g = 50
        f = 0.5
        m = 0.5
        T = 1e4
        dT = 1e-3
            g = 50
        dy = [0.0,0.0,0.0]
        dummy = [0,0,0]
        lyapunov = []
        sumly = [0,0,0] 
        v = [[1,0,0],[0,1,0],[0,0,1]]
        v1 = [[0,0,0],[0,0,0],[0,0,0]]
        unit = [[0,0,0],[0,0,0],[0,0,0]]
        J = [[0,0,0],[0,0,0],[0,0,0]]
        unit = v
        for n in range(int(T/dT)):
            xc1 = rk4(funx1, dT, dy[0],dy[1],dy[2],0)
            xc2 = rk4(funx2, dT, dy[0],dy[1],dy[2],1)   
            xc3 = rk4(funx3, dT, dy[0],dy[1],dy[2],2)
            dy[0] = xc1
            dy[1] = xc2
            dy[2] = xc3
            if n > int(N0):
                J[0][0] = -r
                J[0][1] = r
                J[0][2] = 0
                J[1][0] = xc3+m
                J[1][1] = -1-m
                J[1][2] = xc1
                J[2][0] = -g*(1+m)*xc2+g*2*xc1
                J[2][1] = -g*xc1*(1+m)
                J[2][2] = -f
                J[0] = Addvector(unit[0],ScalarMul(J[0], dT))
                J[1] = Addvector(unit[1],ScalarMul(J[1], dT))
                J[2] = Addvector(unit[2],ScalarMul(J[2], dT))
                v1 = Orthogonalization(MatrixMulti(J,transpose(v)))
                for k in range(3):
                    lyapunov[k] = math.log(Modvecto(v1[k]))/dT
                    v[k]=NormalizeVecto(v1[k])
                    sumly[k] += lyapunov[k]
        print("Time Averaged Lyapunov Exponents.")
        print(sumly/(int(T/dT - N0)))
        #print("l1=" sumly[0]/(int(T/dT - N0)))
        #print("l2=" sumly[1]/(int(T/dT - N0)))
        #print("l3=" sumly[2]/(int(T/dT - N0)))
        #print("ltot=" sumly[0]/(int(T/dT - N0))+sumly[1]/(int(T/dT - N0))+sumly[2]/(int(T/dT - N0)))

    et l'erreur que j'obtiens :

    rikitake system
    Traceback (most recent call last):
      File "lyapunov.py", line 112, in <module>
        xc1 = rk4(funx1, dT, dy[0],dy[1],dy[2],0)
      File "lyapunov.py", line 12, in rk4
        k1 = dt * f(x1,x2,x3)
      File "lyapunov.py", line 6, in funx1
        return 8*(x2-x1)
    TypeError: unsupported operand type(s) for -: 'float' and 'NoneType'

    Est-ce que quelqu'un peut me guider ou me dire ce qui ne va pas dans le code et comment le corriger?
    Merci.

    • Partager sur Facebook
    • Partager sur Twitter
      19 mars 2018 à 13:19:24

      Dans funx1, une des deux variables x1 ou x2 vaut None, et donc on peut pas faire de soustraction avec.

      La solution simple pour ce genre de truc, c'est d'ajouter des print à plusieurs endroits du code pour comprendre d'où vient ce None inattendu.

      • Partager sur Facebook
      • Partager sur Twitter

      Blond, bouclé, toujours le sourire aux lèvres...

        19 mars 2018 à 13:52:53

        LoupSolitaire a écrit:

        Dans funx1, une des deux variables x1 ou x2 vaut None, et donc on peut pas faire de soustraction avec.

        La solution simple pour ce genre de truc, c'est d'ajouter des print à plusieurs endroits du code pour comprendre d'où vient ce None inattendu.

        je vais tester ça, merci bien



        • Partager sur Facebook
        • Partager sur Twitter
          19 mars 2018 à 14:42:21

          Après avoir lu un peu plus en détail, je pense qu'il faudrait afficher la valeur de la liste dy à chaque tour de boucle pour voir à quel moment un None se glisse dedans. A juste lire le code je pense que ça vient forcément des valeurs de cette liste même si j'arrive pas trop à comprendre comment ce None peut arriver là.
          • Partager sur Facebook
          • Partager sur Twitter

          Blond, bouclé, toujours le sourire aux lèvres...

            19 mars 2018 à 18:20:38

            Je fais l'affichage dans l'une des fonctions?
            • Partager sur Facebook
            • Partager sur Twitter
              19 mars 2018 à 18:40:37

              hey, ligne 112 intercale un print juste avant l'appel à rk4 pour vérifier les valeurs de dy

              -
              Edité par __Nicolas__ 19 mars 2018 à 18:41:03

              • Partager sur Facebook
              • Partager sur Twitter
                20 mars 2018 à 9:04:13

                Bonjour,
                Voilà ce que j'obtiens comme résultat
                rikitake system
                voir ligne 112
                voir ligne 112
                Traceback (most recent call last):
                  File "lyapunov.py", line 113, in <module>
                    xc1 = rk4(fun1 , dT, dy[0],dy[1],dy[2],0)
                  File "lyapunov.py", line 12, in rk4
                    k1 = dt * f(x1,x2,x3)
                  File "lyapunov.py", line 6, in fun1
                    return 8*x2 - 8*x1
                TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
                
                Il fait le print seulement deux fois
                • Partager sur Facebook
                • Partager sur Twitter
                  20 mars 2018 à 13:10:21

                  Non ! :lol:

                  Fait 

                  print(dy)

                  Pour voir les valeurs de ta liste

                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 mars 2018 à 13:24:58

                    Bonjour,
                    Oups vous avez raison, voilà ce que j'obtiens,
                    rikitake system
                    [0.0, 0.0, 0.0]
                    [None, 0.0, 0.04817844733188667]
                    Traceback (most recent call last):
                      File "lyapunov.py", line 113, in <module>
                        xc1 = rk4(fun1 , dT, dy[0],dy[1],dy[2],0)
                      File "lyapunov.py", line 12, in rk4
                        k1 = dt * f(x1,x2,x3)
                      File "lyapunov.py", line 6, in fun1
                        return 8*x2 - 8*x1
                    TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
                    
                    C'est bizarre ça, pourquoi les éléments de la liste sont modifiés dès le départ

                    -
                    Edité par newgate 20 mars 2018 à 13:29:05

                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 mars 2018 à 16:18:54

                      Le bug est donc dans ta fonction rk4 puisque c'est elle qui renvoie None à un moment.

                      Au passage les éléments ne sont pas modifiés dès le départ, la ligne 2 montre bien que les 3 éléments sont à 0.0 comme à l'initialisation.

                      -
                      Edité par LoupSolitaire 20 mars 2018 à 16:25:24

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Blond, bouclé, toujours le sourire aux lèvres...

                        20 mars 2018 à 16:47:29

                        Re bonjour,


                        C'est vraiment à la première itération que ça foire, mais ce n'est pas quand il fait appel à la fonction fun1? Pour être franc j'ai écrit ce code à partir d'un code C++ mais là je ne vois pas comment la première valeur de la liste dy devient none!!!

                        • Partager sur Facebook
                        • Partager sur Twitter
                          20 mars 2018 à 17:44:44

                          Re !

                          bon j'ai regardé d'un peu plus près et je pense avoir compris pourquoi le code plante !

                          Prenons les chose dans l'ordre :

                          • Le problème est qu'un None vient se glisser dans 'dy' a l'index 0.
                          • or le seul endroit, ou on modifie cette valeur, c'est à la ligne 115.
                          • On met donc cette valeur à celle de 'xc1', qui vaut lui-même ce que retourne l'appel a 'rk4' ligne 112.
                          • Le problème viens donc d'ici ! il y a un moment ou 'rk4' ne retourne rien.

                          (je repose ici le code de 'rk4' pour bien comprendre : )

                          def rk4(f, dt, x1, x2, x3,i):
                              k1 = dt * f(x1,x2,x3)
                              k2 = dt * f(x1 + 0.5*k1,x2 + 0.5*k1,x3 + 0.5*k1)
                              k3 = dt * f(x1 + 0.5*k2,x2 + 0.5*k2,x3 + 0.5*k2)
                              k4 = dt * f(x1 + k3,x2 + k3,x3 + k3)
                              if i==1 :
                                  return x1 + (k1 + 2 * k2 + 2 * k3 + k4) /6.0
                              if i==2 :
                                  return x2 + (k1 + 2 * k2 + 2 * k3 + k4) /6.0
                              if i==3 :
                                  return x3 + (k1 + 2 * k2 + 2 * k3 + k4) /6.0
                          •  On remarque ici que 'rk4' ne retourne une valeur que si on lui passe en paramètre 'i' la valeur 1, 2, ou 3.
                          • Or, regarde bien la ligne 112 du code : on appelle 'rk4' avec 0 comme dernier paramètre : la fonction ne retourne donc rien.

                          Voila ! il suffit donc d'appeler 'rk4' avec comme dernier paramètre respectif 1, 2, et 3; plutot que 0, 1 et 2 (ligne 112 à 114).

                          En espérant t'avoir aidé ! ;)

                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 mars 2018 à 18:20:28

                            Vous m'avez beaucoup aidé et je vous remercie, c'est une grave erreur de ma part en effet.
                            Merci bien.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 mars 2018 à 18:42:27

                              Grave non, par contre ne pas savoir debug est un gros handicap.

                              Faut vraiment avoir le réflexe de coller des print partout quand on comprend pas ce qui se passe. Quand je dis partout, c'est : quand une variable est modifiée, pour inspecter sa valeur, et quand il y a des boucles et des branchements conditionnels (des if/else) pour voir quels branches sont prises.

                              Avec ce genre de réflexe tu aurais pu comprendre le problème en moins d'une heure en étant large.

                              Après le print est un outil de debug assez basique, on peut aussi utiliser un fichier de log et un debugguer, mais si tu maîtrise pas le debug au print, pas la peine de chercher ailleurs dans un premier temps.

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Blond, bouclé, toujours le sourire aux lèvres...

                                21 mars 2018 à 8:41:03

                                Bonjour LoupSolitaire,
                                Merci en tout cas, c'est une leçon que je viens d'apprendre.

                                • Partager sur Facebook
                                • Partager sur Twitter

                                unsupported operand type

                                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                • Editeur
                                • Markdown