Trying to set up nested while loops using a boolean switch
I'm trying to set up a while
loop that will ask the user for the employee name, hours worked and hourly wage until the user enters 'DONE'. Eventually I'll modify the code to calculate the weekly pay and write it to a list, but one thing at a time. The problem is once the main while
loop executes once, it just stops. Doesn't error out but just stops. I have to kill the program to get it to stop. I want it to ask the three questions again and again until the user is finished. Thoughts?
Please note that this is just an exercise and not meant for any real world application.
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 "P开发者_如何学Pythonlease 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
The problem is that after the first loop, employeeName
and the other variables will already have values, so your inner while loops will be skipped. This leads to the outer loop repeating infinitely without doing anything.
I would just remove the inner while loops: you don't really need them, because you already do validation inside getHours
and the other functions. Another option is to reset the variable values at the start of the outer while loop.
Some more things to improve (not related to this error):
In
getHours
andgetWage
, you can just usewhile True
instead of the condition you have now. If the condition is false, you would have returned from the function already anyway.You need to catch
ValueError
ingetHours
andgetWage
, in case non-numeric data was entered.instead of
booleanDone==False
, usenot booleanDone
. Though if you remove the inner loops as I suggested, you don't even need this boolean: Just break out of the loop when needed.
getHours
and getWage
assume the input is respectively in int
and float
format. So the checks for ...lower()=="done"
can never possibly be satisfied: if the user had entered done
at the prompt in either of these functions, the program would have died with a ValueError
exception. But that's a different bug.
At the end of the first leg of the outer loop, we know that neither of the three strings is empty (the inner loops guarantee that). Then, those strings aren't reset -- so they're still not empty -- so on every future leg of the outer loop none of the inner loops ever execute again. This should cause infinite fast empty looping as opposed to a clean exit (i.e. it's not clear why the symptoms of the obvious bug I just described differ from your observations), so there may be further bugs yet -- but when there are two easily spotted killer bug in this small a piece of code I think it's wiser to stop digging (what's the use of spotting another few?-).
You should rather refactor the structure, making the role of the functions extremely clear and precise: what do those functions return, exactly? If strings, what are the constraints on those strings? It seems they're roughly returning "a valid string for this entry" (except for the possibility of killing all the program if the user has a typo in the wages or hours, which you could avoid with a try
/except
) -- the first one, and that one only, could return done
(but then it should make this clear in its prompting, and avoid the second useless prompt if the users says done
to the first prompt). Once you document them as such it becomes clear that the inner while loops are unwarranted; the outer loop could just be
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
精彩评论