Initialising a list of a class within a class

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Iylae
Regular
Posts: 73
Joined: Sat Jan 09, 2016 6:57 am
Location: Cornwall, UK
Contact:

Initialising a list of a class within a class

#1 Post by Iylae » Sat Jan 09, 2016 7:14 am

Hi all,

As much as I'd love for my first post to not be a question, here it is:

I'm struggling with properly initialising lists and classes to build a data structure.

Trait is a custom class containing a name (for now)
Char is a custom class which should have a list of Trait (and other vars)

The only line in the start label is to find the name of the first trait on the Char prax.

I've been going around in circles for the past few hours, but cannot find anything to explain where I'm going wrong with this. Thanks for any help!

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 22, in script
    "[prax.traits[0].name]"
AttributeError: Trait instance has no attribute 'name'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 22, in script
    "[prax.traits[0].name]"
  File "E:\renpy-6.99.8-sdk\renpy\ast.py", line 603, in execute
    renpy.exports.say(who, what, interact=self.interact)
  File "E:\renpy-6.99.8-sdk\renpy\exports.py", line 1121, in say
    who(what, interact=interact)
  File "E:\renpy-6.99.8-sdk\renpy\character.py", line 819, in __call__
    what = what_pattern.replace("[what]", sub(what, translate=translate))
  File "E:\renpy-6.99.8-sdk\renpy\character.py", line 801, in sub
    return renpy.substitutions.substitute(s, scope=scope, force=force, translate=translate)[0]
  File "E:\renpy-6.99.8-sdk\renpy\substitutions.py", line 229, in substitute
    s = formatter.vformat(s, (), kwargs)
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 563, in vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 585, in _vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 652, in get_field
AttributeError: Trait instance has no attribute 'name'

Windows-8-6.2.9200
Ren'Py 6.99.8.959
test 0.0

Code: Select all

init python:
    
    class Trait:
        def __init__(self, name="Genius"):
            self.name = name
            
    class Char:
        def __init__(self,  name="unknown", age="unknown", traits="unknown"):
            self.name = name
            self.age = age
            self.traits = traits
            
init:
    $ prax = Char(
        name = "Prax", 
        age = 35,
        traits = [Trait()],
        )
    
label start:
    
    "[prax.traits[0].name]"
Last edited by Iylae on Sat Jan 09, 2016 7:38 am, edited 1 time in total.

User avatar
Evildumdum
Regular
Posts: 191
Joined: Sun Jan 18, 2015 8:49 am
Projects: ApoclypseZ
Contact:

Re: Initialising a list of a class within a class

#2 Post by Evildumdum » Sat Jan 09, 2016 7:34 am

I can see a couple of potential problems. Though i'm only certain on how to fix one or two. Others will have to clarify the others. The first is in your label start.

Code: Select all

 "[prax.traits[0].name]"
Why are you trying to call two variables in the same string? Separate them.

Code: Select all

"[prax.traits[0]] [prax.name]"
Secondly i'm not sure you are inputting your lists in the right format when creating your class instance. However having never tried doing it that way i cant give proper advice on that. You might want to look further into that though.

Third, your class instance doesn't need to be that complicated. Just do.

Code: Select all

init:
    $ prax = Char("Prax", 35, [Trait()])
Lastly, if you are going to have other classes inherit from an existing class, you need to make it an object. Easy enough to do.

Code: Select all

class Trait(object):
        def __init__(self, name="Genius"):
            self.type = type
Last edited by Evildumdum on Sat Jan 09, 2016 7:39 am, edited 1 time in total.
"If at first you don't succeed, try hitting it with a shoe."

User avatar
Iylae
Regular
Posts: 73
Joined: Sat Jan 09, 2016 6:57 am
Location: Cornwall, UK
Contact:

Re: Initialising a list of a class within a class

#3 Post by Iylae » Sat Jan 09, 2016 7:39 am

I made a bit of a mistake in my code which I've edited now:

Code: Select all

    class Trait:
        def __init__(self, name="Genius"):
            self.name = name
Evildumdum wrote:Why are you trying to call two variables in the same string? Separate them.
I want the name of the trait, not the name of the char.

Evildumdum wrote:Lastly, if you are going to have other classes inherit from an existing class, you need to make it an object. Easy enough to do.

Code: Select all

class Trait(object):
        def __init__(self, name="Genius"):
            self.type = type
That was the issue, it works fine when adding the object parameter to the class definition.

So the functional code is:

Code: Select all

init python:
    
    class Trait(object):
        def __init__(self, name="Genius"):
            self.name = name
            
    class Char:
        def __init__(self,  name="unknown", age="unknown", traits="unknown"):
            self.name = name
            self.age = age
            self.traits = traits
            
init:
    $ prax = Char(
        name = "Prax", 
        age = 35,
        traits = [Trait()],
        )
    
label start:
    
    "[prax.traits[0].name]" # prints "Genius"
Though that's not to say I'm doing this in the "best" way.


Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot]