Hi Kate, and welcome!

My replies are interleaved between your questions.


On Fri, Sep 19, 2014 at 04:25:50PM -0500, Kate Reeher wrote:

> I have a custom class called Game, and it has a variable called 
> "goals". I'd like to make this a list of custom objects, with various 
> information about the goals.

Unfortunately, either your email, or my email, mangled your code below. 
I've tried to reconstruct it as well I can, but please don't hesitate to 
correct me if I got it wrong.

> class Game: 
>     goals = {} 
>
> class Goal(object): 
>     def __init__(self,time,goal_by,assist_by,team,is_powerplay ): 
>         self.time=time 
>         self.goal_by=goal_by 
>         self.assist_by=assist_by 
>         self.team=team 
>         self.is_powerplay=is_powerplay
> 
> Is that Goal class set up correctly?

I can't be absolutely sure, because I'm not sure of your intention, but 
it looks correct to me. That's certainly the usual way to set up a 
class.


> For an instance of Game called game, is this how you'd set a variable 
> of a goal?
> game.goals[i].time= time

You could do it that way to modify an existing goal. (By the way, in 
Python circles, we prefer to talk about "attributes" of instances, not 
instance variables. If you are interested, I'll give you my standard 
rant about this later :-)

Your Game class is a little unusual though. It's not *wrong*, just 
unusual, perhaps you intended to do it this way. You have set the Game 
class to use a single "class attribute", which means that all 
instances will share it. (Actually, the rules are a little more complex 
than that, but for now thinking of it as a shared attribute isn't far 
wrong.) Was that intentional?

If you're familiar with Java, I think that a class attribute is close to 
a Java static variable. (I'm not a Java expert, so I may be wrong.)

If you intend to have multiple Game instances, each with their own 
independent set of goals, you would write it like this:

class Game:
    def __init__(self):
        goals = {}

but I'm not sure why the goals are kept in a dict. That would require 
you to keep track of whether each goal is the first, second, third... 
goal yourself. I think you want an ordered list:

class Game:
    def __init__(self):
        goals = []

red_vs_blue = Game()
shirts_vs_skins = Game()

# Add new goals.
red_vs_blue.goals.append(Goal(...))  # Fill in the appropriate args.
shirts_vs_skins.goals.append(Goal(...))
red_vs_blue.goals.append(Goal(...))

# Modify existing goals (but why would you do this?)
red_vs_blue.goals[0].team = 'green'

Because each game has its own list of goals, you can run multiple games 
at the same time. You don't have to track the index of the latest goal, 
you just append a new goal. You only need to care about the index if you 
want to modify an existing goal.

On the other hand, what you originally wrote, with a shared class 
attribute, isn't *wrong*. If you absolutely know that there will never 
be more than one game at a time, there is no need to bother creating a 
Game instance:

class Game:
    goals = []

Game.goals.append(Goal(...))
Game.goals.append(Goal(...))
Game.goals[0].team = 'green'

In this case, you can think of the Game class as being almost like a 
singleton instance. (Not quite the same, but it does the same job.)

As I said, this is fairly unusual in Python though. Normally you would 
stick to standard "one class, multiple instances, each with their own 
set of attributes" design.


> I'm finding how python does data classes INCREDIBLY confusing, for 
> whatever reason, so any help would be appreciated.

Sorry to hear that. Please don't hesitate to ask about anything 
confusing. Giving concrete examples is good, and if you are familiar 
with some other language, feel free to say so.



-- 
Steven
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to