Problème "list index out of range" [Résolu]

Signaler
-
 FostRunt -
Bonjour,
Je débute en programmation Python, mais dans le cadre de mon travail, il m'est demandé de programmer un algorithme glouton, permettant d'afficher la monnaie à rendre pour les clients.
Le problème étant que mon algorithme ne prend pas en compte les centimes, et lorsque l'une des valeurs d'entrée comporte des centimes, l'erreur suivant est affiché " line 11, in rendre_monnaie
if retour_monnaie<valeurs[i]:
IndexError: list index out of range"

Si quelqu'un pourrait m'aider, je ne comprend pas d'où vient le problème...
Je code en python 3, et grace au logiciel Pyzo.
Merci d'avance !

valeurs=[0.01,0.02,0.05,0.1,0.2,1,2,5,10,20,50]
valeurs.reverse()

def rendre_monnaie(cout,somme_client,valeurs):
    nombre_billets=[]
    retour_monnaie=somme_client-cout
    i=0
    while retour_monnaie>0:
        if retour_monnaie<valeurs[i]:
            i=i+1
        else :
            retour_monnaie=retour_monnaie-valeurs[i]
            nombre_billets.append(valeurs[i])


    return nombre_billets



Configuration: Macintosh / Chrome 86.0.4240.111

9 réponses

Messages postés
15149
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
27 novembre 2020
618
Messages postés
15149
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
27 novembre 2020
618
Bonjour,

tout d'abord, voici un tuto pour bien utiliser les balises de code https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code pour tes prochains posts.
Tu verras, ce sera mieux que ce pavé gris tout moche.


Apprendre à coder ne peut pas se faire sans apprendre à débugger.
Une très bonne méthode pour débugger est de faire en sorte de savoir ce qui se passe au fur et à mesure de l'exécution.
Je ne connais pas d'éditeurs Python permettant d'exécuter en pas à pas et d'espionner les variables (c'est bien dommage), la solution consiste donc à écrire pleins de trucs dans la console.

Essaye ceci
def rendre_monnaie(cout,somme_client,valeurs):
    nombre_billets=[]
    retour_monnaie=somme_client-cout
    i=0
    while retour_monnaie>0:
        if retour_monnaie<valeurs[i]:
            print("i : ", i)
            i=i+1
        else :
            print("Retour monnaie : ", retour_monnaie)
            print("valeur : ", valeurs[i])
            retour_monnaie=retour_monnaie-valeurs[i]
            print("reste : ", retour_monnaie)
            nombre_billets.append(valeurs[i])
            


    return nombre_billets

valeurs=[0.01,0.02,0.05,0.1,0.2,1,2,5,10,20,50]
valeurs.reverse()    
rendre_monnaie(12.32, 13,valeurs)


Et décris moi ce qui se passe
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Messages postés
4761
Date d'inscription
dimanche 12 juin 2011
Statut
Contributeur
Dernière intervention
23 octobre 2020
1 140
Je ne connais pas d'éditeurs Python permettant d'exécuter en pas à pas et d'espionner les variables (c'est bien dommage)

PyCharm, VSCode avec l'extension Python, Eclipse PyDev, même IDLE sait le faire... et à défaut,
pdb
.
Re-Bonjour,
Merci beaucoup pour votre réponse rapide. Etant nouveau sur le forum, je tacherai d'ajouter de la couleur plus tard, c'est plus agréable effectivement :)

J'ai donc testé ce que vous m'avez proposé, et voici le résultat:

i :  0
i :  1
i :  2
i :  3
i :  4
i :  5
Retour monnaie :  0.6799999999999997
valeur :  0.2
reste :  0.4799999999999997
Retour monnaie :  0.4799999999999997
valeur :  0.2
reste :  0.2799999999999997
Retour monnaie :  0.2799999999999997
valeur :  0.2
reste :  0.07999999999999968
i :  6
i :  7
Retour monnaie :  0.07999999999999968
valeur :  0.05
reste :  0.02999999999999968
i :  8
Retour monnaie :  0.02999999999999968
valeur :  0.02
reste :  0.00999999999999968
i :  9
i :  10
Traceback (most recent call last):
line 22, in <module>
    rendre_monnaie(12.32, 13,valeurs)
line 6, in rendre_monnaie
    if retour_monnaie<valeurs[i]:
IndexError: list index out of range


Encore une fois, la même erreur...
Autre problème que je constate (avec d'autre valeurs prise) est que python me donne un résultat comme 0.09999999999... lorsque que le programme fait la soustraction de 0.3-0.2.
Quelque étapes plus tard, j'arrive au résultat suivant : 0.009999999...
Or, il est compliqué de rendre la monnaie sur cette valeur, d'où peut-être l'erreur "out of range"
Messages postés
15149
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
27 novembre 2020
618
Oui c'est bien là le noeud du problème.
0.009999 est plus petit que 0.1 donc ça passe dans

        if retour_monnaie<valeurs[i]:
            print("i : ", i)
            i=i+1

avec i = 10, qui devient 11.
A la boucle suivante, cette ligne
f retour_monnaie<valeurs[i]:
tente d'accéder à valeurs[11] qui n'existe pas.

Je t'invite à lire ceci
https://forums.commentcamarche.net/forum/affich-35846831-erreur-de-calcul#3

Commence par mon message, puis ceuix de DalFab et Reivax
Messages postés
13329
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
27 novembre 2020
748
bonjour,
le plus simple, c'est de travailler avec des centimes, plutôt que des euros.
Bonjour,
Merci pour votre réponse Whismeril, j'ai pu comprendre d'où venait le problème.
Cependant, je ne vois pas comment le corriger dans le cas présent... Existe-t-il une fonction qui permette de corriger cela ? Ou n'importe ?

yg_be: c'est vrai que c'est une idée à laquelle je n'avais pas pensé, cependant, il m'est demandé en sortie de programme, d'afficher la valeur des billets à rendre ainsi que celle des pièces à rendre. Travailler en centimes rendrait la tache plus compliquée non ?
Messages postés
13329
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
27 novembre 2020
748
peut-être un peu plus de travail, sûrement moins complexe.
Messages postés
15149
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
27 novembre 2020
618
travailler en centimes rendrait la tache plus compliquée non
oui et non.

Ça réglerait le problème de la virgule flottante donc de ce point de de vue c'est plus simple.
Reconvertir des centimes en euros à l'affichage n'est pas bien compliqué.

Une autre solution est d'arrondir les calculs, mais attention ça peut parfois mener à un résultat incorrect.
Re-Bonjour,
Après réflexion c'est vrai que travailler en centimes peut-être une solution.

J'aimerai quand même essayer dans un premier temps de faire cela en Euro.
Mais je n'ai aucune idée idée de comment arrondir les résultats sur Python (je débute vraiment)
Pourriez-vous me montrer la marche a suivre ?

Merci
C'est tout bon !
J'ai réussis en prenant des arrondis sur les valeurs. Après plusieurs tests cela ne mène à aucune erreur.
Merci beaucoup pour vos conseils !
J'ai appris pas mal de choses