Show a dictionary inside a class created by an external function

Asked

Viewed 115 times

0

I’m trying to create an RPG plug simulator, but I’m having trouble properly displaying the labels. Creation runs through the function criaPersonagem() creating an object in dictionary format (at least I tried to create it like this). Then when I call the object in a function print only the values and not the labels appear, I am wrong in the own print or within the function criaPersonagem()?

personagens = ["",]

class personagem:
    def __init__(self,name,genre,race,level,power,damage,health,healthRate,insanity,corruption,strength,agility, intellect, will,perception,defense,size,movement):
        self.name = name
        self.genre = genre
        self.race = race
        self.level = level 
        self.power = power
        self.damage = damage
        self.health = health
        self.healthRate = healthRate
        self.insanity = insanity
        self.corruption = corruption
        self.strength = strength
        self.agility = agility
        self.intellect = intellect
        self.will = will
        self.perception = perception
        self.defense = defense
        self.size = size
        self.movement = movement

    def exibePersonagem(self):

        print(self.name,self.genre,self.race,self.level,self.power,self.damage,self.health,self.healthRate,self.insanity,self.corruption,self.strength,self.agility, self.intellect, self.will,self.perception,self.defense,self.size,self.movement)



def criaPersonagem():
    global personagens
    perso = {}
    perso["name"] = input("Qual o nome do personagem?")
    perso["genre"] = input("Qual o genero do personagem?")
    perso["race"] = input("Qual a raça do personagem?")
    perso["level"] = 0
    perso["power"] = 0
    perso["damage"] = 0
    perso["insanity"] = 0
    perso["corruption"] = 0
    if perso["race"] == "humano":
        perso["strength"] = 10
        perso["agility"] = 10
        perso["intellect"] = 10
        perso["will"] = 10

        perso["perception"] = perso["intellect"]
        perso["defense"] = perso["agility"]
        perso["health"] = perso["strength"]
        perso["healthRate"] = perso["health"]/4
        perso["size"] = 1
        perso["movement"] = 10



    values = personagem(perso["name"], perso["genre"], perso["race"], perso["level"],perso["power"],perso["damage"],perso["health"],perso["healthRate"],perso["insanity"],perso["corruption"],perso["strength"],perso["agility"], perso["intellect"], perso["will"],perso["perception"],perso["defense"],perso["size"],perso["movement"])
    personagens.append(values)


criaPersonagem()
print(personagens[1].exibePersonagem())
  • What would be the "labels" you quote?

  • 1

    The keys to the dictionary.

3 answers

2

From version 3.6 of Python you can use dataclasses for this type of data structure.

from dataclasses import dataclass

@dataclass
class Character:
    name: str
    genre: str
    race: str

The dataclass will generate for you some methods that are common in this structure; one of them, and the main one for this problem, is the method __init__, which is created with all the fields you set. Less manual work for us.

Only with the above mentioned class could we do:

woss = Character(name='Woss', genre='male', race='god')

print(woss)

The exit would be:

Character(name='Woss', genre='male', race='god')

Which follows the class name format, followed with the fields and values between parentheses. You can customize the output by setting the method __str__ of your class:

@dataclass
class Character:
    name: str
    genre: str
    race: str

    def __str__(self):
        return (
            'Dados do personagem:\n'
            f'Nome: {self.name}\n'
            f'Gênero: {self.genre}\n'
            f'Raça: {self.race}\n'
        )

See working on Repl.it

In this case, the exit of print(woss) would be:

Dados do personagem:
Nome: Woss
Gênero: male
Raça: god

And with this you can automate several things. For example, create a function that asks the user for all the character’s data and creates it:

def create_character():
    print('New character:')

    info = {}

    for attribute, _type in Character.__annotations__.items():
        value = input(f'{attribute}: ')
        info[attribute] = _type(value)

    return Character(**info)

So you could do:

>>> print(create_character())

New character:
name: Woss
genre: Male
race: God

Dados do personagem:
Nome: Woss
Gênero: Male
Raça: God

See working on Repl.it

Behold:

inserir a descrição da imagem aqui

  • Wow, ball show!!

  • 1

    And you can easily implement all methods in a way that fits the dataclass definition, so if you want to change the structure, you could just change the fields definition - similar as the function was made create_character, that makes the reflection of the class to verify which are the fields and asks the user.

  • Caraca, it became much more practical! Now I see how it pays to leave the sloth aside and leave the comfort zone to update in the language. Even more in Python!

  • @Édergarcia And we can still greatly improve this code.

  • 1

    @Édergarcia Here, https://repl.it/@acwoss/Expertimportantanimatronics, for example, I can set default values for some of the class fields and not ask the user when creating the character. As I said, we can still go far :D

  • Very mass @Andersoncarloswoss this information was a "watershed". Thank you for sharing your experience!

  • That’s cool, I didn’t know this module, Thanks for sharing this.

Show 2 more comments

0

If you can help again, thank you very much and I think that after that I will fully understand the missing logic. I went back to tinkering with the code at night and based on what @Anderson went through I tried to better understand the dataclasses but I didn’t understand the library itself very well, but what was used in the code I understood.

I was then trying to apply a function to modify attributes based on race during creation however I am not able to increment and do the values assignment correctly in the updateByRace() function, as I could solve it?

I tried to experience a storage of this object in a list to be able to call it more easily later but when I tried to do it in append it seems that it turned into a common dictionary, losing the attributes of an object as well as how to solve it?

tomorrow I should publish the project in git, that as soon as these 2 to-do the creation of the other breeds chip will be quick to finish.

from dataclasses import dataclass,fields,MISSING




personagens = [""]

@dataclass
class character:
    name : str
    genre : str
    race : str
    health : int
    recoveryRate : int = 0
    strength : int = 0
    agility : int = 0
    intellect : int = 0
    will : int = 0
    perception : int = 0
    defense : int = 0
    size : int = 0
    movement : int
    level : int = 0
    power : int = 0
    damage : int = 0
    insanity : int = 0
    corruption : int = 0


    def updateByRace(self):
        if self.race == "humano":
            self.strength = 10
            self.agility = 10
            self.intellect = 10
            self.will = 10

            self.perception = self.intellect
            self.defens = self.agility
            self.health = self.strength
            self.recoveryRate = (self.health)/4
            self.size = 1
            self.movement = 10


    def __str__(self):
        return(
            'Ficha do character: \n\n'
            f'Name : {self.name} | '
            f'Genre : {self.genre} | '
            f'Race : {self.race} \n'
            f'Level : {self.level} |'
            f'Power : {self.power} \n'
            f'Damage : {self.damage} |'
            f'Health : {self.health} | '
            f'recoveryRate : {self.recoveryRate} \n'
            f'STR : {self.strength} | '
            f'INT : {self.intellect} | '
            f'AGI : {self.agility} | '
            f'Will : {self.will} \n'
            f'Perception : {self.perception} | '
            f'Defense : {self.defense} | '
            f'Movement : {self.movement} | \n'
            f'Size : {self.size} | '
            f'Insanity : {self.insanity} | '
            f'Corruption : {self.corruption} \n'

    )






def create_character():
    print('New character:')

    info = {}

    for field in fields(character):
        if field.default == MISSING:
            value = input(f'{field.name}: ')
            info[field.name] = field.type(value)

    character.updateByRace()
    return character(**info)

print(create_character())

0

I understand that the label is the key to the dictionary.

I made few changes:

1) I removed the list personagens that "I was left".

2) I replaced the method exibePersonagem by function exibirPersonagem which takes a dictionary as a parameter personagem and prints your keys and values.

Follows the code:

class personagem:

    def __init__(self, name, genre, race, level, power, damage, health, healthRate,
                 insanity, corruption, strength, agility, intellect, will, perception,
                 defense, size, movement):        
        self.name = name
        self.genre = genre
        self.race = race
        self.level = level 
        self.power = power
        self.damage = damage
        self.health = health
        self.healthRate = healthRate
        self.insanity = insanity
        self.corruption = corruption
        self.strength = strength
        self.agility = agility
        self.intellect = intellect
        self.will = will
        self.perception = perception
        self.defense = defense
        self.size = size
        self.movement = movement


def exibirPersonagem(personagem):
    print("\n--- Info ---\n")
    for k in personagem:        
        print(k, personagem.get(k))


def criarPersonagem():    
    perso = {}
    perso["name"] = input("Qual o nome do personagem? ")
    perso["genre"] = input("Qual o genero do personagem? ")
    perso["race"] = input("Qual a raça do personagem? ")
    perso["level"] = 0
    perso["power"] = 0
    perso["damage"] = 0
    perso["insanity"] = 0
    perso["corruption"] = 0

    if perso["race"] == "humano":
        perso["strength"] = 10
        perso["agility"] = 10
        perso["intellect"] = 10
        perso["will"] = 10

        perso["perception"] = perso["intellect"]
        perso["defense"] = perso["agility"]
        perso["health"] = perso["strength"]
        perso["healthRate"] = perso["health"]/4
        perso["size"] = 1
        perso["movement"] = 10

    return perso    


jogador1 = criarPersonagem()

exibirPersonagem(jogador1)

Exit:

Qual o nome do personagem? Apuleio
Qual o genero do personagem? Ladino
Qual a raça do personagem? humano

--- Info ---

name Apuleio
genre Ladino
race humano
level 0
power 0
damage 0
insanity 0
corruption 0
strength 10
agility 10
intellect 10
will 10
perception 10
defense 10
health 10
healthRate 2.5
size 1
movement 10
  • And you didn’t even use the class personagem that he created?

  • Jeez, truth!!

  • then the idea of that remaining list was to store the objects in it, without having to declare a new object by a variable that I put the name.

  • You would have to see which rule to define the skills by drawing the values, otherwise it will be very annoying using 18 inputs. rsrs

  • Is that in this case I am creating based on the RPG Shadow of the Demon Lord, that at least these status are closed kkkk

  • I’m trying to change the code a little bit here but I’m not succeeding

  • I am creating even to assist in a session of my own that I will do, so to n have to declare new objects by code I want to automate with the function to be adding automatically and then I call by index.

  • I will try to help respecting the scope of the question. It would be nice to take this project to Github. What do you think?

  • As soon as I finish I’ll post it to git, right at the beginning. for now I have plans to create functions to help in control and chip creation and combat.

  • Éder thanks for assisting also.

  • Cool @pydoni also short RPG, it will be a pleasure to contribute in some way.

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.