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
Était-ce utile?

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 et getWage, vous pouvez simplement utiliser while 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 dans getHours et getWage, dans le cas des données non numériques a été saisie.

  • au lieu de booleanDone==False, l'utilisation not 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top