@juicyboose: Mist, das Muster in den Zahlenfolgen hätte einem ja eigentlich auffallen können/müssen.
Also hat man sozusagen Rahmen von Werten die mit einer 0 anfangen und enden, und man sucht den Maximalwert innerhalb des Rahmens. Und den bildet man noch einmal auf eine Länge ab.
Ich habe jetzt 0 geschrieben, weil Programmierer üblicherweise mit 0 anfangen zu zählen.
Vollkommen ungetestet (bis auf die Beispiele in den DocStrings):
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
from contextlib import closing
from functools import partial
from itertools import imap, takewhile
from Queue import Queue
from RPi import GPIO
CONTACT_PINS = [37, 35, 33, 31]
def create_contact_stream(pins):
"""Create an iterable of values for rising edges on given pins.
The values are the index values of the given pins. So the first pin will
yield 0, the second 1, the third 2, and so on.
The returned object has as ``close()`` method which detaches the
callbacks/listeners for the pins. If you don't close the object and don't
consume the iterable, the values for rising edges will be queued and fill
the memory over time.
"""
GPIO.setup(pins, GPIO.IN, GPIO.PUD_UP)
queue = Queue()
for i, pin in enumerate(pins):
GPIO.add_event_detect(pin, GPIO.RISING, lambda _, i=i: queue.put(i))
try:
while True:
yield queue.get()
finally:
for pin in pins:
GPIO.remove_event_detect(pin)
def iter_peak_values(contact_values):
"""Return the peak values between two zero values.
>>> list(iter_peak_values([0, 1, 2, 1, 0, 0, 1, 0, 0, 1, 2, 3, 2, 1, 0]))
[2, 1, 3]
Values between an ending zero and the starting zero of the next measurement
are silently ignored. Like the 42 in this example:
>>> list(iter_peak_values([0, 1, 2, 1, 0, 42, 0, 1, 0]))
[2, 1]
"""
contact_values = iter(contact_values)
takewhile_not_zero = partial(takewhile, bool)
while True:
#
# Skip to first zero value.
#
for _ in takewhile_not_zero(contact_values):
pass
try:
yield max(takewhile_not_zero(contact_values))
except ValueError:
#
# When `max()` gets an empty iterable we are finished.
#
break
def iter_lengths(lengths, peak_values):
"""Map an iterable of peak values to the given lengths.
>>> list(iter_lengths([10, 50, 100], [2, 1, 3]))
[50, 10, 100]
"""
return imap(lambda x: lengths[x - 1], peak_values)
def main():
GPIO.setmode(GPIO.BOARD)
try:
lengths = [10, 50, 100]
with closing(create_contact_stream(CONTACT_PINS)) as contact_values:
total_length = 0
for length in iter_lengths(
lengths, iter_peak_values(contact_values)
):
total_length += length
print(total_length)
finally:
GPIO.cleanup()
if __name__ == '__main__':
main()