1

whileユーザーが「DONE」と入力するまで、従業員名、労働時間、時給をユーザーに尋ねるループを設定しようとしています。最終的には、コードを変更して週給を計算し、リストに書き込みますが、一度に1つずつ行います。問題は、メインwhileループが一度実行されると、停止するだけです。エラーは発生しませんが、停止します。プログラムを停止させるには、プログラムを強制終了する必要があります。ユーザーが終了するまで、3つの質問を何度も繰り返してほしい。考え?

これは単なる演習であり、実際のアプリケーションを対象としたものではないことに注意してください。

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
4

2 に答える 2

3

問題は、最初のループの後、employeeName他の変数にはすでに値があるため、内側のwhileループがスキップされることです。これにより、外側のループが何もせずに無限に繰り返されます。

getHours内部のwhileループを削除するだけです。内部および他の関数の検証はすでに行っているため、実際には必要ありません。もう1つのオプションは、外側のwhileループの開始時に変数値をリセットすることです。

改善すべきいくつかの事項(このエラーとは関係ありません):

  • getHoursとでは、現在の状態の代わりにgetWage使用できます。while True条件がfalseの場合、とにかく関数から戻っているはずです。

  • 数値以外のデータが入力された場合ValueErrorは、getHoursとをキャッチする必要があります。getWage

  • の代わりにbooleanDone==False、を使用しますnot booleanDone。私が提案したように内側のループを削除した場合でも、このブール値は必要ありません。必要に応じてループから抜け出すだけです。

于 2010-04-07T18:07:37.250 に答える
1

getHours入力がそれぞれと形式であるとgetWage想定します。したがって、のチェックが満たされる可能性はありません。ユーザーがこれらの関数のいずれかでプロンプトを入力した場合、プログラムは例外を除いて終了します。しかし、それは別のバグです。intfloat...lower()=="done"doneValueError

外側のループの最初のレッグの終わりで、3つの文字列のどちらも空ではないことがわかります(内側のループはそれを保証します)。次に、これらの文字列はリセットされないため、まだ空ではありません。したがって、外側のループの将来のすべての区間で、内側のループが再び実行されることはありません。これにより、クリーンな出口とは対照的に、無限に高速な空のループが発生するはずです(つまり、今説明した明らかなバグの症状が観察結果と異なる理由は明らかではありません)。この小さなコードのキラーバグ私は掘るのをやめる方が賢明だと思います(別のいくつかを見つけることの使用は何ですか?-)。

むしろ構造をリファクタリングして、関数の役割を非常に明確かつ正確にする必要があります。これらの関数は正確に何を返しますか?文字列の場合、それらの文字列に対する制約は何ですか?彼らは大まかに「このエントリの有効な文字列」を返しているようです(ユーザーが賃金または時間にタイプミスをした場合にすべてのプログラムを強制終了する可能性を除いて、try/で回避できますexcept)-最初のもの、およびその1つだけが戻る可能性がありdoneます(ただし、プロンプトでこれを明確にし、ユーザーが最初のプロンプトに言った場合は2番目の役に立たないプロンプトを回避する必要があり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
于 2010-04-07T18:14:02.600 に答える