Problème de boucle python

Résolu
Totoladilu -  
 Totoladilu -
Bonjour,

J'essaye de faire un programme qui indique le nombre de pièces et billets à rendre pour la monnaie quand on rentre un prix. Mon programme ne fonctionne pas, car j'ai l'impression que je fais un tour en trop dans les boucles, et donc je sors de ma liste. Je ne sais pas où est ce qu'est le problème.

billet = (20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01)
billett = [20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
SD = float(input("Prix : "))
SP = float(input("Somme donnée : "))
x = SP - SD
if x >= 0 :
    list = []
    z = 0
    while x >= 0.01 :
            a = x // billet[z]
            x = x % billet[z]
            z = z + 1
            list.append(a)
    else:
        i = 0
        o = len(list)
        while i <= o:
                if list[i] == 0:
                    del list[i]
                    del billett[i]
                    o = len(list)
                else:
                    i = i + 1
        i = 0
        while i <= len(list):
            if billett[i] > 2:
                print("Rendre ", list[i], " billet(s) de ", billett[i])
            else:
                print("Rendre ", list[i], " pièce(s) de ", billett[i])
            i = i + 1

2 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    Il y a beaucoup de choses étranges dans ton programme :
    • les variables
      o
      et
      z
      semblent inutiles ;
    • tu peux souvent utiliser des boucles
      for
      (plutôt que des
      while
      )


    Principe de l'algorithme

    La manière la plus simple d'aborder le problème consiste à trier les valeurs des billets / pièces par ordre décroissant. Puis, étant donnée une quantité de monnaie à rendre
    x
    , on cherche la plus grande valeur inférieur à et on fait la division euclidienne. Celle-ci révèle le nombre de billets / pièces de cette valeur à rendre que l'on mémorise dans une liste ou un dictionnaire, et qui permet de corriger la quantité de monnaie qu'il reste à rendre. Puis on passe à la valeur suivante. Ci-dessous, je vais choisir une liste (on doit rendre
    amounts[i]
    pièce(s)/billet(s) de valeur
    values[i]
    )

    Une fois cette décomposition faite (voir fonction
    x
    decompose</code>), on passe à l'affichage proprement dit. Il faut, en fonction de la valeur indiquer s'il s'agit d'un billet ou d'une pièce (voir fonction
    label
    ), et en fonction de la quantité appliquer ou non un pluriel (voir fonction
    plural
    ).

    Code

    Plutôt que demander les valeurs à l'utilisateur, ici je modifie légèrement le programme pour se placer dans le cas où l'on veut rendre :
    • 437€ (test 1)
    • 917.58€ (test 2)


    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    def label(value):
        return "billet" if value >= 5 else "pièce"
    
    def plural(amount):
        return "s" if amount >= 2 else ""
    
    def decompose(x, values):
        amounts = list()
        for i in range(len(values)):
            y = values[i]
            if values[i] <= x:
                amounts.append(x // y)
                x %= y
            else:
                amounts.append(0)
            print(f"  --> {amounts[-1]} * {y}€ --> reste {x}€")
            if x == 0:
                break
        return amounts
    
    values = [
        500, 200, 100,
        50, 20, 10,
        5, 2, 1,
        0.5, 0.2, 0.1,
        0.05, 0.02, 0.01
    ]
    
    # Supposons que l'on veuille rendre 437€ (test 1) et 917.58 (test 2)
    for x in [437, 917.58]:
        print("=" * 80)
        amounts = decompose(x * 100, [int(value * 100) for value in values])
    
        print(f"Il faut rendre {x}€:\n" + "\n".join([
            f"  {amount} {label(value)}{plural(amount)} de {value}€"
            for (amount, value) in zip(amounts, values)
            if amount > 0
        ]))


    Exécution

    ================================================================================
    --> 0 * 50000€ --> reste 43700€
    --> 2 * 20000€ --> reste 3700€
    --> 0 * 10000€ --> reste 3700€
    --> 0 * 5000€ --> reste 3700€
    --> 1 * 2000€ --> reste 1700€
    --> 1 * 1000€ --> reste 700€
    --> 1 * 500€ --> reste 200€
    --> 1 * 200€ --> reste 0€
    Il faut rendre 437€:
    2 billets de 200€
    1 billet de 20€
    1 billet de 10€
    1 billet de 5€
    1 pièce de 2€
    ================================================================================
    --> 1.0 * 50000€ --> reste 41758.0€
    --> 2.0 * 20000€ --> reste 1758.0€
    --> 0 * 10000€ --> reste 1758.0€
    --> 0 * 5000€ --> reste 1758.0€
    --> 0 * 2000€ --> reste 1758.0€
    --> 1.0 * 1000€ --> reste 758.0€
    --> 1.0 * 500€ --> reste 258.0€
    --> 1.0 * 200€ --> reste 58.0€
    --> 0 * 100€ --> reste 58.0€
    --> 1.0 * 50€ --> reste 8.0€
    --> 0 * 20€ --> reste 8.0€
    --> 0 * 10€ --> reste 8.0€
    --> 1.0 * 5€ --> reste 3.0€
    --> 1.0 * 2€ --> reste 1.0€
    --> 1.0 * 1€ --> reste 0.0€
    Il faut rendre 917.58€:
    1.0 billet de 500€
    2.0 billets de 200€
    1.0 billet de 10€
    1.0 billet de 5€
    1.0 pièce de 2€
    1.0 pièce de 0.5€
    1.0 pièce de 0.05€
    1.0 pièce de 0.02€
    1.0 pièce de 0.01€


    Bonne chance
    0
    1. Totoladilu
       
      Ok merci beaucoup pour votre aide
      0