changing class variables

This is the place for queries that don't fit in any of the other categories.

changing class variables

Postby Wommbatt » Mon Aug 12, 2013 4:07 am

Hey guys,

Here is a portion of my code so far for a silly rpg/text type game I'm fooling around with as a learning piece:

Code: Select all
import random

#These will eventually be in a separate file to import on startup
creature1 = {'Dict': 'creature1', 'Name': 'Skeleton', 'Level': 1, 'Hp': 4, 'Defense': 3, 'Attack': 9}
creature2 = {'Dict': 'creature2', 'Name': 'Minotaur', 'Level': 1, 'Hp': 4, 'Defense': 3, 'Attack': 9}
creature3 = {'Dict': 'creature3', 'Name': 'Ghoul', 'Level': 1, 'Hp': 4, 'Defense': 3, 'Attack': 9}

mobs = [creature1, creature2, creature3]

class Creature(object):
       """
       Your current enemy
       
       Attributes:
       Name: The name of your current enemy. (str)
       Level: The level of your current enemy. (int)
       Hp: The Hp of your current enemy. (int)
       Defense: The defense of your current enemy. (int)
       Attack: The attack of your current enemy. (int)
       """

       def __init__(self, name, level, hp, defense, attack):
          """
          Creature.__init__(name, level, hp, defense, attack) return None
          Set up the base attributes of the creature.
         
          Parameters:
          Name: The name of your current enemy. (str)
          Level: The level of your current enemy. (int)
          Hp: The Hp of your current enemy. (int)
          Defense: The defense of your current enemy. (int)
          Attack: The attack of your current enemy. (int)
          """
          self.name = name
          self.level = level
          self.hp = hp
          self.defense = defense
          self.attack = attack

#initial enemy setup
mob = random.choice(mobs)
enemy = Creature(mob.get('Name'), mob.get('Level'), mob.get('Hp'), mob.get('Defense'), mob.get('Attack'), mob.get('Dict'))


So the above is a portion of the setup code and it works just fine I'm happy to say. What I want to do next is to have a function that allows me to change what the enemy is and obviously it's stats. To do this I've tried the following two codes but neither work.

Code: Select all
       def new_enemy(self):
              mob = random.choice(mobs)
              enemy = Creature(mob.get('Name'), mob.get('Level'), mob.get('Hp'), mob.get('Defense'), mob.get('Attack'))

def new_enemy():
       mob = random.choice(mobs)
       enemy = Creature(mob.get('Name'), mob.get('Level'), mob.get('Hp'), mob.get('Defense'), mob.get('Attack'), mob.get('Dict'))


The first one is included inside the creature class and the second is an entirely separate function. I believe the second option fails due to it possibly setting a new local variable inside itself. But I'm not certain why the first option fails.

And so here are my questions:
1) Am I on the right track with my train of thought?
2) How can I actually accomplish a class variable change via a function? I can do it manually, but I really want it automated by the end.

As always thanks in advance 8D
-wommbatt
Wommbatt
 
Posts: 24
Joined: Thu Jun 13, 2013 2:15 pm

Re: changing class variables

Postby DrakeMagi » Mon Aug 12, 2013 2:13 pm

your new_enemy function
Code: Select all
def new_enemy():
    mob = random.choice(mobs)
    return Creature(mob.get('Name'), mob.get('Level'), mob.get('Hp'), mob.get('Defense'), mob.get('Attack'))

enemy = new_enemy()

if you want mob.get('Dict') then you will have to add it to init method
Code: Select all
def __init__(self, name, level, hp, defense, attack,dict_=None):


here another option
Code: Select all
import random

LORE = [{'Name':'Skeleton', 'Level':1, 'HP':4, 'Defense':3, 'Attack':9},
        {'Name':'Minotaur', 'Level':1, 'HP':4, 'Defense':3, 'Attack':9},
        {'Name':'Ghoul', 'Level':1, 'HP':4, 'Defense':3, 'Attack':9}
]

class Creature(object):
    def __init__(self, creature_dict):
        self.name = creature_dict.get('Name', 'Unknown')
        self.level = creature_dict.get('Level', 1)
        self.hp = creature_dict.get('Hp', 1)
        self.defense = creature_dict.get('Defense', 1)
        self.attack = creature_dict.get('Attack', 1)

       
enemy = Creature(random.choice(LORE))
print enemy.name

enemy = Creature(random.choice(LORE))
print
print enemy.name
Linux: won't find windows here.
Linux: the choice of a GNU generation.
https://github.com/DrakeMagi
DrakeMagi
 
Posts: 113
Joined: Sun May 12, 2013 8:36 pm

Re: changing class variables

Postby Wommbatt » Mon Aug 12, 2013 5:33 pm

That is a much better looking bit of code than what I've been using lol, thanks 8D

Unfortunately it doesn't seem to do what I'm looking for. The setup is perfect, but when I go to reset the stats with "new_enemy()". I get this:

Code: Select all
>>>
Minotaur
>>> new_enemy()
Ghoul
>>> print(enemy.name)
Minotaur
>>>


What is happening in there? Shouldn't this:
Code: Select all
def new_enemy():
        enemy = Creature(random.choice(LORE))
        print(enemy.name)

Set the "enemy" var with the new creature's stats?
Wommbatt
 
Posts: 24
Joined: Thu Jun 13, 2013 2:15 pm

Re: changing class variables

Postby DrakeMagi » Mon Aug 12, 2013 8:03 pm

All you needed to do was add reset method.
Curious why are you using random.choice if you wanted to reset enemy ?

Code: Select all
import random

LORE = [{'Name':'Skeleton', 'Level':1, 'HP':4, 'Defense':3, 'Attack':9},
        {'Name':'Minotaur', 'Level':1, 'HP':4, 'Defense':3, 'Attack':9},
        {'Name':'Ghoul', 'Level':1, 'HP':4, 'Defense':3, 'Attack':9}
]

class Creature(object):
    def __init__(self, creature_dict):
        self.creature_dict = creature_dict
        self.reset()
       
    def reset(self):
        self.name = self.creature_dict.get('Name', 'Unknown')
        self.level = self.creature_dict.get('Level', 1)
        self.hp = self.creature_dict.get('HP', 1)
        self.defense = self.creature_dict.get('Defense', 1)
        self.attack = self.creature_dict.get('Attack', 1)
     
    def __repr__(self):
        py_tuple = self.name, self.level, self.hp, self.defense, self.attack
        return '{0}: Level:{1}, HP:{2}, Def:{3}, Att:{4}'.format(*py_tuple)

       
enemy = Creature(random.choice(LORE))
print enemy

enemy.hp -= 2
print
print enemy

enemy.reset()
print
print enemy
Linux: won't find windows here.
Linux: the choice of a GNU generation.
https://github.com/DrakeMagi
DrakeMagi
 
Posts: 113
Joined: Sun May 12, 2013 8:36 pm

Re: changing class variables

Postby DrakeMagi » Mon Aug 12, 2013 11:12 pm

you also can just use tuples
Code: Select all
import random

# tuple layout (Name, Level, HP, Defense, Attack)
LORE = (('Skeleton', 1, 4, 3, 9),
        ('Minotaur', 1, 4, 3, 9),
        ('Ghoul', 1, 4, 3, 9),
        ('Ghast', 1, 4, 3, 9),
        ('Zombies', 1, 4, 3, 9),
        ('Mummy', 2, 5, 5, 10)
)

class Creature(object):
    def __init__(self, creature_tuple):
        self.creature_tuple = creature_tuple
        self.reset()
       
    def reset(self):
        self.name = self.creature_tuple[0]
        self.level = self.creature_tuple[1]
        self.hp = self.creature_tuple[2]
        self.defense = self.creature_tuple[3]
        self.attack = self.creature_tuple[4]
       
    def __repr__(self):
        py_tuple = self.name, self.level, self.hp, self.defense, self.attack
        return '{0}:(Level:{1}, HP:{2}, Def:{3}, Att:{4})'.format(*py_tuple)

       
enemy = Creature(random.choice(LORE))
print(enemy)

enemy.hp -= 2
print(enemy)

# enemy reset
enemy.reset()
print(enemy)

# enemy = new enemy
enemy = Creature(random.choice(LORE))
print(enemy)
Linux: won't find windows here.
Linux: the choice of a GNU generation.
https://github.com/DrakeMagi
DrakeMagi
 
Posts: 113
Joined: Sun May 12, 2013 8:36 pm

Re: changing class variables

Postby micseydel » Mon Aug 12, 2013 11:27 pm

Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1387
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: changing class variables

Postby Wommbatt » Tue Aug 13, 2013 12:16 pm

When I said reset what I meant was to grab a new enemy from the LORE list, not reset the stats to their original numbers. I also wasn't even aware there was a self.reset() function so I didn't realize my terminology was confusing.

edit:
Back to my original question though. How come I can set a new enemy from the LORE list when I manually type the code in, but when I put that same code into function form it doesn't set?
Wommbatt
 
Posts: 24
Joined: Thu Jun 13, 2013 2:15 pm

Re: changing class variables

Postby DrakeMagi » Tue Aug 13, 2013 5:56 pm

class method are what you want except for builtin methods which always are __keyword__.
Code: Select all
enemy = random.choice(LORE) # global variable

def new_enemy():
    # global variable remains unchange
    enemy = random.choice(LORE) # local variable of this function
    # local variables are destroyed on exiting function

def new_enemy_global():
    global enemy # allow global variable to be change
    enemy = random.choice(LORE)

more options
Code: Select all
import random

# tuple layout (Name, Level, HP, Defense, Attack)
LORE = (('Skeleton', 1, 4, 3, 9),
        ('Minotaur', 1, 4, 3, 9),
        ('Ghoul', 1, 4, 3, 9),
        ('Ghast', 1, 4, 3, 9),
        ('Zombies', 1, 4, 3, 9),
        ('Mummy', 2, 5, 5, 10)
)

class Creature(object):
    def __init__(self):
        self.new_enemy()
       
    def new_enemy(self):
        self.creature_tuple = random.choice(LORE)
        self.name = self.creature_tuple[0]
        self.level = self.creature_tuple[1]
        self.hp = self.creature_tuple[2]
        self.defense = self.creature_tuple[3]
        self.attack = self.creature_tuple[4]
       
    def __repr__(self):
        py_tuple = self.name, self.level, self.hp, self.defense, self.attack
        return '{0}:(Level:{1}, HP:{2}, Def:{3}, Att:{4})'.format(*py_tuple)
       
enemy = Creature()
print(enemy)

# enemy = new enemy
enemy.new_enemy()
print(enemy)
# or enemy = new enemy
enemy = Creature()
print(enemy)
Linux: won't find windows here.
Linux: the choice of a GNU generation.
https://github.com/DrakeMagi
DrakeMagi
 
Posts: 113
Joined: Sun May 12, 2013 8:36 pm

Re: changing class variables

Postby micseydel » Tue Aug 13, 2013 6:14 pm

Global variables are typically recommended against.
Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1387
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: changing class variables

Postby Wommbatt » Wed Aug 14, 2013 11:06 am

Oh my goodness, what a learning experience. Thanks so much Drake 8D

micseydel wrote:Global variables are typically recommended against.


I know using them like that is frowned upon. That combined with how the namespace scoping works led me to the class idea. Can't wait to be more proficient haha
Wommbatt
 
Posts: 24
Joined: Thu Jun 13, 2013 2:15 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 2 guests