Python’s lists: referencing versus copying

I finished the on-line class Introduction to Interactive Programming in Python from Rice University and it was a lot of fun.

asteroids

This is a screen shot of the last game RiceRocks, which is a simplified version of the arcade game Asteroids. My ship has blown up a few asteroids. 😉

Although the course caters for beginners, I learned a great deal of things. For example, I had never programmed an animated game, so working out this kind of interactive programming was great.

In this post I want to put to the fore an issue which comes up very often. In the RiceRocks game, there was a class Sprite, to create rocks and other objects. The sprite image is based on an image object whose center is a list:

[ x, y ]

The sprite instance has an image_center element which corresponds to the image center. It is created as follows:

self.image_center = info.get_center()

and the method in the Image class

    def get_center(self):
        return self.center

is returning the center as list. The result is that the center is a reference to the same list. So the sprite.image_center and image.image_center point to the same list.

This is not a problem for what is called in the game static images. But explosions are dynamic, which means that the image is actually a tile of a sequence of the explosion, and tiles are shown one at a time in consecutive frames as a function of the center of each tile.

In my implementation, I create a sprite for the explosion of a rock, so the rock sprite is replaced by the explosion sprite. As the time advances, I change the center of the explosion sprite to display the new frame. This worked only for the first explosion…

As I was changing the image_center of the explosion sprite, I was also changing the center of the original image. The solution was to create the sprite with a copy of the list:

self.image_center = info.get_center()[0:]

Data Validation of boolean values in Rails

To validating the presence of a boolean value, the short answer is you don’t need to. Rails does an automatic check on boolean data types.

In theory validating the presence would be just a waste of time, but in practice it creates a bug. If you have in your model.rb a line similar to

validates :is_active, presence: true

and is_active is a boolean, when entering false as a value, Rails interprets it as empty and the action of creating or updating the record is refused.

Leaving the line out will allow the creation or updating of the record and if the value is not either true or false, the stored value will be nil.

You may want to ensure that the value is either true or false. In that case, the following line should be added:

validates_inclusion_of :active, :in => [true, false]

Inspired from: