#๐Ÿ”’ Understanding class structure

50 messages ยท Page 1 of 1 (latest)

keen vigil
#

I am determined to understand this XD

untold pathBOT
#

@keen vigil

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

keen vigil
#
trespasser_character = {
    'character_name': 'name',
    'player_name': 'Roll&D20',
    'words_to_live_by': 'Sure hope this works!',

    'attributes' :{
        'might': 0,
        'agility': 0,
        'intellect': 0,
        'spirit': 0,
        'key_attribute':'',
        'skill': 1,
        'skill_die': '1d6',
        'acrobatics': False,
        'alchemy': False,
        'athletics': False,
        'crafting': False,
        'folklore': False,
        'letters': False
    },
    'health&healing': {
        'HP': 0,
        'recovery_dice': 0,
        'endurance': 0,
        'injury1': {
            'injury_name': '',
            'injury_clock': '',
            'injury_effect': ''
        },
        'injury2': {
            'injury_name': '',
            'injury_clock': '',
            'injury_effect': ''
        },
        'injury3': {
            'injury_name': '',
            'injury_clock': '',
            'injury_effect': ''
        }
    },
    'advancement':{
        'level':1,
        'xp':{
            'xp_current':0,
            'xp_next':10
        },
        'lineage':'human',
        'past_life':'random',
        'calling':'',
        'craft1':'',
        'craft2':'',
        'craft3':'',
        'alignment1':{
            'affirm_count':0,
            'deny_count':0
        },'alignment2':{
            'affirm_count':0,
            'deny_count':0
        }
    },
    'features':{
        'classfeature1': '',
        'classfeature2': '',
        'classfeature3': '',
        'classfeature4': '',
        'craft1_talent1':'',
        'craft1_talent2': '',
        'talent3':'',
        'enhancement4':'',
        'craft2_talent1': '',
        'craft2_talent2': '',
        'talent5': '',
        'talent6': '',
        'enhancement7': '',
        'craft3_talent1': '',
        'craft3_talent2': '',
        'talent8': '',
        'talent9': '',
        'enhancement10':'',
    },
#
'combat_values':{
        'initiative':'agility+skill',
        'accuracy':'key_ability + skill'
    }
#

I initially grouped my data into a dictionary as it made intuitive sense to me. I think I understand what and why classes are better in this regard than a dictionary, but I don't understand to be confident

woeful quarry
#

what do you want to understand abou tthis?
A) I would assume it's your own code, so why don't you understand your own code?
and B) this is just a big, nested dict

#

Ah nvm, you asked an actual question now

dense geyser
#

I mean, what do you think you'd get from using classes here that you don't get from using dicts like you already are?

#

not saying there aren't any possible reasons, just that it's not always the case that classes are better

keen vigil
#

I am digitizing a ttrpg chracter sheet as a personal project, and want to expand it into a discord bot in future projects.

While I was figuring out how I wanted to store information in a nested format I was told that I should be using classes instead so I can use inheritance/other things in future bits

woeful quarry
keen vigil
#

do I have this right:

this large dict is a shell. when I create a character file I'll pass this shell in , then run functions that alter it (for example, your HP is determined by your might, so I would run a function that does the HP math for your level and reasign the HP value to the correct ammount.)

#

I want to make a UI in discord that would allow you to make an attack, for example, so it would run the attack function and pull in the character's key attribute

woeful quarry
#

this large dict is a shell
If we use the usual meaning of a "shell", which would be basically your terminal (or cmd if you use Windows), then this doesn't really make sense. Soo... not sure what you mean by "shell".

keen vigil
#

empty structure that I fill in specific meaning

#

almost all of the values here are empty or 0 and should be filled in

woeful quarry
#

I have a feeling you'll have an easier time using classes tbh.

keen vigil
woeful quarry
#

What doesn't make sense about it? Have you read up on what they are?

keen vigil
#

I included my current code so I can ask examples of how to shift the dict to a class.

keen vigil
woeful quarry
#

How I used to learn it:
A class is a blueprint, i.e. it's the manual for how you need to build something.
An object on the other hand is a specific instance that was constructed using one of those blueprints.
Naturally you can have many constructed instances while just having a single blueprint. For example if we say that we have the blueprint of a car, then we would have a class Car, that would then have attributes/properties describing that car (for example a brand, the amount of wheels, etc). Obviously we can build many (different) cars using just this single blueprint.

keen vigil
#

that makes sense

#

so my code above will be getting turned into a class, and when I make an actual character sheet from it I will be making an object that calls its structure from the class?

woeful quarry
# keen vigil so my code above will be getting turned into a class, and when I make an actual ...

Here, take this as an example:

class Car:
    brand: str
    number_of_wheels: int
    build_year: int

    def __init__(self, brand: str, number_of_wheels: int, build_year: int):
        self.brand = brand
        self.number_of_wheels = number_of_wheels
        self.build_year = build_year

    def print_data(self):
        print(f"This is a car from {self.brand}. It has {self.number_of_wheels} many wheels and was built in {self.build_year}")


my_bmw: Car = Car("BMW", 4, 2010)
my_porsche: Car = Car("Porsche", 4, 2014)
my_semi: Car = Car("Scania", 10, 2009)

my_bmw.print_data()
my_semi.print_data()
my_porsche.print_data()
keen vigil
#

or should I be breaking up my sections like attributes, health&healing, etc into seperate classes?

woeful quarry
keen vigil
#

yeah ๐Ÿ˜… it was getting large enough that I was sure I had commited some programming sin

#

how would I structure the nests like I did here?

'injury1': {
            'injury_name': '',
            'injury_clock': '',
            'injury_effect': ''
woeful quarry
keen vigil
#

would I make that a child class?

woeful quarry
#

Why would you need child classes?

keen vigil
woeful quarry
#

You don't even (really) know classes and want to jump to inheritance already? Let alone that you probably shouldn't need it

woeful quarry
keen vigil
#

I don't want to ๐Ÿคฃ people keep giving advice and I'm trying not to be the difficult student who keeps saying "well I want to do it this way"

I want to complete the project the 'right' way (small chunks, learn one thing at a time, etc)

keen vigil
#

I was also told to use the basemodel package from pydantic, or use dataclasses to help structure things.

Is that something I should do now or is a better first step to construct my 5-6 classes that make up character data and then come back here with questions?

woeful quarry
# keen vigil becuase that what I thought a nested class was called?

You just do stuff like this:

class A:
    value: int
    
    def __init__(self, value):
        self.value = value

class B:
    description: str
    a_one: A
    a_two: A

    # imagine the init

class C:
    text: str
    b: B

    # imagine the init

my_a_one = A(3)
my_a_two = A(4)
my_b = B("some description", my_a_one, my_b_two)
my_c = C("some_text", my_b)

# now we can call it:
print(f"{my_c.b.a_two.value = }")
#

It's also recommend to put each class in it's own file and to just import what you need then

keen vigil
keen vigil
#

awesome!

woeful quarry
#

The plain names may be confusing, if you choose more sensible names it'll make sense more easily

keen vigil
#

I'll give it a shot and ping you once I have something working!

keen vigil
woeful quarry
# keen vigil final question: I've been told to use basemodel/dataclass descriptors to make m...

It's a cool feature and, depending on what you need could be very helpful, but
A) since you're brand new to classes you should just focus on getting familiar with the most basic kind of class and
B) these features come with a few "drawbacks", like for example immutability... it could break your code and it'll work with regular classes regardless, so, just stick to the regular classes

untold pathBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.