Archive for the ‘python’ Category.

Understanding ‘global’ in Python

In one forum I read, many people do not seem to know how to use the global keyword in Python. The most common misconception is that the declaration global foo will make foo global. That is wrong. global tells Python to use the global definition of foo instead of creating a local definition. Let’s see with an example.


>>> foo = "foo"
>>> def func1():
...   foo = "bar"
...   print "Inside func1():", foo
...
>>> def func2():
...   global foo
...   foo = "baz"
...   print "Inside func2():", foo
...
>>> print foo
foo
>>> func1()
Inside func1(): bar
>>> print foo
foo
>>> func2()
Inside func2(): baz
>>> print foo
baz
>>>

In func1(), when I assigned the string bar to foo, Python created a new foo, local to func1() which shadowed the original foo. Which is why before and after the function call, the value of foo (the global one) was “foo”.

Inside func2(), I specifically told Python that I wanted to use the global value of foo, not create a new local one like I did in func1(). This is why the value of foo (the global one) is changed when we do print foo after the function call.

Back into the Django fray for a bit

To sort of go along with the fantasy football related programming post from earlier, I also like to do a set of “power rankings” for the NFL using a fairly simple but data-heavy formula that I derived via a bit of trial and error and really just some thought exercises. For the past season or so I just maintained it using a simple spreadsheet (at first Excel, then Gnumeric once I converted my laptop to Linux after getting the new job), but even when I was doing it I noticed data inconsistency which almost definitely resulted from data entry errors on my part. For example, part of the formula involves a teams “points for” (points they score against other teams) and “points against” (points other teams score against them). Well, when you sum up the “points for” for all the teams, and when you sum up the “points against” for all of the teams, you should get the same number. But sometimes I wouldn’t. Those errors weren’t quite as nefarious to track down as other things like in my strength of schedule calculations the total W-L record of one component should be the mirror opposite of another, but it would be missing some wins somewhere.
Continue reading ‘Back into the Django fray for a bit’ »

Some tripping points when you start using Django

I have the opportunity to use Django at work to develop web sites. Most places use PHP, ASP, ASP.NET, JSP, ColdFusion, Perl or Ruby on Rails; Django shops are a rare breed. A quick search for ‘django’ on some of the job sites for the Montreal region yields no results. I am therefore very grateful to have the chance to work with a non-sucky technology (not that I want to imply that the alternatives suck, but I find them deficient.)

We switched away from PHP for several reasons, the most important was that it was difficult for us to quickly go from a small site to a medium-large site with PHP. What I mean by that is that a client originally wants just a small site with a few static pages to advertise his products and/or services, have a contact page, etc. Then a few months later, the customer decides that he wants to be able to enter his products and their prices himself. That means creating a database + tables, creating the CRUD pages to manipulate the data, etc. Django gives us an automatic administration interface, which means we only need to worry about how to present the data on the site; for creation, modification and deletion, the client can just use the admin interface (which is available in French.)

Other reasons we switched were: a more solid and complete standard library, a more powerful language, built-in support for i18n (not sure if PHP has it), the generic views, especially object_list with automatic pagination, bundled modules for comments, syndication and users.

Along with the fun of not having to do a lot of mindless work, switching to Django brought some new pains as well. Here are some things you should expect if you decide to start using Django instead of PHP.

  • Harder deployment: you gotta give it to PHP, deployment is super easy. Since most Apache installations have PHP already installed and configured, all you gotta do is dump your .php files on the server and you’re pretty much done. Django’s deployment is more complicated than that, unfortunately. Using mod_python, you must either set up a VirtualHost or a Location in your httpd.conf file, which most likely requires root access. mod_python also caches your Python scripts, which means that whenever you make a change to a Python file (or a translation file), you need to restart Apache. If you don’t have root access, you can still put the site online with a few .htaccess files (this is undocumented), but it’s a pain and if you need to update some .py files, you will need to get an administrator to restart Apache for you. This is probably my biggest gripe with Django.I have no experience with the other deployment alternatives such as FastCGI, so I can’t speak about them.
  • Django is still in active development: Django has not yet reached 1.0, so the authors and contributors don’t mind breaking backward compatibility here and there. To make sure we don’t have problems, we use the latest stable version, 0.96. When 0.97 comes out however, some code will need to be updated (e.g.: clean_data was renamed cleaned_data in newforms.) Some interesting features are also only available in the development version, so make sure you read the documentation for your version.
  • You explicitly define URLs: Contrary to PHP where you just type the name of your script in the address bar, you need to define all the URLs on your site in Python files (e.g.: urls.py) I actually consider this a good feature of Django; I’ve seen quite a few sites in production on which navigating to phpinfo.php revealed a gold mine of information. For static pages however, it can be cumbersome to edit the URLs module, add a view function which will load the page.
  • The Django template language: The Django template language is not a full-fledged programming language. In general, this is an advantage, this helps make sure you don’t start mixing code and design a little too liberally. Sometimes, however, there is no way you can do an operation in your Python code, it needs to be in the template. For instance, if you have a list of objects and they are paginated, to display all the page numbers with links, you will need to write your own filter to create a list from 1 to pages (template variable which contains the total number of pages.)
  • Some features are undocumented: Django has awesome documentation, but some aspects of the framework, for one reason or another, are undocumented. These include signals and the comment framework.