views:

191

answers:

2

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 "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
+3  A: 

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 and getWage, you can just use while 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 in getHours and getWage, in case non-numeric data was entered.

  • instead of booleanDone==False, use not 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.

interjay
+1  A: 

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
Alex Martelli