Partage
  • Partager sur Facebook
  • Partager sur Twitter

Python - Problème algo glouton, rendu de monnaie

Sujet résolu
    11 mai 2021 à 16:51:38

    Bonjour,

    J'ai un problème avec mon code, ça me renvoi << AttributeError: 'NoneType' object has no attribute 'append' >>, ça viens de la ligne 7. J'ai l'impression que "solution", qui est une liste, change de type mais je ne vois pas pourquoi.

    Merci d'avance pour votre aide

    pieces = [100,50,20,10,5,2,1]
    def rendu_glouton(arendre, solution=[], i=0):
        if arendre == 0:
            return solution
        p = pieces[i]
        if p <= arendre:
            return rendu_glouton(arendre-p, solution.append(p), i)
        else :
            return rendu_glouton(arendre, solution, i+1)
    



    • Partager sur Facebook
    • Partager sur Twitter
      11 mai 2021 à 17:37:02

      Pumch a écrit:

      Bonjour,

      J'ai un problème avec mon code, ça me renvoi << AttributeError: 'NoneType' object has no attribute 'append' >>, ça viens de la ligne 7. J'ai l'impression que "solution", qui est une liste, change de type mais je ne vois pas pourquoi.

      Merci d'avance pour votre aide

      pieces = [100,50,20,10,5,2,1]
      def rendu_glouton(arendre, solution=[], i=0):
          if arendre == 0:
              return solution
          p = pieces[i]
          if p <= arendre:
              return rendu_glouton(arendre-p, solution.append(p), i)
          else :
              return rendu_glouton(arendre, solution, i+1)
      



      sans doute parce que solution.append(p) vaut None. Et c'est une mauvaise idée que de donner un mutable comme valeur par défaut à un paramètre.

      • Partager sur Facebook
      • Partager sur Twitter
        11 mai 2021 à 17:50:10

        pour le dire d'une autre façon, solution.append(p) ne renvoie pas une liste, ça renvoie None; hors toi, tu veux passer la liste solution, donc faire le append avant le return
        • Partager sur Facebook
        • Partager sur Twitter
          11 mai 2021 à 18:01:58

          umfred a écrit:

          donc faire le append avant le return

          Oui, en effet. Ou alors changer en solution+[p].

          • Partager sur Facebook
          • Partager sur Twitter
            11 mai 2021 à 19:17:31

            Merci pour vos réponses, en fait le code vient d'un sujet que j'ai eu à faire ce matin dans lequel il manque des morceaux de code qu'il faut compléter.

            J'aurais bien aimé mettre solution+[p] mais ce n'est pas possible:( et j'essaie de trouver la solution mais je ne trouve pas.

            def rendu_glouton(arendre, solution=[], i=0):
                if arendre == 0:
                    return ...
                p = pieces[i]
                if p <= ...:
                    return rendu_glouton(arendre-p, solution.append(...), i)
                else :
                    return rendu_glouton(arendre, solution, ...)



            • Partager sur Facebook
            • Partager sur Twitter
              11 mai 2021 à 19:28:26

              return rendu_glouton(arendre-p, solution.append(...), i)
              c'est ce qu'on te demande de compléter? Changes de cours.
              solution.append(...) vaut None
              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                11 mai 2021 à 21:15:08

                PierrotLeFou a écrit:

                return rendu_glouton(arendre-p, solution.append(...), i)
                c'est ce qu'on te demande de compléter? Changes de cours.
                solution.append(...) vaut None


                Donc ce n'est pas possible de le résoudre. En plus de ça, l'exercice est tiré d'un sujet de bac qui devait tomber cette année...
                • Partager sur Facebook
                • Partager sur Twitter
                  11 mai 2021 à 21:35:01

                  Pumch a écrit:

                  pieces = [100,50,20,10,5,2,1]
                  def rendu_glouton(arendre, solution=[], i=0):
                      if arendre == 0:
                          return solution
                      p = pieces[i]
                      if p <= arendre:
                          return rendu_glouton(arendre-p, solution.append(p), i)
                      else :
                          return rendu_glouton(arendre, solution, i+1)
                  




                  Ce code est juste ... 8 fois quand a_rendre vaut 0, 1, 2, 5, 10, 20, 50 ou 100.

                  -
                  Edité par PascalOrtiz 11 mai 2021 à 22:14:28

                  • Partager sur Facebook
                  • Partager sur Twitter
                    12 mai 2021 à 12:10:35

                    Rien n'empêche d'indiquer que le code est faux et va générer une erreur sauf dans les cas décrits par PascalOrtiz et de proposer la version qui fonctionne dans tous les cas.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 mai 2021 à 14:06:07

                      umfred a écrit:

                      Rien n'empêche d'indiquer que le code est faux et va générer une erreur sauf dans les cas décrits par PascalOrtiz et de proposer la version qui fonctionne dans tous les cas.

                      Il y a aussi le problème de l'argument par défaut qui entraîne le problème bien connu suivant :

                      pieces = [100,50,20,10,5,2,1]
                      def rendu_glouton(arendre, solution=[], i=0):
                          if arendre == 0:
                              return solution
                          p = pieces[i]
                          if p <= arendre:
                              solution.append(p)
                              return rendu_glouton(arendre-p, solution, i)
                          else :
                              return rendu_glouton(arendre, solution, i+1) 
                      
                      solution=[]
                      
                      rendu_glouton(42, solution)
                      
                      rendu_glouton(142, solution)
                      print(solution)
                      [20, 20, 2, 100, 20, 20, 2]

                      donc la réponse est fausse. Et en fait ce paramètre par défaut ne sert à rien car si  on ne l'écrit pas on ne peut pas accéder aux solutions. Donc on pourrait écrire

                      def rendu_glouton(arendre, solution, i=0):
                          if arendre == 0:
                              return solution
                          p = pieces[i]
                          if p <= arendre:
                              solution.append(p)
                              return rendu_glouton(arendre-p, solution, i)
                          else :
                              return rendu_glouton(arendre, solution, i+1) 
                      
                      solution=[]
                      rendu_glouton(42, solution)
                      
                      solution=[]
                      rendu_glouton(142, solution)
                      print(solution)
                      

                      mais qui n'est pas terrible non plus car on est obligé à chaque fois de poser solution = [].

                      Une meilleure solution serait que la fonction se charge de créer les solutions :

                      pieces = [100,50,20,10,5,2,1]
                      def rendu_glouton(arendre, i):
                          if arendre == 0:
                              return []
                          p = pieces[i]
                          if p <= arendre:
                              return [p]+rendu_glouton(arendre-p, i)
                          else :
                              return rendu_glouton(arendre, i+1) 
                      
                      print(all(arendre== sum(rendu_glouton(arendre,0)) for arendre in range(110)))







                      • Partager sur Facebook
                      • Partager sur Twitter

                      Python - Problème algo glouton, rendu de monnaie

                      × 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