2016-11-02 6 views
-1

私は与えられたリストの数字の合計に基づいて決定を下すためにこのプログラムを構築しています。私はまた、必要なロジックceratinテスト与えられた関数で数値を合計すると、それは正しい答えを与えるが、値をテストするステートメントが正常に動作しない場合、またはif文間違って実行します:float sum(list)ValueError

import random 
from decimal import Decimal 
from decimal import getcontext 


def language_equate(sentence_parsing): 
    both = ["and", ",", "then", "next"] 
    ignore = ["don't", "not"] 
    travel = ["move", "go", "travel"] 
    dial = ["rotate", "turn", "spin", "twist"] 
    lever_positive = ["push", "back"] 
    lever_negative = ["pull", "forward"] 
    north = ["north", "up", "forward"] 
    east = ["east", "right"] 
    west = ["west", "left"] 
    south = ["south", "down", "backward"] 
    modded_sentence = [] 
    getcontext().prec = 20 
    for i, word in enumerate(sentence_parsing): 
     if word.lower() in both: 
      modded_sentence.append(Decimal(99)) 
     elif word.lower() in ignore: 
      modded_sentence.append(Decimal(-20)) 
     elif word.lower() in travel: 
      modded_sentence.append(Decimal(1)) 
     elif word.lower() in dial: 
      modded_sentence.append(Decimal(1/3)) 
     elif word.lower() in lever_positive: 
      modded_sentence.append(Decimal(1/5)) 
     elif word.lower() in lever_negative: 
      modded_sentence.append(Decimal(1/7)) 
     elif word.lower() in north: 
      modded_sentence.append(Decimal(1/11)) 
     elif word.lower() in east: 
      modded_sentence.append(Decimal(1/13)) 
     elif word.lower() in west: 
      modded_sentence.append(Decimal(1/17)) 
     elif word.lower() in south: 
      modded_sentence.append(Decimal(1/19)) 
    return modded_sentence 


def language_evaluate(sentence_parsing): 
    modded_sentence = language_equate(sentence_parsing) 
    a = sum(modded_sentence) 
    return a 


def entrance(dial, lever, win, current_room, EPSILON): 
    print("You are in the entrance.") 
    print("Go north to try the closed door") 
    print("Go east to the kitchen") 
    print("Go west to the pantry") 
    print("Go south to exit") 
    print("What would you like to do?") 
    sentence_parsing = input().split(" ") 
    go = language_evaluate(sentence_parsing) 
    # Exclusive Disjunction Answer Bank 
    answer_bank = ["Y", "y", "Yes", "yes", "YES"] 
    if abs(go - Decimal(1/11)) <= EPSILON or abs(go - Decimal(12/11)) <= EPSILON: # separate statements 
     if dial == "red" and lever == "backward": 
      win = True 
      current_room = "" 
     else: 
      print("Sorry the door remains locked") 
    elif abs(go - Decimal(1/13)) <= EPSILON or abs(go - Decimal(14/13)) <= EPSILON: 
     current_room = "kitchen" 
    elif Decimal(1/17) or Decimal(18/17): 
     current_room = "pantry" 
    elif abs(go - Decimal(1/19)) <= EPSILON or (go - Decimal(20/19)) <= EPSILON: 
     print("Are You sure you want to quit? [Y/N]") 
     give_up = input() 
     if give_up in answer_bank: 
      print("Ok, maybe next time") 
      raise SystemExit 
    else: 
     print("Sorry I don't understand that") 
    return win, current_room 


def kitchen(lever, lever_position, current_room, EPSILON): 
    print("You are in the kitchen.") 
    print("Go north to move the lever the %s position" % lever) 
    print("Go west to the entrance") 
    print("What would you like to do?") 
    sentence_parsing = input().split(" ") 
    go = language_evaluate(sentence_parsing) 
    print(go) 
    if abs(go - 16/55) <= EPSILON or abs(go - 71/55) <= EPSILON or abs(go - 1/5) <= EPSILON: 
     lever = lever_position[1] 
    elif abs(go - 18/77) <= EPSILON or abs(go - 95/77) <= EPSILON or abs(go - 1/7) <= EPSILON: 
     lever = lever_position[0] 
    elif abs(go - 1/17) <= EPSILON or abs(18/17) <= EPSILON: 
     print("test works") 
     current_room = "entrance" 
    else: 
     print("Sorry I don't understand that") 
    return lever, current_room 


def pantry(dial, current_room, EPSILON): 
    print("You are in the pantry.") 
    print("South of you is a three coloured dial, with the color %s glowing" % dial) 
    print("Go east to the entrance") 
    print("Go south to turn the dial") 
    print("What would you like to do?") 
    sentence_parsing = input().split(" ") 
    go = language_evaluate(sentence_parsing) 
    print(int(go)) 
    if abs(go - 1/19) <= EPSILON or abs(go - 20/19) <= EPSILON or abs(go - 22/57) <= EPSILON or abs(go - 79/57) <= EPSILON or abs(go - 1/3) <= EPSILON: 
     dial += 1 
     if dial == 3: 
      dial = 0 
    elif abs(go - 1/13) <= EPSILON or abs(14/13) <= EPSILON: 
     current_room = "entrance" 
    else: 
     print("Sorry I don't understand that") 
    return dial, current_room 


def main(): 
    EPSILON = Decimal(0.00000000001) 
    current_room = "entrance" 
    dial_color = ["green", "blue", "red"] 
    dial = dial_color[random.randrange(3)] 
    lever_position = ["forward", "backward"] 
    lever = lever_position[random.randrange(2)] 
    win = False 
    while win is False: 
     while current_room is "entrance": 
      entrance(dial, lever, win, current_room, EPSILON) 
      win, current_room = entrance(dial, lever, win, current_room, EPSILON) 
     while current_room is "kitchen": 
      kitchen(lever, lever_position, current_room, EPSILON) 
      lever, current_room = kitchen(lever, lever_position, current_room, EPSILON) 
     while current_room is "pantry": 
      pantry(dial, current_room, EPSILON) 
      dial, current_room = pantry(dial, current_room, EPSILON) 
main() 

を最初から南に3回行くとエラーが表示されます。2回はパントリーの東に向かい、1回は何もしません。私は非常に失われています この時点でプログラムは3つのより類似したelif文が続きますが、入力を最初に与えると無視され、2回目は素数を含むものを除いて間違った動作を実行します1/11の割合;他のすべてのエリフは、増加する素数{1/11、1/13、1/17、1/19}を使用します。私はプログラミングの経験がほとんどなく(3か月)、最初の言語としてPythonを学んでいます。どんな助けでも大いに喜ぶでしょう。

+0

enumerationを使用する代わりに変更することをお勧めします。 –

+1

@EliSadoffコメントに追加すると、sum関数は無限ループ上で再帰的に呼び出されます。ほとんどの場合、実行はif文に達しません –

+0

申し訳ありませんが、間違ってマークされています。 sum()関数、どちらの方法でも動作しません –

答えて

1

あなたのコードにはいくつかの誤りがあります。入力として"south"を3回入力すると、問題の原因が表示されます。

entrance機能が真剣に壊れて一つのテストがあります:あなたは、

elif Decimal(1/17) or Decimal(18/17): 

いつもあなたが(それ以前のためにテストされ、北または東つもりはないことによって)その状態に達するので、もし、本当のことになるだろう常に食料室に行きます。

pantry関数にも同様の問題があります。ここでは、分数の一部をDecimalに変換せずに、解析コードから値を減算します。これにより、表示される例外が発生します。

が2回ある理由は、main関数が常に現在のルームの関数を2行(連続する2行)呼び出すためです。最初の選択は無視されます。

私がまだ見ているコードの他の部分にはおそらく多くのエラーがあります。

入力テキストを解析する値に分数を使用することで、必要以上に難しい作業になります。はるかに良い方法は、2の整数乗数を使用し、それらを組み合わせるためにビットごとに - または(|)を使用することです。単語move12**0)とsouthに解析されたが、162**4)に解析されている場合たとえば、southまたはmove southためのテストはif go == 16 or go == 17(なし型変換またはイプシロン必要に応じて)である可能性があります。余分な単語を気にしない場合は、bitwise-and(&)を使用して、1つの単語だけをテストすることができます:if go & 16

enumモジュール(Python 3.4で追加されたモジュール)を含むPythonのバージョンを使用している場合は、Enumを使用することも考えられます。

0

これはあなたのプログラムに問題がある:

  1. あなたがここに

    while current_room is "entrance": 
    

    の場合isオペレータはあなたを教えて、例えば、==を使用する必要がある場合も同様にテストするためisを使用しますオブジェクトが同じ値を持っていない場合はメモリ内の同じ場所を持ちますが、通常は文字列のような不変オブジェクトの場合と同じですが、それにはカウントできません。例えば

    >>> "asfdvfgbgdf" is "".join("asfdvfgbgdf") 
    False 
    >>> 
    

    ==を使用している間は、正解に

    >>> "asfdvfgbgdf" == "".join("asfdvfgbgdf") 
    True 
    >>> 
    

    な変化を与えるis

  2. ==のためにあなたはブール値またはTrueまたはFalseに対する他の値を比較する必要はありませんすべての。 FalseNone、すべてのタイプ、および文字列を含む、空の文字列とコンテナ(のゼロ数値、タプル:オブジェクトが及びBoolean context使用さパイソンに

    として真または偽の値がfalseとして解釈され振る舞うオブジェクトその、リスト、辞書、セットとfrozensets)。その他の値はすべてtrueと解釈されます。ユーザー定義のオブジェクトは、 __bool__()メソッドを提供することによって、真理値をカスタマイズすることができます。

    あなたは結果として初めて無視されることを原因と二回あなたの他の関数を呼び出して、あなたのmain機能で

    while not win: 
    
  3. へので、このインスタンスの

    while win is False: 
    

    変更をあなたは何もしません

    ここには

    entrance(...) 
    win, current_room = entrance(...) 
    

    kitchenpantryと同じです。その問題を解決するために、それぞれの最初の呼び出しを削除します。パントリー機能で

  4. 、ここ

    elif abs(go - 1/13) <= EPSILON or abs(14/13) <= EPSILON: 
    

    おそらくあなたはどういう意味ですか?

    elif abs(go - 1/13) <= EPSILON or abs(go - 14/13) <= EPSILON: 
    

    が、これが意味すると仮定されたものを二elif

    elif Decimal(1/17) or Decimal(18/17): 
    

    entrance第三elif

  5. kitchenと同じ?他のチェックを失敗した場合、これは常にあなたが使用することはありませんforループ

    for i, word in enumerate(sentence_parsing): 
    

    language_equate

  6. を通過しますので、それらの数のいずれも、ゼロではないとの点2で、それは常に真であります列挙を使用するので、

    for word in sentence_parsing: 
    

    あなたはword.lower()何回も繰り返しにそれを変更する理由はありませんのでiは、あなたは、時間の無駄であるため、常に同じ結果を与えるavoid repeat instructionsに試してみてください代わりに新しい変数を作成したり、あなたが

    input().lower() 
    

    かなどのような入力を取得するとすぐあなたもlowerを呼び出すことができます

    for word in sentence_parsing: 
        word = word.lower() 
        if word in both: 
         ... 
        elif word in ignore: 
         ... 
        ... 
    

    例えばその方法の結果をコン持っているものを再利用します

    input().lower().split() 
    
  7. それを分割し、私は私の以前のコメントで言ったように最後にあなたが通知小数点および浮動小数点数を有することができるように非常に多くのお互いを好きではない、いずれかを選択しますか、もう片方がそれを徹底的に守ってください。

    それともとして

    Blckknghtは、それが再帰的に実行し、すべてであなたはそれがしたいどのように動作しませんので、 `そのようなsum`を定義しないでくださいBit Mask、または

+0

フィードバックをいただきありがとうございます。私はプログラミングには本当に新しいです。私は私よりもはるかによく知っている人から助けを断ることは決してありません。 PSでは、これらの変更や誤った重複、二重否定、その他の種類の事象を数えるための論理的な実装でうまく動作します。 :) –

関連する問題