[Tutor] Set and get class members

Peter Otten __peter__ at web.de
Wed Jul 21 04:02:02 EDT 2021


On 21/07/2021 08:27, Phil wrote:
> On 19/7/21 8:35 pm, Alan Gauld via Tutor wrote:
>>
>> My personal recommendation is to keep it as simple as possible.
>> Access the state attribute directly and have the LEDs stored
>> in a global list variable.
> 
> This is what has been suggested;
> 
>          self.leds = list()

This is *not* Alan's suggestion. "self" shouts "part of an (LED) instance.

>          for i in range(8):
>              self.leds[i].self.state = False # this is not correct. If 
> state is True then the LED is on.
>              self.leds.append(Led((50 + (i * 30), 50))) # this results 
> in 8 equally spaced LEDs
> 
> Is this what you have in mind?
> 
> No matter how I try to set the state of a LED the error message is:
> 
> IndexError: list assignment index out of range
> 
> This is how I came up with a working solution in C++ using set methods 
> quite some time ago.
> 
>    l = new Led[num_leds];
> 
> 
>    for (int i = 0; i < num_leds; i++)
>    {
>      l[i] = new Led(60 + (i * 40), 120);
>      l[i].setState(false);
>      l[i].setLedSize(30);
>      l[i].setOnColour(green);
>      l[i].setOffColour(black);
>    }
> 
> All I need to do is set the state of say LED[3].
> 
> I've been sitting in a broken down motorhome for most of the day and my 
> head is in a bit of a spin which could be why I'm having trouble with 
> this simple problem.

The difference is that in Python usually you do not preallocate the list.

Instead of

leds = [None] * num_leds
for i in range(num_leds):
     leds[i] = Led(...)


you better write

leds = []
for i in range(num_leds):
     leds.append(Led(...))


or with a list comprehension:

leds = [Led(...) for i in range(num_leds)]

In both C++ and Python it would be better to use the 
constructor/initializer to specify the attributes:

red = "red"
black = "black"
green = "green"

class Led:
     def __init__(
         self, pos, state=False, size=50,
         on_color=green, off_color=black
     ):
         self.pos = pos
         self.state = state
         self.size = size
         self.on_color = on_color
         self.off_color = off_color


num_leds = 8
leds = []
for i in range(num_leds):
     leds.append(
         Led((60 + (i * 40), 120))
     )

# modify a specific LED
leds[3].on_color = red

To set all states you can write a helper function

def set_states(leds, state):
     for led in leds:
         led.state = state

# switch on all LEDs
set_states(leds, True)


# switch off all green LEDs
set_states((led for led in leds if led.on_color == green), False)

Once you are a bit more fluent in Python and understand the difference 
between instance, class and global namespace you can wrap the leds list 
into a class as suggested by dn and turn set_states into a method.
For now I suggest that you stick to the simple approach shown above.



More information about the Tutor mailing list