2010-11-30 13 views
1

中性子ビームの単純なモンテカルロシミュレーションを書いています。ジオメトリロジックに問題がある(何かがある環境にあるかどうか)。私の問題は、Rubyは条件を順番に処理して、最初の価値を維持しているようです。ルビーの結合論理の問題

以下のコードは非常にうまくこのことを示しています

def checkPosition(*args) 

    polyCylRad = 2.5 
    polyCylFr = 15 
    polyCylB = -2.0 
    borPolyBoxL = 9.0/2 
    pbCylRad = 3.0 
    pbBoxL = 10.0/2 
    cdBoxL = 9.5/2 

    position = Array.new 
    material = String.new 

    args.each do |item| 
    position << item.inspect.to_f 
    end 
    xSquared = position.at(0) ** 2 
    ySquared = position.at(1) ** 2 
    zSquared = position.at(2) ** 2 
    modX = Math.sqrt(xSquared) 
    modY = Math.sqrt(ySquared) 
    modZ = Math.sqrt(zSquared) 

    puts xSquared 
    puts Math.sqrt(ySquared + zSquared) <= polyCylRad 
    puts (position.at(0) >= polyCylB) 
    puts (position.at(0) <= polyCylFr) 
    puts (position.at(0) >= polyCylB)and(position.at(0) <= polyCylFr) 
    puts (position.at(0) <= polyCylFr)and(position.at(0) >= polyCylB) 

    puts zSquared 


    polyCylinder = (Math.sqrt(ySquared + zSquared) <= polyCylRad)and((position.at(0) >= polyCylB)and(position.at(0) <= polyCylFr)) 
    puts polyCylinder 
    borPolyBox = ((modX <= borPolyBoxL)or(modY < borPolyBoxL)or(modZ <= borPolyBoxL)) and not((modX >= cdBoxL)or(modY >= cdBoxL)or(modZ >= cdBoxL)) and not(Math.sqrt(ySquared + zSquared) <= polyCylRad) 
    puts borPolyBox 
    cadmiumShield = ((modX <= cdBoxL)or(modY < cdBoxL)or(modZ <= cdBoxL)) and not((modX >= pbBoxL)or(modY >= pbBoxL)or(modZ >= pbBoxL)) and not(Math.sqrt(ySquared + zSquared) <= polyCylRad) 
    puts cadmiumShield 
    leadShield = (((modX <= pbBoxL)or(modY <= pbBoxL)or(modZ <= pbBoxL)) or ((position.at(0) <= ployCylFr)and(Math.sqrt(ySquared + zSquared) <= pbCylRad))) and not(Math.sqrt(ySquared + zSquared) <= polyCylRad) 
    puts leadShield 

    if (polyCylinder) : material = "poly" 
    elsif(borPolyBox) : material = "borPoly" 
    elsif(cadmiumSheild) : material = "cd" 
    elsif(leadSheild) : material = "pb" 
    elsif(material == nil) : position = Array.new 
    end 

    thisEnvironment = Array.new 
    thisEnvironment << position << material 
    puts thisEnvironment.at(0) 
    puts thisEnvironment.at(1) 
end 

checkPosition(40, 0, 0) 

その後、(私は怠け者だと将来的にはより多くの引数を追加したい場合があります)あなたが好きなコードを呼び出すが、それを引数として*引数を与えることを3つの浮動小数点数を使って呼び出すと、ジオメトリがロジックに設定されます。

私の質問は:どのようにそれは(つまり、ロジックを正しく評価する)のように動作するようになるかどうかは、 (私はしかし、読んで悪夢であり、メモリが安価で、リメイクしようとしています何である。)

+1

あなたが指定できますあなたがそれをどのようにして論理を評価したいのかについてもっと具体的に?コード出力はどうすればよいですか? – wdebeaum

+0

さて、私が見たいと思っているのは、さまざまなドメインに与えられた真理値です。これは引数の配列に依存します。 私の問題はputs文の最初の束で概説されています。評価された論理の順序は、&&、|| orとandと*、これはなぜですか? 私はこれとは思っていませんが、私はjEditインタプリタを使用しています(これは私のPATHだけに見えます)。 – morb

答えて

0

&&代わりのand||代わりのor!代わりのnotを使用してみてください。

あなたの問題はおそらく優先順位1です - 詳しくはthis articleをお読みください。

+0

またはかっこの使用について信じられないほど宗教的である。 – philosodad

+0

それは私がより良く読むのを助け、私は演算子のすべての順列を通過しました。私は今日、あなたが使うことができることを知りました。そして、私はRuby noobです。 – morb

+0

私は本当に&&と||をテストしましたが、その優先順位は問題ではありませんでした。 – morb

0

コードを見ると、これを設定する方法は、4つの「材料」変数をブール値にすることです。次に、それらのboolをif-elsif-elseブロックに送ります。

この問題は、最初にtrueを返す場合、if-elsif-elseブロックを終了することになります。これが最初の価値を維持することによって意味するものなら、それは極めて予測可能な結果です。

+0

philosodad:ありがとう、たくさん学ぶべきことがある。私はそれが事実だと思った。 – morb

+0

ああ、実際はありません。これはプログラムのロジックの一部であり、特定の領域にある位置(argとして与えられた配列)をテストする中心点から外側に働き、もしelse bloackが*仮定されて*最初の真の値を終了すると仮定すると。 – morb

3

あなたは、あなたの代わりにand&&||代わりのor、および!を使用する必要がありますが、おそらく「盾」あなたがそれらを使用している状況で

を意味し、「Sheild」を数回入力しましたnotの代わりにその理由は、orandの優先順位が低いため、代入演算子が必要な方法で動作しなくなるからです。例えば、

a = b and c 

(a = b) and c 

常に値bが割り当てられ、その結果にtruthyあり、cは評価(および廃棄)されていることなどを評価します。一方、

a = b && c 

は、あなたがこのコードで何をしたいです

a = (b && c) 

として評価されます。その向こう

私は物事のために少しのメソッドの多くを作成することができるように、私は、クラスにこのコードのすべてを移動します:メソッド呼び出しでcheckPosition内のローカル変数を交換する機会のための

class PositionChecker 

    def initialize(*args) 
    @x, @y, @z = *args 
    end 

    def checkPosition 
    ... 
    end 

end 

ルック。あなたは自分の方法として、これらの述語のすべてを持ってたら

class PositionChecker 
    ... 
    def borPolyBox 
    ((modX <= borPolyBoxL)||(modY < borPolyBoxL)||(modZ <= borPolyBoxL)) && !((modX >= cdBoxL)||(modY >= cdBoxL)||(modZ >= cdBoxL)) && !(Math.sqrt(ySquared + zSquared) <= polyCylRad) 
    end 
    ... 
end 

、あなたが作成できます。たとえば、あなたは(一度それが使用する値であり、独自の方法のすべてを)独自のメソッドにborPolyBoxを移動できます

def material 
    [ 
    [:polyCylinder, 'poly'], 
    [:borPolyBox, 'borPoly'], 
    [:cadmiumShield, 'cd'], 
    [:leadShield, 'pb'], 
    ].each do |method, name| 
    return name if send(method) 
    end 
    nil 
end 

と位置について1:そうのような材料を決定する方法、

def position 
    [@x, @y, @z] if material 
end 

何も残っていないまで、この線に沿って進みますが、ちっちゃいのバッグは、メソッドを重視しました。

+0

ありがとうございます!オブジェクトはすべて奇妙なコンセプトです。 – morb

+0

私はこのシステムの周りに構築し、それは美しく、アドバイスのおかげで動作します!私は将来、複雑なロジックを扱う際にこれを必ず使用します。 – morb

+0

@morb、よろしくお願いします!私はあなたのために働いて満足しています。 –

1

すべてをandorから&&||に変更します。

実際に誰も実際にの代わりにarray[index]の代わりに使用されて見た。

私も名前付きパラメータ

def test(params) 
    x = params[:x] || raise("You have to provide x!") 
    y = params[:y] || raise("You have to provide y!") 
    z = params[:z] || raise("You have to provide z!") 
    puts x, y, z 
end 

の一種として、ハッシュパラメータの賛成で*argsに対してお勧めしますと(ルビー1.9+構文)とそれを呼び出す

test({x: 42, y: 4711, z: 93}) 

42
4711
93

+0

'fetch'を使うと、キーが存在しなければ' raise'する必要はありません。 –

+0

array [element]と一緒に動作しませんでしたので、私はgoogleを使用しました... – morb

+0

@Andrewはい、しかし、 'IndexError:key not found'はあまり有益ではありません。 –