1

I'm taking python classes. I've asked for hints about this in our forums but with no luck. I think my implementation is very bad. I'm very new at this, so bear with me, even with the way I ask the question.

The question above is what I am told I need to do. I've tried but with no luck, so I've come here for help.

Ultimately, I am trying to get my key handlers to respond to my keypresses. I've done this previously, but we were not yet working with classes. That's where the snag is. I'm supposed to implement class methods/variables to make them work, not use new variables or new globals.

e.g.

class SuchAndSuch:

    def __init__(self, pos, vel, ang, ang_vel, image, info, sound = None):
        self.pos = [pos[0],pos[1]]
        self.vel = [vel[0],vel[1]]
        self.angle = ang
        self.angle_vel = ang_vel
        self.image = image

    def update(self):
        # this is where all the actual movement and rotation should happen
        ...

The handler below is outside the SuchAndSuch class:

def keydown(key):
    # need up left down right buttons
    if key == simplegui.KEY_MAP["up"]:
        # i'm supposed to just call methods here to make the keys respond???

    ...

So, all updates are supposed to be happening in the SuchAndSuch class and only calls for this updates are supposed to be inside my keyhandler.

Can someone please give me an example on what they mean when they say this? All the variables (or ideas given in forums) I try to implement in my key handlers error as "undefined".

Hannele
  • 9,301
  • 6
  • 48
  • 68
Bianca
  • 27
  • 1
  • 5
  • Maybe @staticmethod could help you? –  Jun 05 '13 at 15:17
  • 3
    I'd double-check that problem. I'd be surprised if you didn't have access to a `SuchAndSuch` instance. – cwallenpoole Jun 05 '13 at 15:21
  • Small niggle - 'the question above' - do you mean below? – Hannele Jun 05 '13 at 15:35
  • @Hannele Presumably "How do I use a method outside a class?" (the question title) – Henry Keiter Jun 05 '13 at 15:36
  • 1
    Is everything in a single file? Can you paste it online somewhere and post a link? (for example, http://pythonfiddle.com) You've posted your question correctly in that you're only showing the relevant chunks, I'm just curious about the larger structure of the problem. – Hannele Jun 05 '13 at 15:51
  • @Hannele. don't want to get in trouble :). but maybe i can give you the bigger pic without all the code. trying to fly an object. and the whole code looks like this: class imginfo: ... lots and lots of image links and position info and sound info... some def that include distance and vector that was done for us that we dont' need to mess with. class suchandsuch: ... class sprite: ... outside class .. draw(canvas) and here we have already set up background sound effects.the rest is all outside class where we have a timer thing.. and then where our keyhandler is supped to be. – Bianca Jun 05 '13 at 17:36
  • Hmn. Have you tried going to your instructor for help? You've got some idea of the basics, but I think you need some one-on-one help on how/where to create an instance of `SuchAndSuch`. There are also some really good interactive tutorials here: http://www.codecademy.com/tracks/python – Hannele Jun 06 '13 at 15:44

1 Answers1

8

There are two ways to call a class' methods from outside that class. The more common way is to call the method on an instance of the class, like this:

# pass all the variables that __init__ requires to create a new instance
such_and_such = SuchAndSuch(pos, vel, ang, ang_vel, image, info)

# now call the method!
such_and_such.update()

Simple as that! The self parameter in the method definition refers to the instance that the method is being called on, and is implicitly passed to the method as the first argument. You probably want such_and_such to be a module-level ("global") object, so you can reference and update the same object every time a key is pressed.

# Initialize the object with some default values (I'm guessing here)
such_and_such = SuchAndSuch((0, 0), (0, 0), 0, 0, None, '')

# Define keydown to make use of the such_and_such object
def keydown(key):
    if key == simplegui.KEY_MAP['up']:
        such_and_such.update()
        # (Perhaps your update method should take another argument?)

The second way is to call a class method. This is probably not what you actually want here, but for completeness, I'll define it briefly: a class method is bound to a class, instead of an instance of that class. You declare them using a decorator, so your method definition would look like this:

class SuchAndSuch(object):
    @classmethod
    def update(cls):
        pass # do stuff

Then you could call this method without an instance of the class:

SuchAndSuch.update()
Community
  • 1
  • 1
Henry Keiter
  • 16,863
  • 7
  • 51
  • 80
  • A-HA so .. for eg. this variable such_and_such = SuchAndSuch(pos, vel, ..., etc) ... is it going in key handler?? tried it this way (pls don't laugh .. hardly know what i'm doing:) def keydown(key): such_and_suck = (pos, vel, ang, ang_vel, image, info) if key == simplegui.KEY_MAP["up"]: Ship.update(self.pos) Ship.update(self.vel) NameError: name 'pos' is not defined – Bianca Jun 05 '13 at 15:37
  • @Bianca: You probably need to write `Ship.update(such_and_suck.pos)` and `Ship.update(such_and_suck.vel)`. – martineau Jun 05 '13 at 15:43
  • `pos`, `vel`, `ang`, etc are used here to demonstrate how to create a instance (a copy) of `SuchAndSuch`. It's highly likely that you already have some global instance of the class - do you see anything like that anywhere in your existing code? There could be different values in between the brackets. – Hannele Jun 05 '13 at 15:47
  • @Bianca The `such_and_such` instance goes wherever you need a persistent object. Think of it this way: SuchAndSuch is a "kind of thing". When you say `such_and_such = SuchAndSuch(...)`, you are making a new thing ([object](https://en.wikipedia.org/wiki/Object-oriented_programming)) of the `SuchAndSuch` type. Then you can do work with that object, like changing its position and so on. In your *handler*, `self.pos` doesn't mean anything, because `self` doesn't mean anything outside the `SuchAndSuch` functions. Instead, you can access those variables like `such_and_such.pos` and so on. – Henry Keiter Jun 05 '13 at 15:48
  • @Hannele i do not see where i have anything like htat – Bianca Jun 05 '13 at 15:49
  • @Bianca As to your first error ("NameError: name 'pos' is not defined"), you need to make sure you actually define `pos` someplace. If that variable isn't set to anything (like `pos = (0, 1)`), Python won't know what to do with it, and it tells you that it's undefined. The same goes for the other variables (`vel`, `ang`, etc). – Henry Keiter Jun 05 '13 at 15:49
  • 1
    wouldn't that be making a local variable which i'm not supposed to? all that i have inside update INSIDE class such_and_such where it is where all the update works? no? i will try it anyway to see. – Bianca Jun 05 '13 at 15:55
  • @Bianca: You might still get a `NameError`, but it's probably now for a different `name`. See @Henry's comment for an explanation of why I said what I said. – martineau Jun 05 '13 at 15:57
  • @Bianca You're absolutely correct - that would create a new local variable each time you call the function. I don't think that's what you're after. There should be an instance of `SuchAndSuch` that you can access from your key handlers - if you search for `SuchAndSuch(` (with an open bracket), is there really nothing that turns up? – Hannele Jun 05 '13 at 15:59
  • ok wait everyone! something is happening lol. let me work on this some more!! nothing is moving but my errors are changing and i know now why.. which means that the buttons are actually being recognized by the keyhandler!!! i think by fixing a few things i mgiht get it to work!!! will keep you updated. thank you for your patience :) thank you very much everyone and @HenryKeiter – Bianca Jun 05 '13 at 16:00
  • @Bianca If you find the answer to your question, make sure to write up the answer here! If the answer turns out to be unrelated to the question you've written, you should probably delete the question afterwards (helps keep things tidy). It's OK and encouraged to do both things! – Hannele Jun 05 '13 at 16:02
  • @Bianca Absolutely right; if you put `such_and_such = SuchAndSuch(...)` inside your `keydown` function, it'll create a new one every time, which is probably not what you want. My guess (without seeing all the code) is that you want a module-level (global) `SuchAndSuch` instance, which you then reference with your keyhandlers. My other guess is that `update` should take another parameter: the thing to update (maybe the key that was pressed?), so that that method can take care of all the work. Something like `def update(self, direction): pass` and `such_and_such.update('UP')` in the handler. – Henry Keiter Jun 05 '13 at 16:03
  • @Hannele hmm not sure. so sorry i dont think i understand maybe. no nothing there except my class name but that is whitout brackets. – Bianca Jun 05 '13 at 16:03
  • man so much info :). you guys are awesome. i'll work with all this and update here as requested @Hannele. or i'll come back with more silly questions. thank you for the encouragement. it's always embarassing to ask elementary Qs like these. but one day hopefuly they will be elementary to me too :) – Bianca Jun 05 '13 at 16:08
  • back at it after doing some work (here at work :). now the image parameter wont go thru. i get undefined or no attribute error – Bianca Jun 05 '13 at 17:37
  • @Bianca If you understand the answer to the question you originally asked, but now have other questions or problems, the appropriate thing to do is mark this question as resolved and post a new question with your new problem clearly stated. That way it gets more attention, keeps questions to a single topic, and people can help you more effectively than in a lengthy discussion in the comments section ;) – Henry Keiter Jun 05 '13 at 18:15
  • it's not a different q. it's the same issue. my key handler is the issue. that's where the error is. inside my keyhandler. this outside inside class concept is my problem. when described by you and others it makes sense but to put it in action is anotehr story. i guess i do have all the info anyone could give. and now it becomes my problem trying to make it work. maybe i'm too dense for it. i have 100% in everything in this class but this project.. is just not working for me. – Bianca Jun 05 '13 at 18:31
  • @Bianca I say that because undefined attributes are a very different problem than "how do I call methods of a class from outside the class". If the error message is different, it usually merits a new question. Based on the code snippets you were showing before (another reason for a new question: you can show your actual code and error messages), I'm guessing that you're trying to access variables that don't exist, or don't have the names you expect. Remember that `self` exists *within* a class; outside the class you use the *instance name*. If you open a new q, feel free to link to it here. – Henry Keiter Jun 05 '13 at 18:38
  • ah. okie dokie. sorry about that. haven't been able to work this code yet so i'll update as promised before when i figure it out. sorry again and thanks for your help. – Bianca Jun 05 '13 at 18:41
  • so .. going to try chat for a bit because i have a related Q but with a different idea... so this way i can eliminate things that have already been mentioned and move on to something else faster while i'm working on it. – Bianca Jun 05 '13 at 18:49
  • FOUND ANSWER -- so, after a headache of an ordeal, (and i've learned a lot of things in the mean time like i can't chat on stackoverflow because i don't have enough points :) .. this was what the answer was. my class suchandsuch was a ship.. and in order to get my key handlers to respond, i had to use my_suchandsuch then either do a command or use methods from the class .. like this --> my_suchandsuch.method. my_suchandsuch was the sprite that was the ship that i was trying to move. which was probably one point i should have said to you guys. hope this helps the next amateur coder :) – Bianca Jun 09 '13 at 06:21