Dev: Flask Intro 1

Recently, I attended a Python Meetup. The first presenter was Carter Rabasa from Twilio. He gave two short demos of Flask. From the site:

Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.

More specifically, it’s a micro web framework.
The alternative would be Django, a full server side MVC web framework.

This motivated me to run out and buy the book, “Flask Web Development” by Miguel Grinberg. This blog series will follow my experiments between the book, external sources like Carter’s open source code, and anything else I might fancy. My bigger motivation here is to see if Flask can help shrink the code footprint of a standard REST interface. I have done these in C# and while I appreciate the larger frameworks, I often find their a bit overkill for my needs. Particularly with a current trend in business shifting us towards Micro-Services. This slide from the presentation sort of explain what I mean:
Snip20141124_1

First thing first: Running Flask on your dev machine.

Setting up your Virtual Environment on OS X:


sudo easy_install virtualenv
sudo mkdir flask_test
cd flask_test
virtualenv venv
source venv/bin/activate
(venv) pip install flask

That installs VirtualEnv. From the site:

virtualenv is a tool to create isolated Python environments.

Best to keep it clean. As an aside; if you need more than this, you might look to Vagrant.
Then you make a directory, startup a virtual environment, start it, and finally install flask.
You’re now ready to write the obligatory hello world:

Open an text editor (like SublimeText) and let’s put this code in:


from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
  return '<h1>Heyas world</h1>'

@app.route('/user/<name>')
def user(name):
  return '<h1>Heyas, %s.</h1>' % name

if __name__ == '__main__':
  app.run(debug=True)

Save that as flask01.py.

So what’s happening here:
Importing the Flask library and creating an app. If you’re familiar with Express, it’s similar.
Then you define two routes. First to take handle addresses to the base URL; Second to show dynamic routes.
Then we run the app.

Back in your terminal:


(venv) python flask01.py

That should run your site:
Snip20141124_4

Snip20141124_5

Snip20141124_6

With the debugging you should be able to watch some logging happen of HTTP error codes as you try out your site:
Snip20141124_7

Okay there’s step 1.

Python PyGame 3.1: Walkthrough the WWII Bombing Pilot Game

PyGame in Python Part 3.1 Walkthrough the WWII Bombing Pilot Game

So, we’ve introduced you to the basics of Python and PyGame over the last several blogs. Now it’s time to get your hands dirty and do something FUN! The next several blogs will be devoted to breaking down the game from Chapter 7 of “Game Programming: The L Line, The Express Line to Learning”.

What you will do: You will put everything together: images (sprites), sounds, user input, classes and objects, moving objects, collisions, etc. My goal will be to break it out in easy chunks.

The story: The story in the book has *obviously* been modified to be politically correct and avoid the subject it rips off: bombing islands in the South Pacific in WWII. I have no editor (clearly), so, I’ve restored the original intent to bombing anti-aircraft facilities scattered over islands. When you fly over an island, you bomb the target successfully. The clouds represent the frak from anti-aircraft cannons. If you touch them, you’ve just had shrapnel rip through parts of your plane. When you’ve been frakked 5 times, your engines fail and you take a short trip into the sea. If you’ve played any games like Modern Warfare… this should be like a trip to the ice cream parlor.

Obviously a game of this size takes a more serious approach to the structure. Additionally there are parts I really don’t care to cover in this blog (designing graphics) so I’m just going to have you take the graphics off the companion site. You could take the whole program, but, there’s no sense of accomplishment there.

So, let’s start by making a new directory under Python27/games (or whatever Python you are running) called 1945. Then go to this link: http://bcs.wiley.com/he-bcs/Books?action=resource&bcsId=3648&itemId=0470068221&resourceId=10183 and drag all the images and sounds over into your folder so we don’t have to worry about them later. Okay, that saves us a lot of trouble and explanations a book cannot avoid.

Ground Rules
1. The bomber plane only moves LEFT and RIGHT, and is controlled through the MOUSE.
2. The background scrolls down forever (seemingly) simulating the plane flying forward.
3. Islands move down screen.
4. When the plane hits an island; we have successfully bombed the enemy and a sound will play. You get a combat bonus of $1,000.
5. Anti-Aircraft fire moves around randomly. If the plane touches it, that’s holes in the fuselage and a sound will play. You’re now 1 step closer to those great white sharks.

First, we’ll make all the sprites…
Create a file called bomber_plane.py

Create a file called bomber_plane.py
""" bomber_plane
    step 1 of 1945 knockoff
    build plane sprite, 
    control it with mouse
"""
    
import pygame
pygame.init()

class Plane(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("plane.gif")
        self.rect = self.image.get_rect()
        
    def update(self):
        mousex, mousey = pygame.mouse.get_pos()
        self.rect.center = (mousex, 430)
		
def main():
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("Bomber Pilot! bomber_plane.py - creating the Plane sprite")

    background = pygame.Surface(screen.get_size())
    background.fill((0, 0, 255))
    screen.blit(background, (0, 0))
    plane = Plane()
    
    allSprites = pygame.sprite.Group(plane)
    clock = pygame.time.Clock()
    keepGoing = True
    while keepGoing:
        clock.tick(30)
        pygame.mouse.set_visible(False)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
                
        allSprites.clear(screen, background)
        allSprites.update()
        allSprites.draw(screen)
        
        pygame.display.flip()
    
    #return mouse cursor
    pygame.mouse.set_visible(True) 
if __name__ == "__main__":
    main()

Let’s review some things here. At the tope we’ve imported and initialized the PyGame libraries. Then we setup the Plane class with a constructor/initialized and an update function. This is where we capture and respond to the user’s mouse. You can see we have fixed the Y-coordinate to the bottom of the screen but the X-coordinate goes where the user moves it.

In the main we build&blit the background, create an instance of the Plane class, setup the main loop and use the sprite group to manage screen updates. I haven’t gone over the sprites and sprite groups yet, so, let me summarize he explanation from PyGame’s tutorial that’s very well written:
The Sprite class is a base class for game objects. It only has methods to help it work with Group classes. The sprite keeps track of which groups it belongs to.
The Group class is a container. You can pass list of sprites to the constructor (__init__ method) to create a Group instance that contains some initial sprites. The sprites() method returns an object that can be looped on to access every sprite the group contains. The Group also has an update() method, which will call an update() method on every sprite in the group.
http://www.pygame.org/docs/tut/SpriteIntro.html


Next up is the Island Sprite. Hopefully you grabbed the graphics for this as I’m not going to describe the big fun of playing with pixel graphics. If you’re a programmer, I’m sure you don’t enjoy that part. Remember to give your nearest graphic designer a hug for taking on all the pain for you ;-)

Here’s a list of the behaviours we want to accomplish with this sprite:
1. Y-coordinate updates at a constant rate (it moves down)
2. X-coordinate is fixed
3. When it hits the bottom, it is re-drawn at the top
4. When it hits a plane, it is re-drawn at the top

Here’s the code:

class Island(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("island.gif")
        self.rect = self.image.get_rect()
        self.reset()
        
        self.dy = 5
    
    def update(self):
        self.rect.centery += self.dy
        if self.rect.top > screen.get_height():
            self.reset()
            
    def reset(self):
        self.rect.top = 0
        self.rect.centerx = random.randrange(0, screen.get_width())

Pretty basic. Notice in the update(self) function that it checks for the bottom screen “collision”. Notice in the reset(self) function how it randomly decides where to draw it at the top. It would be some kind of geographical miracle if the islands in the archipelago all lined up perfectly. Now we’ll modify the main():

    
def main():
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("Bomber Pilot! bomber_plane.py - creating the Plane sprite")

    background = pygame.Surface(screen.get_size())
    background.fill((0, 0, 255))
    screen.blit(background, (0, 0))
    plane = Plane()
    island = Island()
    
    allSprites = pygame.sprite.Group(island, plane)
    clock = pygame.time.Clock()
    keepGoing = True
    while keepGoing:
        clock.tick(30)
        pygame.mouse.set_visible(False)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
                
        allSprites.clear(screen, background)
        allSprites.update()
        allSprites.draw(screen)
        
        pygame.display.flip()
    
    #return mouse cursor
    pygame.mouse.set_visible(True) 
if __name__ == "__main__":
    main()

Now the sprite.Group thing is adding some value. We we’ll just continue to add sprites to this and let the Group functions do the heavy lifting of updating all it’s contained sprites.

We’ll end with the third sprite, the Cloud. Again, we need to figure out the rules of the cloud:
1. Y-coordinate will move at random rates (speed)
2. X-coordinate moves (side to side)

class Cloud(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("Cloud.gif")
        self.image = self.image.convert()
        self.rect = self.image.get_rect()
        self.reset()

    def update(self):
        self.rect.centerx += self.dx
        self.rect.centery += self.dy
        if self.rect.top > screen.get_height():
            self.reset()
    
    def reset(self):
        self.rect.bottom = 0
        self.rect.centerx = random.randrange(0, screen.get_width())
        self.dy = random.randrange(5, 10)
        self.dx = random.randrange(-2, 2)

Nothing super new going on here. You can see the only collision we’re coding for is the bottom of the screen when we reset it. We don’t care if they move off the side. You see us having a variable “speed” with the line: self.dy = random.randrange(5, 10). The next line picks a random side to side drift.

def main():
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("Bomber Pilot! bomber_plane.py - creating the Plane sprite")

    background = pygame.Surface(screen.get_size())
    background.fill((0, 0, 255))
    screen.blit(background, (0, 0))
    plane = Plane()
    island = Island()
    cloud = Cloud()
    
    allSprites = pygame.sprite.Group(island, plane, cloud)
    clock = pygame.time.Clock()
    keepGoing = True
    while keepGoing:
        clock.tick(30)
        pygame.mouse.set_visible(False)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
                        
        allSprites.clear(screen, background)
        allSprites.update()
        allSprites.draw(screen)
        
        pygame.display.flip()
    
    #return mouse cursor
    pygame.mouse.set_visible(True) 
if __name__ == "__main__":
    main()

Again, we’ve added the cloud sprite to the group allSprites and we’re done. Pretty awesome. Okay, so if you run the program now, you’re going to see something that’s not Call of Duty, but, far and away cooler than even the Mandelbrot set (unless you’re a Math person and then Mandelbrot is still way, way cooler):

Next time we’ll move on building sprites and adding sounds to the collissions. Thanks for making it this far. I’m still trying to find the best way to display code in these posts. So far, I like screenshots best for visuals, but it leaves a lot to be desired since you’d have to copy it by hand. I’ll figure it out eventually.

-Mike

Python PyGame: 2.1 (Mandelbrot)

Python PyGame:2.1 Mandelbrot (a short aside)

In my last blog I started off with a game that draws circles of different colors. That is boring. Personally, I never tire of rewriting programs to draw fractals. Today we’ll quickly jump through a program to draw the Mandelbrot set. Drawing 2d fractals may be so 1980, but, I get a kick out of it.

What is a fractal? Simply put, a fractal is worlds within worlds. It’s a geometric shape that no matter how far you zoom into or out of still holds the original shape. It’s a fairly new term coined by Benoit Mandelbrot in 1982 in his book, “The Fractal Geometry of Nature”.

More importantly, fractals are the closest approximation we have come up with for a Mathematics of Nature. They can approximate clouds, coastlines, snowflakes and earthquakes. It’s related to the popularization of Chaos Math by Edward Lorenz and his study of weather prediction in 1961. I cannot claim understanding, but, I do find it fascinating to ponder over. More on that after the code if you’re interested.

Python & PyGame by themselves don’t just carry around the code necessary to pull this off. This gives us an excuse to play with two cool libraries: NumPy and PIL (Python Imaging Library).
http://numpy.scipy.org/
http://www.pythonware.com/products/pil/

Once again, if you’re running Windows 32 bit, life is obvious, if you’re running 64 bit, you must download them from here:
http://www.lfd.uci.edu/~gohlke/pythonlibs/

Next I happened across a version of the program written in 2006. Updated it a bit to work with the newer libraries, and the result:

Run it

You’ll see:

That’s much cooler than a bunch of circles.

Let’s quickly review what some of those NumPy functions do.
Arange – numpy.arange([start], stop[, step], dtype=None, maskna=False)
returns an evenly spaced set of values. Sp, arange(3)=[0,1,2]

Ravel – numpy.ravel(a, order=’C’)
Returns a flattened array. So a two dimensional array of [123] and [abc] is returned as [123abc]

Shape – ndarray.shape
Tuple of array dimensions.

Zeros – numpy.zeros(shape, dtype=float, order=’C’)
Return a new array of given shape and type, filled with zeros.

Here’s some further amateur discussion:
Free Will or Determinism is one of philosophy’s Coke vs. Pepsi discussions. You’ve seen it again and again through popular media: books (Ender’s Game) or movies (Matrix, Inception). In mathematics it has shown up as well. Newtonian Mechanics is pro-determinism. Then Quantum Mechanics became popular, which many felt was more aligned with Free Will. Then Chaos Math came back as a pro-determinism mathematics that can solve a lot of seemingly “random” problems in math: cloud formations, turbulence, weather patterns. The fractal is a mainstay in Chaos Math. Totally predictable and matches up with a lot of patterns in nature. Unfortunately there remain many unsolved problems in these mathematics, but it is fun for me to think about when I’m having trouble with a simple coding problem.

Here’s some more links:
This web page explains the math, theory, and how to do this in c++:
http://warp.povusers.org/Mandelbrot/

© Copyright Duke Hall - Designed by Pexeto