Ren'Py Can someone explain to me list attributes?

lobotomist

Active Member
Sep 4, 2017
834
746
So i was watching this video:



And at around 3:45 she starts to assign attributes to icons. So coming from other programming languages. You would first create and icon class and then on the loop you would either use its constructor or fill it's fields; But in here she seems to be creating the fields for an object(?) on the fly.
I'm not sure at what am I looking at here, so I don't know how to even google it. Any help understanding it, especially with a name for the concept, so I can do my own research would be appreciated.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,285
[Ok, I warn first, I really risk to be really grumpy... So, I'll start by a big "what the fucking fuck", and hope it will calm me enough.]


I'll come back on your question below, but first this person is teaching something that she clearly don't know. If she've even read the documentation, she clearly haven't understood it ; but my guess is that she never read it.

Do not learn through her tutorials. I'm sure that she have only good intentions, and I recognize her one thing, I like the way she solve her problems. But, because there's a really big "but", it's also problem that she created by herself due to her lack of knowledge regarding Ren'Py ; she's going for a very long screen that should need a dozen of lines or something like this.

In no specific order:
  • She rely on two variables, one for the idle icon, one for the hover icon.
    Ren'Py documentation:
    auto
    Used to automatically define the images used by this button. This should be a string that contains %s in it. If it is, and one of the image properties is omitted, %s is replaced with the name of that property, and the value is used as the default for that property.
  • She's adding an index attribute to each entry in the list !!!
    Python:
    for i in range( 0, grid_size): # the 0 is implicit in her code
    list.append( [...]
    list[-1].index = i
    What is the interest to give an index value to something that is already indexed since put in a list ? You want to know what is the index of an entry of your list ? Assuming that this entry is temporarily stored in a variable named "whatever", just write this: index = list.index( whatever ).
    No need for an attribute for this.
  • She declared the screen with screen nameOfTheScreen:.
    I can't quickly find it back in the documentation, but it's clearly said that, a screen have to be declared with an arguments list even if there's no arguments ; therefore screen nameOfTheScreen():.
    This for backward compatibility reasons (so it can change with the 8.x branch). Without the arguments list, Ren'Py will not proceed the screen in the best way, and since they are Ren'Py's bottleneck, it's really not something you want for your game.
  • What she's doing in the "setup_icons" label should be done in an init block.
    It's constant values, they'll not change during the game, and they have absolutely no reason to be saved.
  • Positive point, she realized mid tutorial that what she initially did wouldn't works.
    She started to declare the icons using the "icons/[randValue].png" form, that wouldn't works the way she deal with the icons. Then she change it into "icons/{}.png".format( randValue ), that works the way she deal with the icons.
  • She create her constants in the "start" label.
    Code:
    label start:
    $ grid_size = 100
    $ icon_size = 50
    [...]
    She should have use define instead (since it's constants).
    Code:
    define grid_size = 100
    define icon_size = 50
  • She don't know that the screen statement exist.
    She put on her screen:
    Code:
    for i in range( grid_size ):
    $ xp = [computation]
    $ yp = [computation]
    image "whatever" xpos xp ypos yp
    
    python:
    if [row overflowing condition]:
    [pass to the next row]
    The exact same could have been done with:
    Code:
    grid 10 10:
    for i in range( 0, 100 ):
    image "whatever"
  • She use a screen statement outdated since I don't even know how many years but it's more than 5.
    She used image, this statement have been removed from the documentation years ago, and replaced by . It still works because Ren'Py is good at backward compatibility, but it doesn't mean that one should use it ; I'm not sure that the 8.x branch will effectively by backward compatible back to the first version of the screen language.

Well, I'll not do it all, there's nothing right in the two parts of her tutorial that I watched.
The screen she's building should be limited to those lines:
Code:
screen sameGame():
    grid 10 10:
        for i in range( 0, 100 ):
            fixed:
                add "background image for the cell"
                if tileMap:
                    imagebutton:
                        auto "icons/[i]_%s.png"
                        action [whatever]
It need a bit more to effectively reach the behavior she's trying to have, but I guess that something like this should be near to do it:
You don't have permission to view the spoiler content. Log in or register now.


Now for your question...

In Python, everything is an object, and objects have attributes. So far, it's like most Object Oriented Languages.
But Python add a particularity, objects are not static, they are dynamic. You can at anytime change their behavior by updating their definition. Not at class level, but really at object level.
And it's what she's doing here. She's just adding two attributes to the "Transform" object she created one line ago.

Demonstration code:
Python:
label start:

    $ regList = [ "a", "b", "c" ]
    $ altList = [ "d", "e", "f" ]
    $ altList.pickaboo = "Boo !"
    if not hasattr( regList, "pickaboo" ):
        "No, this is a regular list, it don't have an extra attribute."
        $ t = type( regList )
        "Type of regList is [t]"
    if hasattr( altList, "pickaboo" ):
        "[altList.pickaboo]"
        $ t = type( altList )
        "Type of altList is [t]"
        $ altList.pickaboo = "Bee"
        if altList.pickaboo == "Bee":
           "Is it a 'pickabee' now ?"
    "END"
Both list have the same type (a subclass of list defined by Ren'Py), but only one have an extra attribute. And this extra attribute can be addressed like any other attribute can.



Edit: Sorry, the list mess with the formatting in code blocks
Second Edit: Noticed a small typo in the full game code.
 
Last edited:
  • Like
Reactions: capital2500

lobotomist

Active Member
Sep 4, 2017
834
746
thanks!
this feels so counter intuitive from other languajes.

It's dissapointing that this tutorial is soo bad because it's still the best minigame tutorial i've ever seen. Do you perhaps have any recommendations for good learning resources? i feel like most code
I see out there is bad and that is from someone that is still learning python.
 

Sancho1969

Message Maven
Modder
Donor
Jan 19, 2020
12,382
48,059
Do you perhaps have any recommendations for good learning resources? i feel like most code
I see out there is bad and that is from someone that is still learning python.
If I may, always start with the OEM documentation imho, for example on lists .
 

Sancho1969

Message Maven
Modder
Donor
Jan 19, 2020
12,382
48,059
Regards. And I didn't miss it, I read it all. I consider anne O'nymous a mentor. I'm only adding that the official documentation shouldn't be overlooked as a learning resource. Best to you and yours.
 

lobotomist

Active Member
Sep 4, 2017
834
746
Yes you missed the point, the point was that coming from other languages this was counter intuitive, and I was trapped in a typical case of I don't know what I don't know, which I made very clear by stating that I didn't know what to look for, to which the answer was not lists but objects so even looking at the documentation on list which of course I did, I didn't found anything. Heck if you hadn't missed the point you would had seen that in the documentation that you linked, there is not a single mention of modifying objects on the fly.
Also I specifically requested a name for the concept so I could investigate on my own. That if you hadn't missed the point, meant that once I knew what I was looking for I could read the documentation about it.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,285
this feels so counter intuitive from other languajes.
It's just a question of habit. Each language have its particularities, and therefore all also have their counter intuitive parts.


Do you perhaps have any recommendations for good learning resources?
This section of the forum. Over the time we, because I'm not the only one, made it a gold mine for who take the time to browse through it.
And obviously there's also . But there, take care of the date at which the thread was started. It exist since a really long time, and any thread over three/four years old have to be considered as outdated. They can still contain interesting information, but when reading them keep in mind that Ren'Py perhaps have now a better way to do "this".
And the official documentation, that come with the SDK and can be found in the "doc" sub directory. Drag & drop the "index.html" file into your web browser, and you'll be able to browse through the doc as if it was a web site. As Sancho1969 said, it's also a good learning source. A bit obscure sometimes, and it lack of practical examples, but it's not really difficult to write your own ten testing lines of script to see if you understood how this or that works.


i feel like most code I see out there is bad and that is from someone that is still learning python.
Too many, yes, but not most. There's often better way to do, but globally it's not as disastrous than this particular tutorial. Yet, by itself it's not this disastrous, just a, way too much over complicated, way to do something relatively simple. It just add a, "but it's really not a reason to do it that way", at the end of the good old, "if it works it's not stupid".
The main issue is that Ren'Py is in constant evolution, with more or less ten updates by year. Therefore, something that was valid few years ago can perfectly be over complicated today.