【问题标题】:Is there a way to detect True to False transitions in python?有没有办法在 python 中检测真到假的转换?
【发布时间】:2020-08-20 14:15:52
【问题描述】:

我正在使用下面的代码来检测从 False 到 True 的转换。我需要单独的代码,只检测从真到假的变化。有没有办法用下面的当前代码做到这一点?

test = [True, False, False, True, True, False, True, True, False, False, False, True]

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

 # simple self-test
 if __name__ == '__main__':
     vlist = test
     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("Phase transition")

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

注意:这不是我的代码。我正在使用该线程提供的代码:How to execute a function once when boolean value changes in python?

我无法在该线程中发帖询问后续问题。 感谢您提供任何帮助。

【问题讨论】:

    标签: python boolean boolean-logic


    【解决方案1】:

    问题出在if new_value and not self.last_value:

    所以第一部分是寻找 new_value 是否具有 Truthy 值。并且它正在寻找 self.last_value 是否具有 Falsey 值。当您开始相互比较两个不同的布尔值时,这会变得很混乱。

    第一部分真的是看new_value中是否有值。因此,我们可以将其与无进行比较。第二部分是真正查看两个布尔值是否匹配,因此我们可以将它们相互比较。

    将线更新为这个,它应该适用于任一方向的转换。

    if new_value is not None and new_value is not self.last_value:

    编辑:

    根据您的 cmets: 有几种方法可以跟踪相变,而无需逐个查找。

    选项一:

    使用一个函数来跟踪从真到假的过渡和从假到真的过渡。我们可以将值传回给打印机函数。

    def test(self):
        new_value = self.reader()
        if new_value is not None and new_value is not self.last_value:
            self.action(new_value) # Note here we are passing a value back
    
        self.last_value = new_value
    

    现在我们只需添加到打印机功能以查看更改。

    def printer(transition):
       print(f"Phase transition to: {transition}")
    

    最终代码选项 1:

    test = [True, False, False, True, True, False, True, True, False, False, False, True]
    
    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()    # initialize value
    
         def test(self):
             new_value = self.reader()
             if new_value is not None and new_value is not self.last_value:
                 self.action(new_value)
    
             self.last_value = new_value
    
    
    
    # simple self-test
    if __name__ == '__main__':
        vlist = test
        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(transition):
           print(f"Phase transition to: {transition}")
    
        test_subject = EdgeDetector(test_reader, printer)
        for i in range(len(vlist)-1):
            test_subject.test()
    

    选项二:

    如果您想要单独的代码用于从 false 到 true 以及从 true 到 false 的转换,这就是这样做的方法。

    首先在 EdgeDetector 类中,我们需要修改 init 如下:

    def __init__(self, reader, action_true, action_false): #Note the second action here
        self.reader = reader
        self.action_true = action_true
        self.action_false = action_false # We set it just like the previous one.
        self.last_value = reader()
    

    然后我们就可以更新测试代码了。

    def test(self):
        new_value = self.reader()
        if new_value is not None and new_value is not self.last_value:
            if new_value:
                self.action_true()
            else:
                self.action_false()
    
        self.last_value = new_value
    

    然后我们修改printer语句,添加第二条:

    def printer_true():
        print("Phase transition to true")
        
    def printer_false():
        print("Phase transition to false")
    
    

    最后EdgeDetector的初始化需要更新。

    test_subject = EdgeDetector(test_reader, printer_true, printer_false)
    

    选项 2 的最终代码

    test = [True, False, False, True, True, False, True, True, False, False, False, True]
    
    class EdgeDetector:
         """Detects False to True transitions on an external signal."""
    
         def __init__(self, reader, action_true, action_false):
             self.reader = reader
             self.action_true = action_true
             self.action_false = action_false
             self.last_value = reader()    # initialize value
    
         def test(self):
             new_value = self.reader()
             if new_value is not None and new_value is not self.last_value:
                 self.action(new_value)
    
             self.last_value = new_value
    
    
    
    # simple self-test
    if __name__ == '__main__':
        vlist = test
        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_true():
           print(f"Phase transition to true")
    
        def printer_false():
           print(f"Phase transition to false")
    
        test_subject = EdgeDetector(test_reader, printer_true, printer_false)
        for i in range(len(vlist)-1):
            test_subject.test()
    

    【讨论】:

    • 感谢您的帮助。我将在上述更改中遇到的问题是它会产生太多信号。如果不手动查找原因,将很难区分它发生变化的原因。
    • 你只是想要从假到真的变化吗?
    • 是的,我需要只寻找真到假变化的代码。我想要两个不同的代码,所以它可以生成两种不同类型的信号。输入每个代码的数据集将是不同的。很抱歉对原帖的混淆。我稍微编辑了一下
    • 我编辑了答案并提供了更多细节。那帮助更好?
    • 是的,正是我需要的。谢谢您,对于原始帖子的混乱,我们深表歉意。
    【解决方案2】:

    想法:需要检测 False , True 模式,表达式为~a & b。 要对齐输入,请使用 input[1:] 和 input[:-1],所以~input[:-1] & input[1:]

    test = [True, False, False, True, True, False, True, True, False, False, False, True]
    
    def edge_detector(inp):
        import numpy as np
        inp = np.array(inp)
        return np.arange(len(inp)-1)[~inp[:-1] & inp[1:]]
    
    print(edge_detector(test))
    

    【讨论】:

      猜你喜欢
      • 2015-06-18
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 2019-09-27
      • 2011-06-26
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多