Virtuous Programmer Adventures of an Autodidact

1Nov/103

Python 1/4: Getting Started

This is the first article in a series, to read the entire series go here.

Why Python is Interesting

Programs must be written for people to read,
and only incidentally for machines to execute.
-Abelson and Sussman

Readable Syntax

When Guido van Rostrum designed Python it's clear that he had this principle, if not this exact quote in mind. The result is a language which often reads like pseudo-code. For example:

  1. def buyFruit(fruit):
  2.   if fruit.color == 'red' and fruit in [Apple, Orange, Tomato]:
  3.     return fruit.price
  4.  

Flexible Semantics

Although Python primarily an object oriented/procedural language, it has functional elements including functions as first class objects, lambda expressions and map/filter/reduce functions. This gives considerable flexibility in how you go about solving problems.

An excellent summary of the design philosophy that guides both Python's code design and the style of Python programs in general see: The Zen of Python

List Comprehension

Python's list comprehension syntax is a compact and clear way to create new lists from existing lists. The syntax itself looks a lot like set comprehension notation as it's used in discrete mathematics. Here are a few examples:

Given the base list of integers:

  1. xs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

You can create a list of every integer doubled with:

  1. [x * 2 for x in xs]

Or you can create a list of only odd integers with:

  1. [x for x in xs if x % 2 == 1]

Or a combination of both, doubling all of the odd integers from 1 to 10:

  1. [x * 2 for x in xs if x % 2 == 1]

Generators

Generators are a powerful addition to Python's syntax. They permit a form of lazy evaluation where they create values as they are needed rather than all at once. For example, a common way to write a function for a Sieve of Eratosthenes to generate prime numbers is:

  1. def generatePrimes(topValue):
  2.   primes = [2]
  3.   for testValue in range(3, topValue + 1):
  4.     divisors = [prime for prime in primes if testValue % prime == 0]
  5.     if divisors == []:
  6.       primes += [testValue]
  7.   return primes

The above function will, when called, generate all of the prime numbers from 2 up to the value given in the argument. The problem is that it will generate them all immediately, whether you need them or not. This is potentially a serious waste of resources if it comes out that you only needed a handful of them. Python solves this problem by using generators:

  1. def generatePrimes(topValue):
  2.   primes = [2]
  3.   for testValue in range(3, topValue + 1):
  4.     divisors = [prime for prime in primes if testValue % prime == 0]
  5.     if divisors == []:
  6.       primes += [testValue]
  7.       yield testValue

The only difference between our new function and the original is the last line. Note that in the new function there is no return statement, instead there is a 'yield' statement, and it is inside the for loop. The new function returns a generator which can be passed to any function that operates on lists and it will treat it as a linked list. Should the function that uses the generator return before all of the values have been extracted then the remaining values will never be generated. This will allow you to avoid doing work that isn't needed. Even if you find that you need all of those values, rather than having a potentially long wait at the start of the process, the work will be spread throughout the process, allowing for just in time delivery of your data.

Python's Lineage

ABC

Python was originally developed to be a replacement for ABC, and on the surface the resemblance is striking:

ABC:

  1. PUT {} IN telephone
  2. PUT 5551212 IN telephone["Spam Foo"]
  3. PUT 8674309 IN telephone["Eggs Bar"]
  4. FOR name IN keys telephone:
  5.   WRITE "Name:", name, " Phone:", telephone[name] /

Python:

  1. telephone = {}
  2. telephone["Spam Foo"] = 5551212
  3. telephone["Eggs Bar"] = 8674309
  4. for name in telephone.keys():
  5.   print "Name:", name, " Phone:", telephone[name]

Both of the above map telephone numbers to names in an associative array, then print them in the form: Name: Spam Foo Phone: 5551212 Name: Eggs Bar Phone: 8674309

In addition to the similarities in syntax, they both use an interactive environment which allows you to type your code directly into the command line and get a response from the interpreter.

Haskell

From the appearance of the syntax, it's clear that Python acquired its list comprehension functionality from Haskell.

Haskell:

  1. [oddNum * 2 | oddNum <- [1 .. 10], oddNum `mod` 2 == 1]

Python:

  1. [oddNum * 2 for oddNum in range(1, 11) if oddNum % 2 == 1]

Both of the above produce a list of integers, [2, 6, 10, 14, 18] which are the odd numbers from 1 to 10, doubled.

Python Installation

Complications to Look Out For

Currently there are two active branches in Python, 2.7 and 3.1. Python 3.1 has a number of improvements to the language which make the syntax regular and prevent some difficult to track bugs that are a serious issue in 2.7. Unfortunately it is not backwards compatible. I'll be using 2.7 for this article because it continues to have the most libraries available for it.

If you're interested in the changes made in Python 3.1, you can find them at What's New In Python 3.0.

Downloading And installing Python 2.7

You can find the latest release of Python 2.7 from Python download. From that point installation is easy, run the installer and accept the default values. The full install will take 52MB of space on your drive.

First Program

For a first program, we'll get started with "Hello World". In Python this one is so trivial that it takes more effort to run it than to write it. Copy and paste the code below into your preferred text editor and save it as 'helloworld.py':

helloworld.py:

  1. print "Hello World"

Executing the Program

The primary purpose of the hello world program is to create a simple program that demonstrates how to compile/execute a program in the given language.

To execute this one type "c:\python27\python helloworld.py" at the command line.

There is no direct use of a 'main' function in Python. Code execution starts at the beginning of the file and progresses through the end.

There are a number of ways to impose more structure on a Python program, but the purpose of this first project is to make sure our systems are configured correctly. I'll get to the more interesting stuff in next week's post.

Trivia

Python was named for the British comedy group Monty Python. Python's creator creator, Guido van Rostrum has the final say on all of Python's design decisions and is called the Benevolent Dictator for Life.

Resources

Python Wikipedia Article

Python.org

Python Download

The Zen of Python

What's New In Python 3.0

Python Cheat Sheet

Posted by Frank Berthold

Comments (3) Trackbacks (0)
  1. “… sterling debut by a promising author.” – New York Times “While a bit light on content in this first chapter of what promises to be a thrilling geek epic, the commentary and trivia make it ail worthwhile.” – Rolling Stone “…sure to cause a serious re-examination of current best practices in corporate programming language choices” – Fortune

  2. OMG, I have to take a language that uses whitespace as a critical syntactic element seriously.


Leave a comment

No trackbacks yet.