Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Initializing variables in a class

Thu Jun 17, 2021 9:18 pm

Hello. I'm writing a class for my NeoPixel LED strip, and before I continue further, I wanted to get some pointers on how to write good classes. Also a couple questions:
  1. How would I make it so that I can make the brightness configurable? Say I wanted to have a default brightness of "0.2" and the user wanted to change it. Let's say it can be changed with a new function called adjustBrightness(brightness_level). Right now the value is defined outside of the class when instantiating NeoPixel.
  2. Is there a way I can just instantiate the outside variables (like numPixels or pixels) inside the class, or would that be bad practice?
My code:

Code: Select all

# LEDStripClass.py
import time
import board
import neopixel

# LED Strip Pin Location
LED_STRIP_PIN = board.D12

# LED Strip Initialization
numPixels = 60
pixels = neopixel.NeoPixel(LED_STRIP_PIN, numPixels, brightness=0.2)

class LEDStrip:
    def turnOff(self, pixels):
        pixels.fill((0, 0, 0))
        time.sleep(0.3)

    def turnRedOn(self, pixels):
        pixels.fill((255, 0, 0))
        time.sleep(0.3)

    def turnGreenOn(self, pixels):
        pixels.fill((0, 255, 0))
        time.sleep(0.3)
        
    def turnBlueOn(self, pixels):
        pixels.fill((0, 255, 0))
        time.sleep(0.3)

    def rainbowPattern(self, pixels):
        for x in range(0, 9, 1):
            pixels[x] = (255, 0, 0)
            time.sleep(0.1)

        for x in range(9, 18, 1):
            pixels[x] = (255, 70, 0)
            time.sleep(0.1)

        for x in range(18, 27, 1):
            pixels[x] = (255, 255, 0)
            time.sleep(0.1)

        for x in range(27, 36, 1):
            pixels[x] = (0, 128, 0)
            time.sleep(0.1)

        for x in range(36, 45, 1):
            pixels[x] = (0, 0, 255)
            time.sleep(0.1)

        for x in range(45, 54, 1):
            pixels[x] = (75, 0, 130)
            time.sleep(0.1)

        for x in range(54, 60, 1):
            pixels[x] = (128, 0, 255)
            time.sleep(0.1)
Thanks!

ghp
Posts: 1998
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Initializing variables in a class

Fri Jun 18, 2021 6:32 am

Python classes provide an __init__ method which is the 'constructor'. See https://docs.python.org/3/reference/dat ... t.__init__
For your code, it could look like this:

Code: Select all

class LEDStrip:
    def __init__(self, pin, numPixels, brightness=0.2):
        self.numPixels = numPixels
        self.brightness = brightness  
        self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightness)

    def turnOff(self, pixels):
        self.pixels.fill((0, 0, 0))
        time.sleep(0.3)
pin and numpixels have no default values, as these are most possibly different when you attach a second LED strip.
in the class, as indicated for the turnOff-method, the pixels have to refer to the class field: self.pixels

Creating an instance of the class is like this:
ledStrip = LEDStrip(LED_STRIP_PIN, 60 )
or
ledStrip = LEDStrip(LED_STRIP_PIN, 60, 0.5 )

Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Re: Initializing variables in a class

Fri Jun 18, 2021 6:41 pm

ghp wrote:
Fri Jun 18, 2021 6:32 am
Python classes provide an __init__ method which is the 'constructor'. See https://docs.python.org/3/reference/dat ... t.__init__
For your code, it could look like this:

Code: Select all

class LEDStrip:
    def __init__(self, pin, numPixels, brightness=0.2):
        self.numPixels = numPixels
        self.brightness = brightness  
        self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightness)

    def turnOff(self, pixels):
        self.pixels.fill((0, 0, 0))
        time.sleep(0.3)
pin and numpixels have no default values, as these are most possibly different when you attach a second LED strip.
in the class, as indicated for the turnOff-method, the pixels have to refer to the class field: self.pixels

Creating an instance of the class is like this:
ledStrip = LEDStrip(LED_STRIP_PIN, 60 )
or
ledStrip = LEDStrip(LED_STRIP_PIN, 60, 0.5 )
Thanks a lot! I will try that way now.

Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Re: Initializing variables in a class

Fri Jun 18, 2021 11:48 pm

ghp wrote:
Fri Jun 18, 2021 6:32 am
Python classes provide an __init__ method which is the 'constructor'. See https://docs.python.org/3/reference/dat ... t.__init__
For your code, it could look like this:

Code: Select all

class LEDStrip:
    def __init__(self, pin, numPixels, brightness=0.2):
        self.numPixels = numPixels
        self.brightness = brightness  
        self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightness)

    def turnOff(self, pixels):
        self.pixels.fill((0, 0, 0))
        time.sleep(0.3)
pin and numpixels have no default values, as these are most possibly different when you attach a second LED strip.
in the class, as indicated for the turnOff-method, the pixels have to refer to the class field: self.pixels

Creating an instance of the class is like this:
ledStrip = LEDStrip(LED_STRIP_PIN, 60 )
or
ledStrip = LEDStrip(LED_STRIP_PIN, 60, 0.5 )
So I tried writing it that way, but I am getting this error: "__init__() takes 3 positional arguments but 4 were given" when I initialize it as "ledStrip = LEDStrip(LED_STRIP_PIN, 60)".

Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Re: Initializing variables in a class

Fri Jun 18, 2021 11:57 pm

My code:

Code: Select all

# LEDStripClass.py
import time
import board
import neopixel

class LEDStrip:
    def __init__(self, pin, numPixels, brightnessValue):
        self.numPixels = numPixels
        self.brightnessValue = brightnessValue
        self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightnessValue)

    def turnOff(self):
        self.pixels.fill((0, 0, 0))
        time.sleep(0.3)

    def turnRedOn(self):
        self.pixels.fill((255, 0, 0))
        time.sleep(0.3)

ledStrip = LEDStrip(board.D12, 60, 0.2)

try:
    while True:
        ledStrip.turnOff()
        time.sleep(0.5)
        ledStrip.turnRedOn()
        time.sleep(1)
except KeyboardInterrupt:
    ledStrip.turnOff()
The exact error in question:

Code: Select all

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    ledStrip = LEDStrip(board.D12, 60, 0.2)
  File "test.py", line 10, in __init__
    self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightnessValue)
TypeError: __init__() takes 3 positional arguments but 4 were given

cleverca22
Posts: 3912
Joined: Sat Aug 18, 2012 2:33 pm

Re: Initializing variables in a class

Sat Jun 19, 2021 12:02 am

i think the problem is on this line

Code: Select all

self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightnessValue)

Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Re: Initializing variables in a class

Sat Jun 19, 2021 12:04 am

cleverca22 wrote:
Sat Jun 19, 2021 12:02 am
i think the problem is on this line

Code: Select all

self.pixels = neopixel.NeoPixel(pin, self.numPixels, self.brightnessValue)
Yeah, trying to figure out how to fix it right now. Going crazy :lol:

cleverca22
Posts: 3912
Joined: Sat Aug 18, 2012 2:33 pm

Re: Initializing variables in a class

Sat Jun 19, 2021 12:17 am

compare it to the original line you gave:

Code: Select all

pixels = neopixel.NeoPixel(LED_STRIP_PIN, numPixels, brightness=0.2)
that has 2 positional arguments (plus the implied self), and one named argument

Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Re: Initializing variables in a class

Sat Jun 19, 2021 1:08 am

cleverca22 wrote:
Sat Jun 19, 2021 12:17 am
compare it to the original line you gave:

Code: Select all

pixels = neopixel.NeoPixel(LED_STRIP_PIN, numPixels, brightness=0.2)
that has 2 positional arguments (plus the implied self), and one named argument
Hmm I will probably just stick to my original code. Still can't figure it out

cleverca22
Posts: 3912
Joined: Sat Aug 18, 2012 2:33 pm

Re: Initializing variables in a class

Sat Jun 19, 2021 2:04 am

the key difference, is self.brightnessValue vs brightness=self.brightnessValue

https://treyhunner.com/2018/04/keyword- ... in-python/

Gatsby25
Posts: 26
Joined: Wed Jun 09, 2021 10:21 pm

Re: Initializing variables in a class

Sat Jun 19, 2021 2:55 am

cleverca22 wrote:
Sat Jun 19, 2021 2:04 am
the key difference, is self.brightnessValue vs brightness=self.brightnessValue

https://treyhunner.com/2018/04/keyword- ... in-python/
Jeez it's really the minor things that get you. It works now. Thank you!

If I wanted the user to be able to configure red/green/blue intensity, I can just make separate functions that would return those values within the class right?

ghp
Posts: 1998
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Initializing variables in a class

Sat Jun 19, 2021 7:34 am

right?
right !

Return to “Python”