Krafter
Posts: 22
Joined: Wed Jan 27, 2016 11:36 pm

Variable passed to class

Wed Oct 17, 2018 2:27 am

Yes, I'm sure this will be an easy answer but I'm a little confused.

I have a library to control RGB Leds and I am working on a script to call different functions in that library. In the library, I also have a class that I'd like to pass a variable to. Below is the class. I'd like to have each element of the list to a variable. Any tips would be great.

Code: Select all

class RGB():
	rgb_red = [100, 0, 0]
	rgb_grn = [0, 100, 0]
	rgb_blu = [[0, 0, 100]
	# rgb_yel = [x, x, x] and so on

scotty101
Posts: 3184
Joined: Fri Jun 08, 2012 6:03 pm

Re: Variable passed to class

Wed Oct 17, 2018 8:58 am

I'm not sure what you are trying to do so perhaps you can explain it again.

Here is an example of a python class (and simple usage) that may help you figure out what you want to do or the correct syntax.

Code: Select all

class MyClass:
    def __init__(self, param1, param2, param3):
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3

    def show_params(self):
        print(self.param1,self.param2,self.param3)

foo = MyClass("test","test2","test3")
foo.show_params()
Reading your post back, are you sure you don't want to use a dictionary to store your color names and their RGB values?

Code: Select all

myColors = {'red': [100,0,0],
             'green': [0,100,0],
             'blue': [0,0,100]
            }

#Set the LED to a named color
color = myColors['red']
#This is made up code, Note I use * to expand a list to be 3 seperate parameters
set_rgb(*color)
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

User avatar
paddyg
Posts: 2227
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Variable passed to class

Wed Oct 17, 2018 9:20 am

Python will let you drive rough-shod over normal structured programming. So you could just

Code: Select all

class RGB:
    rgb_red = [100, 0, 0]
    etc
...
RGB.my_random_color = [99,50,50]
# you can now use your class level attribute!
Quite hard to make suggestions without seeing how you intend to use this. Passing a variable to a class function sounds like you have an instance of the class. It looks like maybe the rgb_red, rgb_grn etc are preset values for an array to represent the three components [r, g, b]. i.e. I'm assuming you won't change the values of rgb_red etc (though the convention would be to use capitalized 'variable' names if these were to be static 'constants'). One problem you will find is that if you set an object equal to another object (unless it's a primitive int or float), python will simply set the left hand variable to point at the memory where the right hand variable is stored. So to copy the actual contents of an array you have to do

Code: Select all

rgb_red = [100, 0, 0]
rgb = rgb_red[:]
#or
rbg = rgb_red.copy()
I agree with scotty that if you want to either set to a named colour such as 'red', 'green' etc, or to an arbitrary colour you might want to use a dict and have a function to check if it's predefined.

Code: Select all

class RGB():
    COLOR = {'red': [100, 0, 0],
            'green': [0, 100, 0],
            'blue': [0, 0, 100],
            # and so on
        }
    
    def __init__(self, value=[0, 0, 0]):
    	self.rgb = value.copy()
    
    def set_color(self, value):
        if value in RGB.COLOR: # or self.COLOR
            self.rgb = RGB.COLOR[value].copy()
        elif len(value) == 3:
            self.rgb = value.copy()
    
you should really do more checking, case conversion etc but you get the idea. To get at the class level variables in this new form you would have to do

Code: Select all

x = RGB.COLOR['red']
#c.f. your version
x = RGB.rgb_red
EDIT - fixed some missing self.s
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

User avatar
MrYsLab
Posts: 120
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Variable passed to class

Wed Oct 17, 2018 12:31 pm

I agree with the others that a dictionary is probably what you are looking for. Your example shows the use of class variables which could work. In case you are unfamiliar with class vs instance variables , here are a couple of articles that might help
:https://realpython.com/instance-class-a ... mystified/
https://realpython.com/python3-object-o ... ogramming/

If you really want a method in your class to retrieve and/or set the RGB values, you probably would want to use @property:
https://www.programiz.com/python-programming/property

Krafter
Posts: 22
Joined: Wed Jan 27, 2016 11:36 pm

Re: Variable passed to class

Wed Oct 17, 2018 9:25 pm

Ok. I'm going to add some snippets of my go and a little more description of what I want.

I have a script that reads the values from an Allen Bradley PLC using PyComm. I have a graphical interface with the PLC and the Pi will read an integer for each color that is generated from the PLC. One for red, one for green and one for blue. (among several other things)

party_lib.py

Code: Select all

class RGB():
	rgb_red = [100, 0, 0]
	rgb_grn = [0, 100, 0]
	rgb_blu = [0, 0, 100]
	rgb_yel = [100, 100, 0]
	rgb_mag = [100, 0, 100]
	rgb_cyn = [0, 100, 100]
	rgb_wht = [100, 100, 100]
	rgb_org = [100, 50, 0]
	rgb_pnk = [100, 0, 50]
I am then calling on this class to either give me a static color at will or a random color using other functions in the library.



micro_gui.py

Code: Select all

import party_lib
import party_2018

############### colors ##############################
red = party_lib.RGB.rgb_red
grn = party_lib.RGB.rgb_grn
blu = party_lib.RGB.rgb_blu
yel = party_lib.RGB.rgb_yel
mag = party_lib.RGB.rgb_mag
cyn = party_lib.RGB.rgb_cyn
wht = party_lib.RGB.rgb_wht
org = party_lib.RGB.rgb_org
pnk = party_lib.RGB.rgb_pnk

def Color_Set(value):
	global color
	global random 
	color = value
	random = 0
	
while 1:
	N7, F8 = PLC_Read(N7, F8)
	#print(N7)
	#print(F8)
	mode   = N7[0]
	color  = N7[1]
	random = N7[3]
	sock   = N7[4]
	bright = N7[5]
	delay  = F8[0]
	
	if sock == 1:
		party_2018.RGB([bright, 0, 0], bright)
		print(bright)
	elif sock == 2:
		party_2018.RGB([0, bright, 0], bright)
	elif sock == 3:
		party_2018.RGB([0, 0, bright], bright)

	if mode == 1 and random == 1 and color == 0 and num < cycles:
		random_1 = party_lib.Random_1(bright)
		party_lib.Mode_1(random_1, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 2 and color == 0 and num < cycles:
		random_2 = party_lib.Random_2()
		party_lib.Mode_1(random_2, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 1 and num < cycles:
		colors = party_lib.Set_Colors(red, red, red, red, red, red, red)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 2 and num < cycles:
		colors = party_lib.Set_Colors(grn, grn, grn, grn, grn, grn, grn)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 3 and num < cycles:
		colors = party_lib.Set_Colors(blu, blu, blu, blu, blu, blu, blu)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 4 and num < cycles:
		colors = party_lib.Set_Colors(yel, yel, yel, yel, yel, yel, yel)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 5 and num < cycles:
		colors = party_lib.Set_Colors(mag, mag, mag, mag, mag, mag, mag)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 6 and num < cycles:
		colors = party_lib.Set_Colors(cyn, cyn, cyn, cyn, cyn, cyn, cyn)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 7 and num < cycles:
		colors = party_lib.Set_Colors(wht, wht, wht, wht, wht, wht, wht)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 8 and num < cycles:
		colors = party_lib.Set_Colors(org, org, org, org, org, org, org)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 9 and num < cycles:
		colors = party_lib.Set_Colors(pnk, pnk, pnk, pnk, pnk, pnk, pnk)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	num = 0
The intent is to be able to set the brightness of each color in the class using the bright variable coming from the PLC. I am really, really concerned about power consumption since I'm using ~ 38 strands of LEDs for this project and I want to be able to control that by adjusting the duty cycle of my PWMs on the fly.

FYI: I have up to seven different channels of LED strips. That why you see something like "colors = party_lib.Set_Colors(pnk, pnk, pnk, pnk, pnk, pnk, pnk)" If I need to add my entire code I can but it definitely shows my noobness lol.

In the mean time, I will give a go at some of the suggestions here and see what I can make work.

Thanks for the replys.

User avatar
paddyg
Posts: 2227
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Variable passed to class

Wed Oct 17, 2018 9:47 pm

Looks quite complicated and it might be better to not suggest anything until you've digested and modified things in the light of comments... but it's probably worth pointing out that you will find life easier if you avoid repeating stuff whenever you can. i.e

Code: Select all

	elif mode ==1 and random == 0 and color == 1 and num < cycles:
		colors = party_lib.Set_Colors(red, red, red, red, red, red, red)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 2 and num < cycles:
		colors = party_lib.Set_Colors(grn, grn, grn, grn, grn, grn, grn)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 3 and num < cycles:
		colors = party_lib.Set_Colors(blu, blu, blu, blu, blu, blu, blu)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 4 and num < cycles:
		colors = party_lib.Set_Colors(yel, yel, yel, yel, yel, yel, yel)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 5 and num < cycles:
		colors = party_lib.Set_Colors(mag, mag, mag, mag, mag, mag, mag)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 6 and num < cycles:
		colors = party_lib.Set_Colors(cyn, cyn, cyn, cyn, cyn, cyn, cyn)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 7 and num < cycles:
		colors = party_lib.Set_Colors(wht, wht, wht, wht, wht, wht, wht)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 8 and num < cycles:
		colors = party_lib.Set_Colors(org, org, org, org, org, org, org)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 9 and num < cycles:
		colors = party_lib.Set_Colors(pnk, pnk, pnk, pnk, pnk, pnk, pnk)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
can be boiled down to

Code: Select all

clist = [red, grn, blue, yel, mag, cyn, wht, org, pnk]
...
	elif mode ==1 and random == 0 and num < cycles:
		colors = party_lib.Set_Colors(*[clist[color - 1] for i in range(7)])
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
and could obviously be simplified more by changing your Set_Colors() function and making your red, grn etc into a list in the first place.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Krafter
Posts: 22
Joined: Wed Jan 27, 2016 11:36 pm

Re: Variable passed to class

Wed Oct 17, 2018 10:05 pm

paddyg wrote:
Wed Oct 17, 2018 9:47 pm
Looks quite complicated and it might be better to not suggest anything until you've digested and modified things in the light of comments... but it's probably worth pointing out that you will find life easier if you avoid repeating stuff whenever you can. i.e

Code: Select all

	elif mode ==1 and random == 0 and color == 1 and num < cycles:
		colors = party_lib.Set_Colors(red, red, red, red, red, red, red)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 2 and num < cycles:
		colors = party_lib.Set_Colors(grn, grn, grn, grn, grn, grn, grn)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 3 and num < cycles:
		colors = party_lib.Set_Colors(blu, blu, blu, blu, blu, blu, blu)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 4 and num < cycles:
		colors = party_lib.Set_Colors(yel, yel, yel, yel, yel, yel, yel)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 5 and num < cycles:
		colors = party_lib.Set_Colors(mag, mag, mag, mag, mag, mag, mag)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 6 and num < cycles:
		colors = party_lib.Set_Colors(cyn, cyn, cyn, cyn, cyn, cyn, cyn)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 7 and num < cycles:
		colors = party_lib.Set_Colors(wht, wht, wht, wht, wht, wht, wht)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 8 and num < cycles:
		colors = party_lib.Set_Colors(org, org, org, org, org, org, org)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
	elif mode ==1 and random == 0 and color == 9 and num < cycles:
		colors = party_lib.Set_Colors(pnk, pnk, pnk, pnk, pnk, pnk, pnk)
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
can be boiled down to

Code: Select all

clist = [red, grn, blue, yel, mag, cyn, wht, org, pnk]
...
	elif mode ==1 and random == 0 and num < cycles:
		colors = party_lib.Set_Colors(*[clist[color - 1] for i in range(7)])
		party_lib.Mode_1(colors, delay, cycles)
		num = num + 1
and could obviously be simplified more by changing your Set_Colors() function and making your red, grn etc into a list in the first place.
I really, really appreciate your code example. I can follow it for the most part and I will be sure to make use of it but unfortunately I don't have much time to do a lot of cleanup right now. I'm facing a deadline that is coming up really quickly and I'm afraid I will run out of time. If what I am asking isn't possible with my current code then I'll just have to hard code the values until I have time to rewrite my library and gui which I intend to do anyway.

And if you think that code is "complicated" you should see the tkInter gui code that I was using before I went with what I'm using now lol. Nasty....

Krafter
Posts: 22
Joined: Wed Jan 27, 2016 11:36 pm

Re: Variable passed to class

Thu Oct 18, 2018 6:33 pm

Well the overall code isn't the prettiest but it works. I created an RGB dictionary and I can change the elements of each from an external variable. Pretty simple change really.

Thanks again for the tips.

party_lib.py

Code: Select all

RGB = {'red': [100 ,0 ,0], 'grn': [0, 100, 0], 'blu': [0, 0, 100]}
#etc..
micro_gui.py

Code: Select all

party_lib.RGB['red'][0] = bright
#etc...

User avatar
paddyg
Posts: 2227
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Variable passed to class

Thu Oct 18, 2018 8:47 pm

@Krafter, I should probably feel sheepish to say this now, (but maybe there's a lesson in not being bashful about exposing ugly code to the 'pundits' (all capable of writing ugly code themselves!)) If we had realized that's what you wanted to do we might have suggested you leave your code as it was and just

Code: Select all

party_lib.RGB.rgb_red[0] = bright
#etc...
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Krafter
Posts: 22
Joined: Wed Jan 27, 2016 11:36 pm

Re: Variable passed to class

Thu Oct 18, 2018 9:01 pm

paddyg wrote:
Thu Oct 18, 2018 8:47 pm
@Krafter, I should probably feel sheepish to say this now, (but maybe there's a lesson in not being bashful about exposing ugly code to the 'pundits' (all capable of writing ugly code themselves!)) If we had realized that's what you wanted to do we might have suggested you leave your code as it was and just

Code: Select all

party_lib.RGB.rgb_red[0] = bright
#etc...
:lol:

You are probably right. I'm a PLC programmer (ladder logic) by trade and I'm very particular on making code neat, slim and easy to follow. I only dabble in python. It's just a little embarrassing to show off code that I know is substandard lol. In fact, the code that I wrote is for an annual party and has been modified several times now. Maybe next year I will actually have time to rewrite it.

Thanks again.

Return to “Python”