Essayer de mettre en place des boucles imbriquées en utilisant un commutateur booléen
-
25-09-2019 - |
Question
Je suis en train de mettre en place une boucle de while
qui demandera à l'utilisateur pour le nom de l'employé, les heures travaillées et le salaire horaire jusqu'à ce que l'utilisateur entre « DONE ». Finalement, je vais modifier le code pour calculer la rémunération hebdomadaire et écrire à une liste, mais une chose à la fois. Le problème est une fois que la boucle principale de while
exécute une fois, il arrête juste. Ne pas l'erreur mais juste arrête. Je dois tuer le programme pour l'obtenir pour arrêter. Je veux poser les trois questions encore et encore jusqu'à ce que l'utilisateur soit terminé. Pensées?
S'il vous plaît noter que ceci est juste un exercice et non destiné à une application du monde réel.
def getName():
"""Asks for the employee's full name"""
firstName=raw_input("\nWhat is your first name? ")
lastName=raw_input("\nWhat is your last name? ")
fullName=firstName.title() + " " + lastName.title()
return fullName
def getHours():
"""Asks for the number of hours the employee worked"""
hoursWorked=0
while int(hoursWorked)<1 or int(hoursWorked) > 60:
hoursWorked=raw_input("\nHow many hours did the employee work: ")
if int(hoursWorked)<1 or int(hoursWorked) > 60:
print "Please enter an integer between 1 and 60."
else:
return hoursWorked
def getWage():
"""Asks for the employee's hourly wage"""
wage=0
while float(wage)<6.00 or float(wage)>20.00:
wage=raw_input("\nWhat is the employee's hourly wage: ")
if float(wage)<6.00 or float(wage)>20.00:
print ("Please enter an hourly wage between $6.00 and $20.00")
else:
return wage
##sentry variables
employeeName=""
employeeHours=0
employeeWage=0
booleanDone=False
#Enter employee info
print "Please enter payroll information for an employee or enter 'DONE' to quit."
while booleanDone==False:
while employeeName=="":
employeeName=getName()
if employeeName.lower()=="done":
booleanDone=True
break
print "The employee's name is", employeeName
while employeeHours==0:
employeeHours=getHours()
if employeeHours.lower()=="done":
booleanDone=True
break
print employeeName, "worked", employeeHours, "this week."
while employeeWage==0:
employeeWage=getWage()
if employeeWage.lower()=="done":
booleanDone=True
break
print employeeName + "'s hourly wage is $" + employeeWage
La solution
Le problème est que, après la première boucle, employeeName
et les autres variables auront déjà des valeurs, de sorte que votre intérieur en boucles seront sautées. Cela conduit à la boucle extérieure répétant à l'infini sans rien faire.
Je voudrais juste enlever la boucle while intérieure: vous n'avez pas vraiment besoin d'eux, parce que vous faites déjà validation à l'intérieur getHours
et les autres fonctions. Une autre option consiste à réinitialiser les valeurs de variables au début de l'extérieur tandis que la boucle.
Quelques plus de choses à améliorer (non liée à cette erreur):
-
Dans
getHours
etgetWage
, vous pouvez simplement utiliserwhile True
au lieu de la condition que vous avez maintenant. Si la condition est fausse, vous êtes revenu de la fonction déjà de toute façon. -
Vous devez attraper
ValueError
dansgetHours
etgetWage
, dans le cas des données non numériques a été saisie. -
au lieu de
booleanDone==False
, l'utilisationnot booleanDone
. Bien que si vous retirez les boucles internes comme je l'ai suggéré, vous ne même pas besoin de ce booléen: Il suffit de sortir de la boucle en cas de besoin .
Autres conseils
getHours
et getWage
supposent respectivement l'entrée est en format int
et float
. Ainsi, les contrôles pour ...lower()=="done"
ne peuvent jamais peut-être satisfaits: si l'utilisateur est entré done
à l'invite dans l'une de ces fonctions, le programme serait mort avec une exception ValueError
. Mais c'est un bug différent.
A la fin de la première étape de la boucle extérieure, nous savons que ni des trois chaînes est vide (les boucles internes garantissent). Ensuite, ces chaînes ne sont pas remis à zéro - ils sont donc toujours pas vide - donc sur chaque jambe avenir de la boucle extérieure aucune des boucles internes jamais exécuter. Cela devrait provoquer boucle infinie rapide vide par opposition à une sortie propre (il ne sait pas pourquoi les symptômes du bogue évident que je viens de décrire diffèrent de vos observations), donc il peut y avoir d'autres bogues encore - mais quand il y a deux facilement repérables bug killer dans ce petit un morceau de code, je pense qu'il est plus sage d'arrêter de creuser (ce qui est l'utilisation de repérer encore quelques -).
Vous devriez plutôt factoriser la structure, ce qui rend le rôle des fonctions extrêmement claires et précises: qu'est-ce que ces fonctions renvoient exactement? Si les chaînes, quelles sont les contraintes qui pèsent sur ces chaînes? Il semble qu'ils sont à peu près retour « une chaîne valide pour cette entrée » (sauf la possibilité de tuer tout le programme si l'utilisateur a une faute de frappe dans les salaires ou les heures, que vous pouvez éviter un try
/ except
) - la premier, et que l'on ne, pouvait revenir done
(mais il devrait le préciser dans son invite, et éviter la deuxième demande inutile si les utilisateurs dit done
à la première invite). Une fois que vous les document en tant que tel, il est clair que les boucles tout en interne ne sont pas fondées; la boucle extérieure pourrait juste être
while True:
employeeName=getName()
if employeeName.lower()=="done":
break
print "The employee's name is", employeeName
employeeHours=getHours()
print employeeName, "worked", employeeHours, "this week."
employeeWage=getWage()
print employeeName + "'s hourly wage is $" + employeeWage