printing to stdout
Cameron Simpson
cs at cskk.id.au
Sun Aug 19 18:19:12 EDT 2018
On 19Aug2018 15:09, richard lucassen <mailinglists at lucassen.org> wrote:
>On Sun, 19 Aug 2018 19:53:04 +1000
>Cameron Simpson <cs at cskk.id.au> wrote:
>Although I do not understand what zip is doing exactly here (I presume
>I switch to use pointers instead of the values),
Someone else has descibed zip tersely: it pairs it the elements of 2 lists. In
fact it joins up matching elements of an arbitrary number of iterables. Here is
a 3 iterable example:
>>> zip( (1,2,3), (4,5,6), (7,8,9) )
<zip object at 0x10aa4ce88>
>>> list( zip( (1,2,3), (4,5,6), (7,8,9) ) )
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
See that is has collected the first element of each tuple, then the second and
so forth?
In my sentence above, "iterable" means any object you can iterate over - any
object you could use in a for-loop. So, obviously, a list as in your programme.
And also a tuple like (1,2,3) as in the example above (a tuple is an
unmodifiable list). ANd any number of other things that will yield a sequence
of values.
In Python 3 (which you're using) zip returns a lazy object, which does the
zipping as you request the values. That is why the example shows a base "zip()"
returning a "zip object" - we hand it to list() to get an actual list of all
the values. This is fast (instant return of the zip object without doing much
work) and cheap in memory (no need to make a huge result if you're zipping big
lists) and cheap in time (no need to make the whole result if you're only using
the first part of it).
So, to the code using the zip:
for device_nr, (pcf, pcf_value) in enumerate(zip(list_pcf, list_pcf_value)):
The inner zip yields (pcf, pcf_value) pairs from zipping list_pcf and
list_pcf_value, an iterable of:
(pcf[0], pcf-value[0]), (pcf[1], pcf_value[1]), ...
and you can write a for loop like this:
for pcf, pcf_value in zip(list_pcf, list_pcf_value):
to deal with each of those pairs in turn.
However, since you also need the index (device_nr) in order to update
list_pcf_value:
list_pcf_value[device_nr] = output
we then hand the whole thing to enumerate:
for device_nr, (pcf, pcf_value) in enumerate(zip(list_pcf, list_pcf_value)):
The enumerate does just what the previous one did, yields pairs of (index,
value). Each value is a pair from the zip, so it yields:
(0, (pcf[0], pcf-value[0])),
(1, (pcf[1], pcf_value[1])),
...
and Python's tuple unpacking syntax is fairly generous, so you want write:
device_nr, (pcf, pcf_value) = (0, (pcf[0], pcf-value[0]))
and you can stick that in the for loop, getting the syntax you're using in the
programme:
for device_nr, (pcf, pcf_value) in enumerate(zip(list_pcf, list_pcf_value)):
>The code is now as follows:
Much nicer. A few tiny nit picks:
>#!/usr/bin/env python3
>
>import sys
>from smbus import SMBus
>from time import sleep
>import RPi.GPIO as GPIO
>
>list_pcf = [0x38, 0x39, 0x3a, 0x3b]
>list_pcf_value = []
Just convention: you could call these pcfs and pcf_values and perhaps have more
readable code. Using plural names kind of indicates that they're lists (or
tuples or some other sequence of values) and reads more like prose.
># initialisation of the input devices:
>print ("[INFO] initialisation input devices")
"print" is just a regular function. We tend not to put a space before the "("
with other functions, and print isn't special. You might have this trailing
space left over from Python 2 (either your own or some example code), where
print _wasn't_ a function. So:
print("[INFO] initialisation input devices")
>for pcf in list_pcf:
> try:
> bus.write_byte(pcf, 0xff) # set device to 0xff
> except IOError as e:
> print ("[ALERT] I/O problem device 0x%x (init): %s" % (pcf, e))
> output = bus.read_byte(pcf)
You presumably also want a try/except around the bus.read_byte. You could use a
distinct try/except (rather wordy) or, since they're adjacent and your
exception action is the same, just put them both inside the try/except.
The advice to keep things as small as possible within the try/except has to do
with knowing exactly what kind of thing threw the exception. But they're both
bus operations and handled the same - including both is reasonable.
> list_pcf_value.append(output) # append value to list
> print ("found pcf8574 at 0x%x, input value: 0x%x" % (pcf, output))
> sys.stdout.flush()
># GPIO 23 set up as input. It is pulled up to stop false signals
>GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
>loopcntr = 0 # detects if INT is kept low
>
>while True:
> if GPIO.input(23) == 1: # if still 0, another event has occurred
> GPIO.wait_for_edge(23, GPIO.FALLING)
Can the GPIO ops also raise IOErrors? Just wondering.
Cheers,
Cameron Simpson <cs at cskk.id.au>
Stepwise Refinement n. A sequence of kludges K, neither distinct or finite,
applied to a program P aimed at transforming it into the target program Q.
More information about the Python-list
mailing list