2017-05-20 2 views
0

2つの微分方程式の値を含むオブジェクトがあります。例えばオブジェクトを負の数でチェックする方法

#create equation object 
class EquationValues(object): 
    x   = 0 
    y   = 0 
    xMin  = 0 
    xMax  = 0 
    yMin  = 0 
    yMax  = 0 
    deltaTime = 0 

# Class constructor/initilizer 
    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime): 
     self.x   = x 
     self.y   = y 
     self.xMin  = xMin 
     self.xMax  = xMax 
     self.yMin  = yMin 
     self.yMax  = yMax 
     self.deltaTime = deltaTime 

def make_equationValues(x, y, xMin, xMax, yMin, yMax, deltaTime): 
    equationValues = EquationValues(x, y, xMin, xMax, yMin, yMax, deltaTime) 
    return equationValues 

with open ('inputs.csv', 'r') as f: 
    reader = csv.reader(f, delimiter = ',') 
    data  = list(reader) 
    rowCount = len(data) 

while x < rowCount: 

    try: 
     # Set variables and make sure they are the right format 
     x   = float(data[x][0]) 
     y   = float(data[x][1]) 
     xMin  = float(data[x][2]) 
     xMax  = float(data[x][3]) 
     yMin  = float(data[x][4]) 
     yMax  = float(data[x][5]) 
     deltaTime = float(data[x][6]) 

     # Check for negative input, if negative throw value error 
     if (x < 0) or (y < 0) or (xMin < 0) or (xMax < 0) or (yMin < 0) or (yMax < 0) or (deltaTime < 0): 
      raise ValueError 

は、どのように私はすべての値を効率的に負の数を確認することができますか?

現在、私は、例えば

するtry/exceptで声明使用し、場合、それを行うことができる午前:

if (x < 0) or (y < 0) or (xMin < 0) or (etc): 
    raise ValueError 

これはそれを行うための最善の方法のように見えるしていません。これを行うより良い方法はありますか?あなたのコードは、実際に動作する場合

+0

者:次に、あなたの元のクラスは次のようになり

from weakref import WeakKeyDictionary class NonNegativeNumber(object): def __init__(self): self.data = WeakKeyDictionary() def __get__(self, obj, objtype): return self.data.get(obj, 0) def __set__(self, obj, val): if val < 0: raise ValueError('must be nonnegative value') self.data[obj] = val 

:記述子は記述子クラスを使用して定義された任意の属性に設定されているから無効な値を防ぐために使用することができますクラス属性。もっとコードを表示できますか? –

+1

これらの値をコンテナに入れ、コンテナにループすることはありますか?また、このクラス定義はあなたが思っていることをしていない可能性があります... –

+0

本当に、あなたはおそらく '__init__'関数を定義したいと思うでしょう。 – nucleon

答えて

1

(これらは属性がある場合、それは動作しないでしょう)、あなたはこのようにそれを書き換えることができます。

if any(var < 0 for var in (x, y, xMin, xMax, yMin, yMax, deltaTime)): 
    raise ValueError 

チェックしたい変数は名前だけの集まりなので、そこにあなたができることはそれほど多くありません。彼らがリスト、辞書、またはNamedTupleなどであれば、改善の余地が増えます。

チェックがmake_equationValues()で開催することになっている(しかし、なぜあなただ​​けのコンストラクタにチェックを入れていない?)、あなたはあなたが表示さよりもたくさんより多くの変数を持っている場合は、このようなチェックを効率化することができ:

def make_equationValues(*args): 
    if any(var < 0 for var in args): 
     raise ValueError 

    return EquationValues(*args) 

しかし、あなたは、もはやそれエラーが発生しやすいし、維持するのは難しいますあなたの関数、引数のための署名を持っていないので、私は、このことをお勧めしません。

+0

これはうまく動作します。 – feltersnach

1

anyステートメントを使用して、いずれかが否定的であるかどうかを確認できます。

class EquationValues(object): 
    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime):  
     self.x   = x 
     self.y   = y 
     self.xMin  = xMin 
     self.xMax  = xMax 
     self.yMin  = yMin 
     self.yMax  = yMax 
     self.deltaTime = deltaTime 

     negatives = any(v for v in {x,y,xMin,xMax,yMin,yMax,deltaTime} if v < 0) 
     if negatives: 
      raise ValueError("One variable is negative") 

EquationValues(0,0,0,0,0,0,-1) 
# ValueError: "One variable is negative" 

また、現在のローカルスコープ変数の辞書を取得するためにlocals()を使用することができます。

class EquationValues(object): 
    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime):  
     self.x   = x 
     self.y   = y 
     self.xMin  = xMin 
     self.xMax  = xMax 
     self.yMin  = yMin 
     self.yMax  = yMax 
     self.deltaTime = deltaTime 

     if [v for v in locals().values() if isinstance(v, int) if v < 0]: 
      raise ValueError("One variable is negative") 

EquationValues(0,0,0,0,0,0,-1) 
# ValueError: "One variable is negative" 
+0

リストをマテリアライズして空のリストをチェックする代わりに、代わりにジェネレータ式で 'any'を使うことができますか? –

+0

素晴らしいアイデア、ありがとう。あなたのお勧めを使用するように変更されました – abccd

+0

@abccd私の問題であなたの助けに感謝します。 – feltersnach

1

この例は、Python Descriptors Demystifiedからコピーされています。

特定の値に制限する必要がある属性を格納するには、ディスクリプタを使用する必要があります。彼らは、オブジェクト属性をされていません

class EquationValues(object): 
    x   = NonNegativeNumber() 
    y   = NonNegativeNumber() 
    xMin  = NonNegativeNumber() 
    xMax  = NonNegativeNumber() 
    yMin  = NonNegativeNumber() 
    yMax  = NonNegativeNumber() 
    deltaTime = NonNegativeNumber() 

    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime): 
     self.x = x 
     self.y = y 
     self.xMin = xMin 
     self.xMax = xMax 
     self.yMin = yMin 
     self.yMax = yMax 
     self.deltaTime = deltaTime 
+1

'self.x = NonNegativeNumber(-1)'のようなものはまだ動作しませんか? – mkrieger1

+0

@tomlynch私はこれまで、意図したように動作していないこれで動作しています。 – feltersnach

+0

私はそれを修正しました。また、記述子は '__init__'への呼び出しで負の数を禁止する必要があります。 –

関連する問題