[Tutor] Re: I'm just full of questions today
Daniel Yoo
dyoo@hkn.eecs.berkeley.edu
Sun, 29 Oct 2000 00:30:45 -0700 (PDT)
> def PaddleMotion(dir, lpx1, lpx2, lpy1, lpy2):
> if dir == 'left':
> lpx1 = lpx1 - 30
> lpx2 = lpx2 - 30
> Screen.coords(paddle, lpx1, lpy1, lpx2, lpy2)
>
> So it moves left. I have to re-assign the values of everything again so
> that it will keep moving with repeating presses of the button.
That looks ok. You can definitely make things look nicer if you apply
some OOP on that Paddle. Here's a really quick sketch of what it might
look like:
####
class Paddle:
def __init__(self, x1, x2, y1, y2):
"""Initialize a Paddle with inital coordinates
x1, x2, y1, and y2."""
self.x1, self.x2, self.y1, self.y2 = x1, x2, y1, y2
def move(self, offset):
self.x1, self.x2 = self.x1 - offset, self.x2 - offset
###
Then you can create an instance of a paddle and use it to hold the
paddle's coordinates:
mypaddle = Paddle(0, 10, 0, 3) # construct a paddle
mypaddle.move(-30) # tell it to move -30
print mypaddle.x1, mypaddle.x2 # and show the results of the move()
One other advantage of object orientation, and objects in general, is that
it'll allow you to escape a certain troublesome situation. Let's take a
look at your function again:
> def PaddleMotion(dir, lpx1, lpx2, lpy1, lpy2):
> if dir == 'left':
> lpx1 = lpx1 - 30
> lpx2 = lpx2 - 30
> Screen.coords(paddle, lpx1, lpy1, lpx2, lpy2)
There's a small problem here becase any changes you make to lpx1, lpx2,
lpy1, and lpy2 will be local to PaddleMotion. This might make more sense
with a short, unrelated example:
###
>>> def printSquare(x):
... x = x * x
... print x
...
>>> num = 5
>>> printSquare(num)
25
>>> num
###
Notice that nothing happens to num. That's because when we call
printSquare(num), Python does something like this:
x = num (now x contains the value of num, since num contains an
"immutable" numeric type)
x = x * x
print x
Within that exchange of values to parameters, x gets a copy of whatever
num contained, and within the function, nothing happens to num. This is
how local variables provide isolation; often, it's very helpful, but not
when you want a function to modify the state of a set of variables.
One way to fix this is to explicitly return those values back with the
return statement:
###
def PaddleMotion(dir, lpx1, lpx2, lpy1, lpy2):
if dir == 'left':
lpx1 = lpx1 - 30
lpx2 = lpx2 - 30
Screen.coords(paddle, lpx1, lpy1, lpx2, lpy2)
return (lpx1, lpx2, lpy1, lpy2)
###
and call PaddleMotion like this:
x1,x2,y1,y2 = PaddleMotion('left', x1, x2, y1, y2)
But already this is a little long to read. The easier approach is to
accumulate those coordinates into a class, and provide methods to change
the state of an instance.
Hope this helps!