FAQ: Python in Pokitto


#61

Like this:
myrect = upygame.Rect(x,y,w,h)


#62

@Hanski if I create a rom pixel data like this:

boxPixel = b'\
\xff\xff\xff\xff\
\xfc\xcc\xcc\xfc\
\xfc\xff\xfc\xfc\
\xfc\xff\xcc\xfc\
\xfc\xfc\xcc\xfc\
\xfc\xcc\xcc\xfc\
\xff\xff\xff\xfc\
\xfc\xcc\xcc\xcc\
'

and then I pass this data to a class like this:

class Tile:
    def __init__(self,pixels,x,y,w,h):
        self.pixels = pixels
        self.surface = upg.surface.Surface(w, h, pixels[0])

in this way

newTile = tile.Tile([td.boxPixels],xp,yp,12,12)

Am I wasting memory? Consider the same tile could be create n-times at different x and y. Is this the correct way to manage it? Data is passed by value or reference?
I keep a reference to the pixel because the tile could be animated (passing an array), and so I create different surface as time elapsed.
Hope I’ve been clear.


#63

opps, I’m an idiot.


#64

I suppose it is passing a reference. You can check that by calling:

gc.collect()
print ("free:",gc.mem_free())

before and after you have created an instance of the class. Put import gc at start of the file.


#65

how “I suppose”? You’re my python guru! You should be sure of it! :wink:
It seems so.:grin:


#66

Sorry to disappoint :wink: I actually know about Python language far less that about C++.


#67

Why do you need to wrap it in []?
Wouldn’t passing boxPixel be enough?
Presumably that creates a copy in a new array?
(Assuming it’s legal syntax.)

It’s passed by value, but references are values.

Comparing it to C++, a Python object reference is like a pointer.
If you pass an object reference to a function, the object that the reference refers to can be manipulated, but if you try to change the reference then you only change the function parameter, the variable that was passed to the function remains the same.

Run this code and hopefully you’ll see what I mean:

def a_function(a_list):
	# Alters the object by appending 2
	a_list.append(2)
	# Reassigns the a_list parameter to a new object
	a_list = [10]
	# Appends a 5 to the new object
	a_list.append(5)
	# Prints [10, 5]
	print(a_list)
	
my_list = [0, 1]

# Prints [0, 1]
print(my_list)

# Prints [10, 5]
a_function(my_list)

# Prints [0, 1, 2]
print(my_list)

(You can try it online here.)


And before anyone asks, I’m not a Python guru either,
I barely know the language and I’m far from its biggest fan,
I’m just relatively good at learning languages and finding information.


#68

I’m passing an array, that way the tile take care of animation loop if it found something to iterate.

Yes it is, python is really smart on array operations (slicing and iteration in primis)

I see. Primitives are also passed by value.

It’s also fun that we are all using python now, but nobody seems to be really used to it. :sweat_smile:


#69

I checked and I was right, you’re actually instantiating a new list.
But instead of copying the contents of boxPixels into the list, it’s actually constructing a new list with boxPixels as its only element.

I.e. tile.pixels[0] is a reference to boxPixels.
As demonstrated by this program:

boxPixels = b'\
\xff\xff\xff\xff\
\xfc\xcc\xcc\xfc\
\xfc\xff\xfc\xfc\
\xfc\xff\xcc\xfc\
\xfc\xfc\xcc\xfc\
\xfc\xcc\xcc\xfc\
\xff\xff\xff\xfc\
\xfc\xcc\xcc\xcc\
'

class Tile:
    def __init__(self,pixels,x,y,w,h):
        self.pixels = pixels
        
a = Tile([boxPixels], 0, 0, 0, 0)
b = Tile([boxPixels], 0, 0, 0, 0)

print("a.pixels == b.pixels: ", a.pixels == b.pixels)
print("a.pixels is b.pixels: ", a.pixels is b.pixels)
print("a.pixels[0]: ", a.pixels[0])
print("a.pixels[0] is boxPixels: ", a.pixels[0] is boxPixels)
print("b.pixels[0]: ", b.pixels[0])
print("b.pixels[0] is boxPixels: ", b.pixels[0] is boxPixels)

Output:

a.pixels == b.pixels:  True
a.pixels is b.pixels:  False
a.pixels[0]:  b'\xff\xff\xff\xff\xfc\xcc\xcc\xfc\xfc\xff\xfc\xfc\xfc\xff\xcc\xfc\xfc\xfc\xcc\xfc\xfc\xcc\xcc\xfc\xff\xff\xff\xfc\xfc\xcc\xcc\xcc'
a.pixels[0] is boxPixels:  True
b.pixels[0]:  b'\xff\xff\xff\xff\xfc\xcc\xcc\xfc\xfc\xff\xfc\xfc\xfc\xff\xcc\xfc\xfc\xfc\xcc\xfc\xfc\xcc\xcc\xfc\xff\xff\xff\xfc\xfc\xcc\xcc\xcc'
b.pixels[0] is boxPixels:  True

I’d like to point out that if you just want something you can index, you can index boxPixels on its own:

boxPixels = b'\
\xff\xff\xff\xff\
\xfc\xcc\xcc\xfc\
\xfc\xff\xfc\xfc\
\xfc\xff\xcc\xfc\
\xfc\xfc\xcc\xfc\
\xfc\xcc\xcc\xfc\
\xff\xff\xff\xfc\
\xfc\xcc\xcc\xcc\
'

class Tile:
    def __init__(self, pixels, x, y, w, h):
        self.pixels = pixels
        
a = Tile(boxPixels, 0, 0, 0, 0)
b = Tile(boxPixels, 0, 0, 0, 0)

print("a.pixels == b.pixels: ", a.pixels == b.pixels)
print("a.pixels is b.pixels: ", a.pixels is b.pixels)
print("a.pixels[0]: ", a.pixels[0])
print("a.pixels[0] is boxPixels: ", a.pixels[0] is boxPixels)
print("b.pixels[0]: ", b.pixels[0])
print("b.pixels[0] is boxPixels: ", b.pixels[0] is boxPixels)

This isn’t slicing or iteration, this is construction.

(Side note: it would be possible to simulate slicing in C++, but you’d have to use a different operator. E.g. you could do array & slice(1, 2), or array | slice(1, 2), or even array, slice(1, 2). Object ownership would be a bit of a conundrum though.)

That’s expected behaviour.

Everything is pass by value, but there aren’t any primitive references, only object references.
(Unless Python supports boxing like C# and Java do.)

Can I have C++ back please? :P

Seriously though, although there’s less code involved I’m really missing enums, constants, function overloading* and static typing.

* Proper automatic function overloading, not manually checking the dynamic types of the arguments

At least there’s operator overloading though, so I guess that’s one up over C and Java.


#70

Probably a typo here? You probably want to check b.pixels[0] instead of a.pixels[0]?
EDIT: probably same error in the previous line aswell.


#71

Yep, fixed it. The output is the same either way.


#72

Is it possible to stop the music from playing?


#73

Yep, there is a pause() -method.