Closed Sarioah closed 1 year ago
A slice on the left side of the =
designates multiple pixels. It will not expand a single pixel value (an RGB tuple) on the right. You have to do that yourself, as in pix[::2] = [(255, 0, 0)] * len(pix[::2])
.
This is true of any Python slicing operation. It's not just neopixels. E.g.:
>>> a = [2,4,6]
>>> a[::2]
[2, 6]
>>> a[::2] = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must assign iterable to extended slice
>>> a[::2] = (3, 3)
>>> a
[3, 4, 3]
If you are seeing examples that are doing implicit expanding, they are wrong and we need to fix them, so please give us links to those if you see them.
Note that you can loop on indices and assign each color using auto_write=False to avoid updating until you are finished.
len(pix) // 2
would be a better choice too (len(pix[::2])
will allocate a temporary slice).
There's also helpers that can abstract a group of pixels that you use regularly like adafruit_pixelmap's PixelMap, which has a fill() method and is accelerated in C. If your board's build doesn't support the low level _pixelmap, you can use the PixelMap class from the adafruit_led_animation library helpers module.
A slice on the left side of the
=
designates multiple pixels. It will not expand a single pixel value (an RGB tuple) on the right... ...This is true of any Python slicing operation. It's not just neopixels
That's what I figured, but then the example I found suggested custom behaviour with the single colour on the RHS which ended up confusing me so thanks for clearing that up.
In my case iterating over the temporary slice with a delayed .show()
is going to be the cleanest way I think (since I'm already instantiating with auto_write=False
anyway). The PixelMap looks like an interesting library though, when I get a chance this weekend I'll probably have a play with it, thanks :)
I found the main example suggesting the custom behaviour here. I do remember seeing it in a couple other places, though this one is all I can find right at the moment. I suspect perhaps the others might reference this same "CheatSheet" like this forum post does.
There are a couple of examples out there in the wild that suggest that list slicing can be a shortcut to setting many NeoPixel-compatible LEDs at once (one such example).
The gist seems to be that one can assign a colour to a sliced list, i.e.
NeoPixel[::2] = (255, 0, 0)
should set every second pixel to red.In practice it seems like the slicing exposes a mostly plain tuple instead. Attempts to assign to it appear to invoke sequence unpacking on the colour, usually throwing a
ValueError
since the LHS and RHS have different lengths.I've been able to assign a tuple of colours to a sliced NeoPixel list, but this seems pretty cumbersome to do every time...
The final statement works, but doesn't feel like this is the way the slicing implementation was supposed to be used. The examples I can find seem suggest I should be able to have a bare colour on the RHS.