2017-04-07 2 views
0

私は、条件が満たされていないときにブール値Falseを出力する外部デバイスを監視しています。条件が満たされたときにブール値Trueを返します。 問題は、条件が満たされた後にブール値が複数回出力されることです。 Pythonでブール値が変更されたときに関数を一度実行する方法は?

この

は、出力は次のようになります。

False 
False 
False 
False 
True 
True 
False 
False 
False 

は、だから私は行うことができるようにしたいと思い何時間ごとに一度だけ、簡単な関数を、この値を監視し、実行している偽のブール値の変化に真実。私は単純な "変更"機能を持っている他の言語を見てきました。その可能性があり、おそらくもっと簡単になることがわかっています。

現在、私はこれを持っています。これを説明するために、変数 "ext_data"がpythonスクリプトが監視している外部データとして使用されます。

while True: 
    if ext_data == True: 
     print("true") 
     pass 

これはブール値trueに等しく、それは自分自身をリセットすると、ブールがまだTrueに設定されているので、私は一つだけをしたいときに私は、複数の測定値を取得するたびに「真」出力します。

助けてくれたおかげで!

編集:

がholdenwebによって書かれたEdgeDetectorクラスを使用してコードを更新しました。

ext_data = True/False # This returns True or False depending on the state 
         # of the variable. It is constantly monitored and 
         # could change at any moment, which is why I'm 
         # running the function in a while True loop 
def printer(): 
    print(u'something%s' % serialport.cts) 
    post_to_api('cycle_count') 

def myfunction(): 
    return ext_data 

test_subject = EdgeDetector(myfunction, printer) 

while True: 

    test_subject.test() 

これでも時折重複した投稿が返されます。このデータはEdgeDetectorクラスが正しく動作するための配列である必要がありますが、無限に長い配列を作成せずにこのデータを配列に配置することをどのように提案しますか?

+0

です。私の知る限り、アレイにデータを格納することについて言及した唯一の人物はあなたでした。それが「重複する投稿を返す」と言うと、どうやってそれを決定していますか?実際問題としては、バグがなければ(常に可能)、最初にハイからローへの遷移がない限り、コードがエッジを検出することは不可能です(技術的には本当にRisingEdgeDetectorと呼ぶべきですが、これは信号の極性に関する知識)。あなたがポーリングしているので、短命のパルスを見逃す可能性があります。 – holdenweb

答えて

2

あなたの質問の枠組みは、外部価値の取得方法を明確にしていません。これには、状態情報、具体的には最後に読み取られた値を格納する必要があります。

これをグローバル変数に格納することは可能ですが、これは適切な方法ではありません。必要に応じて再利用可能なソフトウェアコンポーネントを作成しようとすると、同じモジュール内の他のコードが同じグローバル変数を他の目的のために使用することを決定するイベント。したがって、クラスはより満足できるかもしれません。

次のクラスは、呼び出されたときに外部変数の値を返す関数を受け取るように記述されています。これはクラス__init__にパラメータread_signalとして渡されます。第2パラメータactionは、オブジェクトがFalseからTrueへの遷移を検出したときに呼び出す関数です。

これをキャストするということは、どのプログラムでも簡単に統合できることを意味します。多くの外部変数に対処する必要がある場合は、それぞれに対してEdgeDetectorを作成するだけです。

class EdgeDetector: 
    """Detects False to True transitions on an external signal.""" 

    def __init__(self, reader, action): 
     self.reader = reader 
     self.action = action 
     self.last_value = reader() # initialise value 

    def test(self): 
     new_value = self.reader() 
     if new_value and not self.last_value: 
      self.action() 
     self.last_value = new_value 

if __name__ == '__main__':     # simple self-test 
    vlist = [False, False, False, True, True, False, True, True, False, False, False, True] 
    vgen = (v for v in vlist)    # generator for value sequence 

    def test_reader():      # generate test sequence 
     value = next(vgen) 
     print("Read:", value) 
     return value 

    def printer(): 
     print("Edge transition detected") 

    test_subject = EdgeDetector(test_reader, printer) 
    for i in range(len(vlist)-1): 
     test_subject.test() 

通常、このモジュールをプログラムにインポートすると、メインコードから実装の詳細を再利用しやすくなります。プログラムとして実行すると、セルフテストコードは入力値のシーケンスと遷移が検出されたときに、コードを展開する前にコードに少しでも自信を持たせることができます。自己テストの出力は

Read: False 
Read: False 
Read: False 
Read: True 
Edge transition detected 
Read: True 
Read: False 
Read: True 
Edge transition detected 
Read: True 
Read: False 
Read: False 
Read: False 
Read: True 
Edge transition detected 
+0

これはまさに私が探していたものです。エッジ検出のすべての検索では、画像処理のためのエッジ検出が行われました。そのような詳細な応答をありがとう –

+0

助けを借りて喜んで – holdenweb

+0

簡単な質問は、変数のデータを格納せずにライブ変数を監視する場合、どうすればよいですか?私は、ライブ変数の最後の2つの値をリストに保存し、リストが2つの値に達するたびにリストを書き直そうとしました。私。リストは '[False、False]'となり、書き換えが続けられ、 '[False、True]'と等しい時にテストされますが、それでも私はそれから二重の読みを得ます。 –

1

あなたは(擬似コード)をトラックオフに保つ内部変数を持つことができ

executed = false 

if(!executed && output_from_device == true) 
    print("true") 
    executed = true 

しかし、私はあなたの全体のセットアップを知らないので、それのためのイベント処理のいくつかのフォームを作成する方が良いかもしれ素朴なアプローチではなく、

+0

'提案されたが、動作させることができなかった。私はそれを別のものにします。更新された "実行された"ことをfalseにすることで、ループは次のインスタンスまで正確に進むことができます。 – pixis

+0

のように内部変数を保持しようとしましたが、 '実行された場合、出力されなかった:実行された= false'のように、'実行された '' true'から 'false'へ' output_from_device'が変更された場合、 ' –

+0

@Dennisはコードの記述方法です私はまだ複数の読みを得ているからです。 varはブール値のデータです。実行しない場合は\ n と入力してください。 print( "実行")\ n 実行= True \ n if実行されていないvar:\ n 実行= False \ n' –

1

なぜような単純なsomehtingない:fooは空であるため、入力データの最初の要素は、印刷をトリガする

#Input Boolean 
inputData = [True,False,False,False,True,True,False] 


foo ='' 

for i in inputData: 
    if foo != i: 
     print("Yo") 
     foo = i 

引数inputData要素はFalseになりますときにFOO = Trueのように、次回の印刷がトリガされます。 ..など...

+0

これはライブデータを監視しているので、forループを実行できるとは思わないので、上限は無限になるでしょうか?これは、データを記録し、データをログに記録するのではなく、リアルタイムでデータと印刷( "yo")を監視する必要があります。 –

+0

ループの始めに何かからの入力を受け取る、あなたがこのデータを受け取るたびに、私が「いいえ」と書いた条件で確認することができますか? – NoOne

関連する問題