A time for work and a time for blog(ing)

Quick message here with two points.

1. Yes, I haven’t updated this blog since before I left the US for Italy, Indonesia, and Thailand.

2. Yes, I have been a very busy bee and I have a ton of good technical information which I will blog about this Winter.

So, stay tuned.

My recent technical experiences have spanned the globe literally.  Here’s a few topics I will write about:

  • Securing a WordPress installation.
  • Setting up a VPN connection to tunnel your traffic through different places.
  • The technology involved for successful world travel.
  • How to have a WordPress blog autopost to social media sites.
  • How to approach design problems on a budget.
  • etc.

Well, here’s to future posts!  It’s been a great, fantastic, wonderful, amazing seven months for starting up ideas, trying a million things, failing and succeeding over and over and I look forward to sharing it with you.

Posted in Uncategorized | Leave a comment

A Word on Minimalism and Technology (Nook/Transformer/Clip)

I put a lot of stock in living with a minimalist approach to things I own.  It’s not that I seek the aesthetic life (re: Quakers, Monks, etc), but, I appreciate the aesthetic of simplicity.

When the first eInk eReaders came out I was immediately fascinated with them.  Here’s a technology that would allow me to reduce my considerable library into a tiny device.  It was really the eInk that sold me though, as reading books on LCD’s truly does wear my eyes out and I already do this all day.  The eInk is like reading any book (as far as eye strain goes).

Nook

I did my research and settled on the Nook.  Primarily because they had taken efforts to make getting ebooks from the library smooth.  PS-I love Libraries and how they are embracing eBooks, audiobooks, and online checkouts (nice work: http://www.overdrive.com/).

My big drawback on the Nook ($90ish?) was that I found programming books on it impractical due to it’s size and B&W.  Of course, they’ve hence come out with bigger eInk eReaders, but they’re not color, and they’ve come out with smaller LCD based color ones.  Luckily now tablets have been around long enough not to suck and offer 10 inch screens and color.

ASUS Transformer

Again I did my research and settled on the ASUS Transformer ($330 @ TigerDirect).  The odd thing about this device is the specs and price SMOKE the competition.  It’s not even close.  Yet, when I started researching Tablets I did not even come across this device for some time.  Apple’s iPad dominates the marketing on the web.  For my purpose, reading technical manuals, brand-agnosticism is the key because prices vary widely from book, reseller, and publisher.  One example is “Gray Hat Python”.  It’s $40 for the nook, $32 from the publisher, and $17 on the Kindle…  I imagine “The Market” will eventually correct this behavior and level the prices, but for today, I will shop.

SansaDisk Clip

mp3 players is a similar story.  At one point I could not resist the elegance of the iPod nano and classic. The price of these devices is frankly a crime against humanity.  Sadly, mine were stolen and I was out hundreds.  This pushed me to find a fiscally conservative solution.  The SansaDisk Clip ($close to price of a large Starbucks latte) does everything I need it to do and plays many formats and cost me $30 for a 4gb.

So, between these very small, relatively cheap items, I have been able to eliminate large physical amounts of:

  • Novels
  • Reference Books
  • CDs

That’s a lot of what I used to own.  I’ve converted the stuff I wanted to keep over and I love the aesthetic of my clean and efficient space.

Posted in Uncategorized | Tagged , , , , , | Leave a comment

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

Posted in Uncategorized | Tagged , , , , | Leave a comment

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/

Posted in Uncategorized | Tagged , , , | 2 Comments

Python PyGame: 2

Python PyGame: 2

In my first blog I covered the basics of getting PyGame installed on your Widnows machine with Python 2.7. We also went over the core methodology of IDEA: ALTER presented in the “Game Programming The Express Line to Learning” book I’m using to start this series. For review:

  • IDEA (the game framework)
  • 1.Import & Initialize
  • 2.Display Configuration
  • 3.Entities
  • 4.Action (broken into the ALTER steps)
    • ALTER
    • 1.Assign values to key variables
    • 2.Loop (infinite w/breakout clause)
    • 3.Timer (setup framerate)
    • 4.Event Handling
    • 5.Refresh Display

Today I’m going to take us a step further into the game development world with three programs. All of these are covered in great depth in the book, so, my purpose is simple introdcution to the concepts and you can walk through it with me if you like. I am a believer that if you do anything 10,000 times you’ll be much farther advanced than today, so, it may feel tedious to type the code out, but over time, you’ll engrain it into your brain.

The book itself is written largely towards total beginners to programming, so, I am sparsely choosing which ones I do. The three programs today are drawCircles, mouseEvents, and Paint. So, you’ll see how to draw stuff on your canvas, interact with the user through keyboard and mouse, and then put it all together.

Let’s check out the first program, drawCircles:

Two points of interest. We’re using PyGame’s draw command to create a lot of circles of various colors and starting at different points. Secondly, we’re demonstrating out ability to save files back to a folder (in this case we’re converting the screen into a bitmap). One additional thing is the use of a function call as opposed to just doing everything in one go. It’s not so impressive here, but, it will be more handy when we begin writing larger programs or using object oriented techniques.

Go ahead and run this and look in your file folder. You’ll find this image:

Personally, whenever I get a chance to draw things I inevitably want to draw fractals like it’s 1980. I’ll post a small addendum later to do that.

Okay, so the second program is called mouseEvents.py. It grabs a few user events and prints them to the console. Let’s take a look at the code:

So, you can see the IDEA:ALTER is still working for us here (it will keep working for us too). Outside of the normal stuff, we’re using the PyGame Event Handler to grab when the user hits the Close button, presses a key down, or clicks the mouse. One thing of interest is that the simple pygame.KEYDOWN event is all you need to create a keylogger and steal people’s passwords all day long. There’s a reason Python is a popular language among black and white hat hackers. It’s easy, light, and fast.

Run this program and you’ll be able to see the console spit out everything you do:

That’s good fun…

Okay now let’s put them together into a Paint program. This silly task shows us a lot of good features of game programming. Let’s take a look at the first part where we define some functions:

The first function is interfacing with the input from the user to determine what to do. Primarily what color and line width to use for the paint brush. The second function is reporting back what color and width the user has chosen. Setting the MyFont to the “None” of SysFont means it will use the default font on whatever system is running the program. That’s a handy thing to keep in mind.
Okay, the second part defines the main function:

So once we are inside the main loop, we check first to see if the user has quit, and then handle the mouse and keyboard. If any key is pressed we update the values of myData. If the mouse is held down we use pygame’s draw command and feed it MyData’s variables. Result? Paint:

Okay, so, that’s it for today. With these kind of fundamentals we are ready to tackle some bigger concepts and move towards more object oriented games. See you next time.

Posted in Uncategorized | Tagged , | Leave a comment

Python PyGame: 1

Introduction:

A particular nephew of mine asked if I could help him write a computer game. I said of course, but I really had no idea what this meant. So, I did some quick research on Amazon and came up with a couple of books to run through on the subject. The next few blogs will be working through “Game Programming The Express Line to Learning”. It was written in 2006 fro Python (which you wouldn’t know by the name). Why Python? Because I’m teaching myself Python and I enjoyed my experiences with Django and Python on the more familiar web development side of things. Okay, enough with the chatter, onto some meat.

Assumptions:
This is written assuming you have Python 2.7 installed on your Windows 64bit machine. If not, modify accordingly.
You’re at least a level 1 programmer with a +1 ring of protection… (j/k).

Editors: I have switched to notepad++ for my Python work because my free PyCharm ran out. A major bummer because PyCharm is super awesome. Luckily, notepad++ is pretty good to when you add in the right extensions.

Download the appropriate installer.
If you go to the obvious place [http://pygame.org/download.shtml], you’ll notice there are no Windows 64bit installations.

If you try to install a 32 bit version, then on the next step you’ll get this error:

 
You have to go here for those: http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame

Run the installer. Select the Entire Features to be installed and change the directory to your Python27 location.

Now open up IDLE and type: import pygame
It should think a bit and then come back to a >>> line.
If it does not you’re probably missing libraries, so go find them and download them.

So, now it’s time to write your first game.
Go ahead and make a folder inside your Python27 folder called games and then put another one in there called idea:

The core idea this book sets us up with surprisingly takes the form of ingenious acronyms! Acronyms are largely responsible for our higher pay and social eschewing. Regardless, they are a constant.
Here’s the SETUP:
IDEA and ALTER
Where A=ALTER
Thus, it’s really: IDE[ALTER]
What does it mean in pseudo-code?
IDEA (the game framework) =
1.Import & Initialize
2.Display Configuration
3.Entities
4.Action (broken into the ALTER steps)
ALTER
1.Assign values to key variables
2.Loop (infinite w/breakout clause)
3.Timer (setup framerate)
4.Event Handling
5.Refresh Display

 
Okay,now that we have a total understanding of what we’ll be diong from the beginning game to the end game, let’s jump right into the intro program that does nothing but display a blue screen:

Create a file called idea.py inside the games/idea folder.
Slap this code in there:

Let’s go over some of the less obvious things. We’re using an infinite loop. True. This appears to be acceptable in the gaming world, whereas I’m used to this being an unforgivable sin in the web world. Pygame is doing most of the heavy lifting. You don’t really need to know that pygame is a wrapper around SDL (Simple DirectMedia Layer: http://www.libsdl.org/ ), but, take it for granted that someone (Pete Shinners) did a lot of heavy lifting for you to make writing games fun and easy. Thanks Pete!
The clock.tick(30) is setting your FPS (FRAMES PER SECOND).
BLIT = Copies data from one rectangle to another (moves objects)
FLIP = displaying graphics on the screen the easiest way will be slow and create a flicker effect. Thus we use the “screen flipping” technique that implements “double buffering” routines (most new systems support this now) that is a special kind of blit which copies the screen object onto the visual display. This reduces screen refresh rates and improves the flicker effect.
And Blue = RGB value 0,0,255.

Open a command prompt and run this file:

You’ll see this:

It’s fairly amazing that something this awesome could be so easy… okay, so it’s not fairly amazing, but it is the foundation for everything from here on out.

Okay, so now lets move a box across a screen so we can see this screen refresh stuff in actions.
Create a new game file called movebox.py and slap this code in there (I made a new folder under the same name):

 

Not much has changed, but we have added another entity. Now we have a background and a box. Then in the Events we have told the box to move positions to the right on the X axis. We’ve also added in a “collision” detection with the edge so it will start over. Nothing mind blowing. Go run it.

 

You’ll see an animated version of this:
 

Okay, that’s a bit cooler than a blue background. Okay, that took us through to chapter 5. So, next blog we’ll get into some more interesting elements around drawing and events. Thanks!

Resources:
http://www.amazon.com/Game-Programming-Line-Express-Learning/dp/0470068221
http://pygame.org
http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
http://pygame.org/docs/tut/newbieguide.html
http://notepad-plus-plus.org/
 

Posted in Uncategorized | Tagged , , , | Leave a comment

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!

Posted in Uncategorized | Leave a comment

Django & Python Adventure Part 6

Today I am going to focus on incorporating JQuery into Django. If you’re following along this is material covered in chapter 6 of Ayman Hourieh’s “Django 1.0 Web Site Development”. The book was published in March 2009, so this will be an interesting test of what’s changed in JQuery in 21 months. It was common practice back then to download a copy of JQuery, but, today I believe utilizing CDNs (Content Delivery Network) is the preferred method.

The big players run these CDNs:
• Microsoft: http://www.asp.net/ajaxlibrary/cdn.ashx
• Google: http://code.google.com/apis/libraries/
• JQuery: http://code.jquery.com/

As an interesting aside, some developers worry about their applications being unable to connect to the CDN 100% of the time. If you want to read more on this, read this blog about getting around it:
http://code-inside.de/blog-in/2011/02/06/howto-jquery-hosted-cdn-version-local-fallback/

One final note, it’s best to use the .min version of whatever JQuery as it has been “minified” to work faster for you application.

We only want to reference this once, so we’ll drop it in the Master Page base.html:

The first thing I want to implement is AJAX-enabled search functionality on the bookmarks. The book suggests the best practice of writing the search form without AJAX (so it should work if the AJAX fails) and then add on the AJAX functionality. This is called “Progressive Enhancement” and it simply means we try not to leave anyone out of the fun.

First: bookmarks/forms.py:

Second: bookmarks/views.py
Notice the search is already implemented in Django. We’re calling it with Bookmark.objects.filter(). When we passit arguments, they must be in the format: field__operator. For a .Net programmer I still find the double underscore a little odd, but, whatever. There are other operators we could use aside from “icontains”. “contains”, “startswith”, and “exact” are some others. You can see this gives you similar power to a SQL SELECT blah FROM blah WHERE… Again, Django is handling the ORM code for us so this is what we’ll use to query the Model.

Third: implement templates/search.html

Fourth: update urls.py
(r’^search/$’, search_page),

Now test it out:

Very cool. We’ve now created our base search functionality with a few lines of code. Now we can add in the AJAX for browsers that can handle it (have JavaScript enabled).

First: update base.html to have a link to the search page:

Second: update the views.py

Third: update the search.html

Fourth: create the search.js file. This…

Again, we can test it. Notice this time the page does not reload. That is the JQuery AJAX call handling the manipulation of the innerHTML of the page for you:

AJAX accomplished! It’s a brand new day. Next time I’ll be doing something a little more advanced, but this was a good start.

Thanks,
Mike

Posted in Uncategorized | Tagged , , , | Leave a comment

Django & Python Adventure Part 5

In this post I’ll be adding the Tag concept to my bookmarks website. This will get the website one step closer to what Delicious does and is an integral part of social websites. Throughout the course of the blog we’ll add Tags, and Tag Clouds into the website and give the user several ways to bounce between Tags and Bookmarks.

First we’ll need to add a model for the Tag in models.py:

PS-Notice that we have updated each model with a __unicode__ method. The old way you’ll see this is with __str__ which returns bytes instead of characters. The value of this is Django will use it to return a normal human language representation of whatever the model is under the hood.

Then re-issue the command prompt for syncing the database:
c:Python27django_bookmarks>python manage.py syncdb

Next I’ll add a form for the user to submit bookmarks and tags. Open forms.py

Next we need to create a View for this, so open up views.py

And finally we need a template and a url. So, create a file called “bookmark_save.html” in the templates folder. It will look similar to all the templates we’ve done in this series:

And edit your urls.py to look like this. The book suggests at this point to do some clean up, so you’ll notice the comments breaking urls out into functional areas.

Now you can browse to your save page:

Enter a few links and see how your user page grows:

Cool, but kind of sad that it doesn’t display the tags we’re duitifully entering, right? So a couple of things are in order to clean this up. We’ll begin with locking this page down to the proper users. Right now you can type different usernames in the URL and see their stuff. That wouldn’t fly for anyone. Open the templates/base.html:

Then we’re going to limit the access of the bookmark save page to only authenticated users. This could be hacked with an if-else statement, but Django provides a better way. Open views.py:

Pretty cool? Just an include and a decorator on your view definition tells it that the user must be authenticated. The last thing you need to do is add the following like (variable declaration) to the bottom of the settings.py:
LOGIN_URL = ‘/login/’

Now when you logout and try to browse directly to http://127.0.0.1:8000/save/ You will get:

Okay, so now it’s time to get User page to not only display our saved links but their tags as well. We’re going to do this by creating a template for displaying bookmarks and tags and then drop it into the user page.
Create a new template file called “bookmark_list.html”:

This template is less like a Master Page and more like a User Control. In the Classic ASP days it was just called an include file, or a code snippet. Wow, there are a lot of ways to say we’re going to hide this code so we can make it look like 1 line in other places 😉 So, now do that in your user_page.html:

Notice everything in the {% block content %} has been replaced with our include. We were dropping a lot of class definitions in the include file that don’t exist yet in our CSS file. So open up the style.css:

The last thing we need to do is update the user_page view definition to show the tags. You’ll notice a new Django function “get_object_or_404” in use here. It’s another if-else statement asking the database if it can retreive the user object and if it cannot it’s going to display a 404 error. Just like the old code, just streamlined.

Great, now you can check out your page at: http://127.0.0.1:8000/user/username/:

Next I’ll turn all the tags into their own pages so users can see all the links that match the tag.

Let’s start with urls.py. Add this definition to it:
(r’^tag/([^s]+)/$’, tag_page),

Then hop over to the views.py:

Then create a template page for the response called tag_page.html:

Then modify the part of bookmark_list.html that generates the Tags so that it creates a URL link to the tag page:
So, this line:

  • {{ tag.name }}
  • To this line:

  • {{ tag.name }}
  • Now if you refresh your User page you’ll notice the Tags are now links:

    And if you click on a link page you should see the associated bookmarks and the Posted By username:

    The final step in this chapter is on creating a tag cloud. If you hang out in WordPress blogs at all you’re probably familiar with the visual Tag Clouds that they often have on the side. The point is to show all the tags in the blog. Here it is to show the tags in our bookmark database. After that you want to be able to assign a “weight” to each tag based on how many “hits” or counts that tag has in the database. This is one of the cooler concepts that web 2.0 sites use. This sort of collective intellgence based on what the community is doing. Sound familiar? It’s was one of the big things I noticed when google’s search came out. Results sorted by “weight”. You see it as weight/rank/relevance depending on what site you’re on, but, in all cases, it’s pretty cool and I’d probably need a PhD to blog more on it :p.

    Okay so hop back over to views.py:

    And then create a template page for “tag_cloud_page.html” and put this code in:

    So, what’s going on? Nothing beyond a little math. We’re setting a range from 0 to 5 for each tag, and then calculating the weight based on how many tags there are in the database. Something I really think is cool is the dynamic CSS class assignment in the HTML. That’s how we’ll dynamically control the size of the cloud font to show which are more popular.
    So, pop open style.css:

    And finally we’ll update the urls.py:
    Add this line under the last one you did:
    (r’^tag/$’, tag_cloud_page),

    Then browse to http://127.0.0.1:8000/tag/

    Cool! It’s cooler if we add more bookmarks with tags, but you see the potential here. Okay, so there was a lot of code in this post. I am starting to get pretty used to the pattern of adding of content to the site. Bouncing between adding database models to views and templates and adding url paths for users to get to them. Although the site map is growing, there’s really only those main 3 pages I keep going to.

    Another thing I’ll note is at this point I’ve had to do some debugging a couple of times and I found the process pretty painless. Django’s debug messages point me directly to the problem it’s having. Either a type on the view, or the urls made up most bugs. If you get something wrong with your database model, you tend to notice it immediately.

    Posted in Uncategorized | Tagged , | Leave a comment

    Django & Python Adventure Part 4

    In this post we’ll be dealing with Django’s User Authentication and Base Templates (Master Pages). These are things every project requires and so you cannot really know a platform until you’ve covered this ground.

    First let’s take care of the Base Template. In this part we’ll add a special kind of template that is used by other templates. If you’re a .Net person, this is a Master Page. If you’re some other kind of person…. Hiya! We’ll also add a style sheet to our project to handle a universal nav:
    In your project, add the following pieces:
    project folder

    So, a folder called “site_media” with a style.css in it and in the templates folder a base.html.
    styles.css will look like this:

    We’ve already included the auth library in the settings.py under the INSTALLED_APPS section, but we have to modify the MIDDLEWARE_CLASSES section to allow our sessions to save a cookie.
    Find that section and add this line to the list:

    'django.middleware.csrf.CsrfViewMiddleware',

    Now we can jump to the urls.py and setup a line to instantiate the authentication login view:

    (r'^login/$','django.contrib.auth.views.login'),

    Now add a folder to your templates directory called “registration” and add a page to that called “login.html” and paste in this code:

    IMPORTANT! That {% csrf_token %} was not in the book and took some research to figure out. Ultimately, it was this blog that got me past that bug: http://jordanmessina.com/2010/05/24/django-1-2-csrf-verification-failed/
    Otherwise, you get a nice 403 error telling you it’s missing.

    Now you can go to views.py and add in the following and replace your main_page definition:

    And redo the user_page function in the same page to use the render_to_reponse library:

    Now we’ll add a page “forms.py” in the bookmarks application folder.
    Here are the entire contents:

    Next you’ll need to update the views.py:

    It will come out like this:
    registration page

    Now we need to modify the top navigation to account for these new options, so edit your base.html nav id:

    Lastly we’ll implement a successful message page for the registration process. If you’ve noticed in this walk through Django provides a lot of functionality for you out of the box. Here is another example. There is a view inside the django.views.generic.simple library called direct_to_template.

    Create a register_success.html inside your templates/registration folder and enter this code in:

    Then update your urls.py:

    (r'^register/success/$', direct_to_template, {'template':'registration/register_success.html'})

    Tmie to test this out:
    registration form tested
    Hit register and:
    registration success
    (PS-if you’re paying attention you’ll notice the nav at the tops say’s “sa” and not “ishmael”. I had to logout of sa and do it again to get that to work right, but my post-production budget is tight)

    Afterthoughts: This took a bit more time for me to debug, and there’s probably some libraries that have changed since the book I’m reading. I noticed that PyCharm gave me a deprecation warning on this library: django.views.generic.simple, so that’s something I’ll check into later.

    Overall though, I’m impressed at how simple it was to add Authentication. Although this is something you do once per project, I’ve seen a lot of custom code that makes it extremely painful. For me, saving lines of code means simplicity which is what I’m going for. If you have any questions or comments, feel free to shoot them over.

    Posted in Uncategorized | Tagged , | Leave a comment