尝试使用布尔开关设置嵌套的while循环
我正在尝试设置一个 while
循环,这个循环会不断询问用户员工的名字、工作小时数和每小时工资,直到用户输入 'DONE' 为止。最终我会修改代码来计算每周的工资,并把结果写入一个列表,但我想一步一步来。问题是,一旦主 while
循环执行了一次,它就停止了。并没有报错,但就是不动了。我必须强制结束程序才能让它停止。我希望它能不断地问这三个问题,直到用户说结束。你有什么想法吗?
请注意,这只是一个练习,并不用于任何实际应用。
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
2 个回答
getHours
和 getWage
这两个函数假设输入的格式分别是 int
(整数)和 float
(浮点数)。所以,检查 ...lower()=="done"
这个条件永远不会成立:如果用户在这两个函数的提示中输入了 done
,程序就会因为出现 ValueError
错误而崩溃。不过,这算是另一个问题。
在外层循环的第一轮结束时,我们知道这三个字符串都不是空的(内层循环保证了这一点)。然后,这些字符串不会被重置——所以它们仍然不是空的——因此在外层循环的每一轮中,内层循环都不会再执行。这应该会导致程序一直快速循环而不退出,而不是干净利落地结束(也就是说,明显的错误症状和你观察到的情况不太一样),所以可能还有其他错误存在。不过在这么小的代码中出现两个明显的致命错误,我觉得不如先停止深入查找(再找出几个又有什么用呢?)。
你应该重新整理一下结构,让函数的作用非常清晰和明确:这些函数到底返回什么?如果返回的是字符串,那这些字符串有什么限制?看起来它们大致上是返回“这个输入的有效字符串”(除了用户在输入工资或小时数时可能出现的拼写错误,这会导致程序崩溃,你可以用 try
/except
来避免)——第一个函数,只有它,可能会返回 done
(但它应该在提示中明确这一点,并且如果用户在第一个提示中说 done
,就避免第二个无用的提示)。一旦你把它们记录清楚,就会发现内层的 while 循环是多余的;外层循环可以直接是
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
问题是,在第一次循环之后,employeeName
和其他变量已经有了值,所以你里面的 while 循环会被跳过。这导致外面的循环无限重复,但什么也不做。
我建议你去掉里面的 while 循环:其实你不需要它们,因为你在 getHours
和其他函数里已经做了验证。另一个选择是在外面 while 循环开始时重置变量的值。
还有一些可以改进的地方(和这个错误无关):
在
getHours
和getWage
中,你可以直接用while True
,而不是现在的条件。如果条件为假,你其实已经从函数里返回了。你需要在
getHours
和getWage
中捕获ValueError
,以防输入了非数字的数据。用
not booleanDone
替代booleanDone==False
。不过如果你按照我建议的去掉内层循环,你甚至不需要这个布尔值:只需在需要的时候跳出循环就行。