Partage
  • Partager sur Facebook
  • Partager sur Twitter

Raccourcir le code d'une fonction

    26 octobre 2016 à 19:36:42

    Bonsoir !

    Je suis en train d'apprendre Python (cours officiel : CH1,"Pas à pas vers la modularité") et pour m’entraîner au module, je réalise une fonction qui me calcul l'argent dans ma tirelire au centime prêt. Voilà le code : 

    #!/usr/bin/python3.5
    # -*-coding:UTF-8*-
    
    def total(b50=0, b20=0, b10=0, b5=0, p2=0, p1=0, c50=0, c20=0, c10=0, c5=0, c1=0):
    	b50 = float(b50)
    	b20 = float(b20)
    	b10 = float(b10)
    	b5 = float(b5)
    	p2 = float(p2)
    	p1 = float(p1)
    	c50 = float(c50)
    	c20 = float(c20)
    	c10 = float(c10)
    	c5 = float(c5)
    	c1 = float(c1)
    	return 50*b50 + 20*b20 + 10*b10 + 5*b5 + 2*p2 + p1 + 0.5*c50 + 0.2*c20 + 0.1*c10 + 0.05*c5 + 0.01*c1

    b = Billet, p= Pièce, c= centime.

    Vu la longueur, je me dit qu'il y à sans doute un moyen de raccourcir tout ça, non ?

    Merci par avance,

    Simon

    • Partager sur Facebook
    • Partager sur Twitter
      26 octobre 2016 à 19:43:38

      Ta fonction pourrait recevoir un nombre arbitraire d'arguments nommés (**kwargs), et tu utiliserais un dictionnaire de correspondances pour savoir combien vaut chaque pièce/billet en euros.

      -
      Edité par entwanne 26 octobre 2016 à 19:43:49

      • Partager sur Facebook
      • Partager sur Twitter
        26 octobre 2016 à 20:42:46

        entwanne a écrit:

        Ta fonction pourrait recevoir un nombre arbitraire d'arguments nommés (**kwargs), et tu utiliserais un dictionnaire de correspondances pour savoir combien vaut chaque pièce/billet en euros.

        -
        Edité par entwanne il y a environ 1 heure


        Merci pour votre réponse. Je verrai ça dans les prochains chapitres, je suppose  ?
        • Partager sur Facebook
        • Partager sur Twitter
          26 octobre 2016 à 21:44:17

          On peut le faire de plusieurs façons, mais si tu n'es encore qu'à des choses simples tu peux juste passer en argument une liste contenant les 15 valeurs:

          def total(lst_monnaie):
              VALEURS = (500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01)
              somme = 0
              for valeur, nb in zip(VALEURS, lst_monnaie):
                  somme += nb*valeur
              return somme


          À l'usage ça donne:

          print(total([0, 0, 1, 1, 1, 2, 3, 0, 0, 4, 2, 4, 0, 2, 7]))
          
          #Par contre même si tu n'as qu'un seul billet, il faudra mettre les 15 valeurs
          print(total([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
          
          #Ou au moins celles qui se trouvent avant (grâce au fonctionnement de zip)
          print(total([0, 0, 0, 0, 0, 1]))
          • Partager sur Facebook
          • Partager sur Twitter
          Précepte: Le mieux est l'ennemi du bien
            26 octobre 2016 à 21:46:31

            Oui c'est ça l'apprentissage ^^

            Dans le genre version courte je peux proposer :

            from collections import Counter
            
            def tirelire(*args, monnaie=[500,200,100,50,20,10,5,2,1,.5,.2,.1,.05,.02,.01]):
              assert all(x in monnaie for x in args), \
                     "Monnaie invalide {param}".format(param=[x for x in args if x not in monnaie])
              dict=Counter(args)
              return round( sum(key*dict[key] for key in dict.keys()) , 2 )
            

            ligne 1 : j'importe la classe Counter du module collections. C'est un dictionnaire «qui compte»
            ligne 3 : *args c'est la liste des paramètres non nommés, le paramètre nommé monnaie est la liste des monnaies valides (de la grosse coupure de 500€ à la pièce de 1 centime).
            lignes 4/5 je vérifie que tous les paramètres passés à la fonction font bien partie des monnaies valides et si ce n'est pas le cas  on s'interrompt avec un message d'erreur
            ligne 6 : je crée le dictionnaire qui compte les occurrences de chaque paramètre non nommé. Par exemple avec les paramètres 10,10,5,20,5,0.1,5 on obtient {10:2, 5:3, 0.1:1} car on a 2 fois 10, 3 fois 5 et une seule fois 0.1.
            ligne 7 : je fais le calcul, d'abord on multiplie chaque clé du dictionnaire avec le compte, puis on additionne le tout. Comme le résultat sera un flottant pour éviter quelques glitches à l'affichage on limite le nombre de décimales à 2 

            Edit: code modifié suite à la judicieuse remarque d'Olygrim.

            -
            Edité par PicoDev 26 octobre 2016 à 22:01:22

            • Partager sur Facebook
            • Partager sur Twitter
            First solve the problem. Then, write the code. ~ John Johnson
              26 octobre 2016 à 21:54:59

              @Pico: args est un tuple, donc tu peux t'en servir directement (pas besoin de passer par [*args];)

              • Partager sur Facebook
              • Partager sur Twitter
              Précepte: Le mieux est l'ennemi du bien
                26 octobre 2016 à 22:00:30

                Olygrim a écrit:

                @Pico: args est un tuple, donc tu peux t'en servir directement (pas besoin de passer par [*args];)

                C'est aussi pour ça que ce forum est top ! on arrête pas d'apprendre et à force ça finit/finira par rentrer :)

                Je modifie mon message, merci :)

                • Partager sur Facebook
                • Partager sur Twitter
                First solve the problem. Then, write the code. ~ John Johnson
                  26 octobre 2016 à 23:00:07

                  def total(**kwargs):
                  	convert =  {'b50':50,'b20':20,'b10':10,'b5':5,
                  		'p2':2,'p1':1,
                  		'c50':0.5,'c20':0.2,'c10':0.1,'c5':0.2,'c2':0.02,'c1':0.1}
                  	return sum(convert[a]*b for a,b in kwargs.items())
                  
                  tirelire = total(b50=3,b20=1,p2=25)
                  print(tirelire)
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Python c'est bon, mangez-en. 

                    26 octobre 2016 à 23:14:09

                    Merci à tous ! 

                    Voila qui me donne matière à... travailler ? :D

                    Toute vos méthode on l'ai bien complexe pour le débutant que je suis :lol:. Aussi, je vais continué le cours et relire tous vos codes.

                    Encore merci à tous et ma tirelire vous remercie également ! ;)

                    Simon.

                    -
                    Edité par SimonPaulL 26 octobre 2016 à 23:16:58

                    • Partager sur Facebook
                    • Partager sur Twitter
                      26 octobre 2016 à 23:48:24

                      Perso j'utiliserais un dict dont les clés sont les valeurs des billets et pièces, tout simplement.
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Raccourcir le code d'une fonction

                      × 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