500 Programming Languages: Python

sillywalk

Python is one of my favorite programming languages. It’s almost always the first one that I reach for when I have a programming task I’d like to try out, and often enough, it’s the final language of that task, too.

Introduction to Python

On the official Python website, Python is described as “a dynamic object-oriented programming languages that can be used for many kinds of software development.”

They also claim that “Many Python programmers report substantial productivity gains and feel the language encourages the development of higher quality, more maintainable code.”

I am inclined to agree.

Though Python is a true “everything is an object” OO language, you can do more than just Object-Oriented programming with it. You can do plain-ol’ procedural programming, functional programming, Object-Oriented programming, and probably some other types of programming if you wanted.

One of the nicest things about Python is the “batteries included” approach, which means that Python comes with a ton of modules that do a large amount of what you want to do, right out of the box (or tarball, or installer…I don’t know if you can actually get Python in a box). Does your app need to write a cgi app? Or even better, a wsgi app? Web client? Web server??

Yep, it has all those, and many, many more.

There are many, more thorough introductions to Python out there, so I won’t attempt to cover the language in too much more depth, but I will show you a couple of things that really capture the spirit of Python:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import braces
  File "<stdin>", line 1
SyntaxError: not a chance
>>> import this
The Zen of Python, by Tim Peters
 
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
>>> import __hello__
Hello world...
>>>

My First Python Program

This is far from my first program in Python. I first discovered Python when I was in High School, so possibly as early as 1999-2000. I had discovered Blender, a free 3D editing application, and it had Python embedded within it, for use in creating extensions and scripting games for the built-in game engine. Back then, I still thought I was going to be a video game developer, so I made some effort to learn Python so I could write games in Blender.

Anyway, enough history. :)

For this program, I implemented a Brainfuck-to-Python compiler. I won’t go into Brainfuck right now because I will be doing a post on it next.

This program is nowhere near demonstrating all of, or even a large number of, Python’s features, but it does demonstrate how easy it is to write a quick-and-easy program.

I threw this compiler together in less than 5 minutes, and it functioned properly on my first try (the Brainfuck hello world from Wikipedia).

The only addition I had to make later was handling the case of end-of-file on the input.

def compile(program):
    indent = 4
    code = [
        'def compiled(input=None, output=None):',
        '    import sys',
        '    if not input: input = sys.stdin',
        '    if not output: output = sys.stdout',
        '    i = 0',
        '    a = [0]*30000'
        ]
    commands = {
        '>': 'i += 1',
        '<': 'i -= 1',
        '+': 'a[i] += 1',
        '-': 'a[i] -= 1',
        '.': 'output.write(chr(a[i]))',
        ',': 'a[i] = ord(input.read(1) or "\0")',
        '[': 'while a[i]:',
        ']': ''
        }
    for command in program:
        line = commands.get(command, None)
        if line: code.append((' ' * indent) + line)
 
        if command == '[':   indent += 4
        elif command == ']': indent -= 4
    exec '\n'.join(code)
    return compiled

This function takes a string containing BF code as its one argument and returns a function which will run that code when called.

The function returned will have two optional arguments, input and output, which are expected to be file-like objects (at least implementing read and write, respectively), which allows for passing in specific input and/or handling the output from within a python program.

It’s kind of a dirty way to do it, building Python source, an then running it with exec, but it gets the job done. I could also save the function to a compiled .pyc file, so you could later import it directly, but that would require a bit more code and ruin the simplicity of it all. I could also have generated input for my Python assembler, and used that to generate a compiled .pyc file, but like I said, I was going for simplicity here, and encouraging people to learn Python, not necessarily Python bytecodes.

You can download the Brainfuck-to-Python Compiler if you’d like. You can download the Brainfuck-to-Python Compiler if you’d like.

continue on to learn more about Python

Anatomy of a Python program

Modules

Python is organized in modules and (optionally) packages. A module is simply a file which contains some amount of Python code. A package is simply a directory which contains some number of modules.

You can import modules with the import statement, which runs the code in the module, and then imports any objects the module defines into the current context (generally under some namespace, see the Python Modules documentation for more details on the import statement).)

The code in a module can be at the module-level, outside of any functions, or it can be contained in functions and classes. Code at the module level is run immediately when the module is imported.

For short scripts, it’s usually fine to write code at the module level. For more complex modules, it’s common practice to put all the code into functions, and then conditionally invoke that function if the module is run directly.

For example, to extend my BF compiler above to be invoked directly from the commandline, I added the following code to the end of the bf module:

 
def cmd_line():
    import sys
    if len(sys.argv) < 2:
        print('usage: %s bf_file\n' % sys.argv[0])
    else:
        try:
            with file(sys.argv[1]) as f:
                bf_fn = compile(f.read())
        except IOError, msg:
            print("couldn't read file %s: %s\n" % (sys.argv[1], msg))
 
        bf_fn()
 
if __name__ == '__main__': cmd_line()

The cmd_line function is just a regular function. The real magic happens on the last line there. At the module level, name will be set to “main” if the current module is the one which was run directly.

If a module is imported from any other module, name is set to the name of the module.

Python Shell

You can also run Python code directly, one line at a time, from the python shell. The shell comes up if you just run Python directly without specifying a module for it to run.

Python makes a great calculator, random-number picker, interactive prototyping tool, etc.

Often when I’m playing around with an idea for how to do something, I’ll just open up the Python shell and play around until I get it working how I’d like, then I will commit the code to an actual file.

Installing and Running Python

There’s a nice guide to installing and running Python on various systems at Python.org, so I won’t spend time repeating what they’ve got there.

Learning more about Python

A good place to start is the Python tutorial, and there’s a lot to learn from the links on the Python Documentation page.

Conclusion

Python is a great language, for both new programmers and experienced programmers who want to try a language that is probably way nicer than what they’re used to programming in, especially if what you’re used to programming in is PHP. Heck, even Terry Chay recommends Python as a learning language, and he’s known to be a strong supporter of PHP.

In conclusion, if you haven’t yet, give Python a try. You won’t regret it!

7 Responses to “500 Programming Languages: Python”

  1. terry chay Says:

    I also recommend it as a general purpose scripting language, especially for large teams. Perl is more utilitarian, but it gets hard for even the writer to read over time. Python pretty much looks the same no matter who codes it.

  2. pib Says:

    It’s just too bad it’s not quite as quick to throw together a Python web application as it is to throw together a PHP one. It probably has something to do with Pythonists insisting on doing things “the right way.” It results in better overall code, but a longer lead-in time, I think.

  3. Ryan Says:

    @pib,

    Have you seen Django? It’s hard to think the difference in time would be more than a negligible amount.

  4. pib Says:

    Yes, I wrote a post about Django a while back, even. Django is exactly what I mean by “the right way”. Sure, the development is fast, and you don’t even have to set up an actual web server, but when it comes time to put your Django app up on a production server, it’s more work. Most hosts already have PHP up and running, and lots of them won’t support Python at all. So you have to find a host that supports it, then you’ve got to set up your app to work with whatever type of Python setup their server has.

    With PHP, it’s pretty much the same setup for development and deployment.

    Now, this is all coming from a guy who likes Erlang for web development, so the extra little bit is negligible for me, but not for your typical, starting-out web developer.

  5. terry chay Says:

    Yeah Django is a framework, it should be compared to ZF and Ruby on Rails. I’d say that of the three, I’d like Django the most, but that isn’t saying much. Frameworks make design decisions for you and they tend to get in the way unless you wrote it yourself.

    It’s really hard to compete with mod_php, it’s everywhere with most every extension you need preinstalled, and has a whole host of great open source programs and tools premade and trivial to install (mediawiki, wordpress, etc.). I like to say, “When you are developing for the web, web frameworks fall somewhere between downloading Wordpress and building it yourself. That’s a pretty narrow straight to navigate.”

    I’m not a fan of Erlang for web development. The main reason for this is simply that I think the “web as glue” model is good design and I want my glue to be straightforward. There is no doubt that it does some important (today) things that PHP just can’t do (or rather… SHOULDN’T do), I just feel that it should be a service (maybe in erlang like CouchDB or ejabberd) and then you bind to it. But I can think of some web problems that disprove that, just as I can think of web problems where Django would be better than DIY PHP code.

  6. pib Says:

    I think the approach I like best for Erlang web development (for dynamic apps) is to have most of the front-end code actually run in the user’s browser via JavaScript, and basically just make API calls to the Erlang backend. That way you don’t need two server-side languages.

    I really like the idea of CouchApps that Chris Anderson has been working on, but I think I prefer a little wrapper around the nasty long URLs that CouchDB ends up having, and some sort of good authentication layer, as well.

    I also would love to get a chance to give Nitrogen (http://nitrogenproject.com/) a try for some dynamic applications. At that point you’re basically writing your apps in a mix of Erlang, HTML templates, and a DSL for defining how to react to various events. I like the idea of writing all the code in one place that it has.

  7. Probably Programming » Blog Archive » A brainfuck synthesizer Says:

    [...] WordPress.org « 500 Programming Languages: Python [...]

Leave a Reply