A Django site.
October 6, 2008

Jordan Gunderson
jordy
Jordy Blog
» Utah Mobile Developers Group

I’m way excited about the Utah Mobile Developers user group that is forming. Their first activity is on the schedule for Wednesday, October 29 and will discuss both iPhone and Android development. Here’s the agenda and RVSP:

6:00pm Doors open, pizza, networking
6:30 Opening, recognize sponsors, review agenda, review door prizes
6:40 Presentation 1 - iPhone Development
7:40 Presentation 2 - Android (Google Phone) Development
8:40 Door prizes
9:00 Meeting over
Afterward - trip to someplace local for pie, drinks, fries, whatever

Please rsvp by sending an email to glen@glenlewis.com.

I’ve already added it to the Utah Tech Events Calendar. If you’re a nerdy Utahn who loves mobile phones you should come. This is going to be an area of explosive growth and opportunity.

For those who didn’t know, I’m working on a tech business that’s very mobile-phone related, so I’m very excited to see this group forming in Utah.

September 30, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Building Cocoa GUIs in Python with PyObjC, Part Five

Adding Python Modules to the Bundle

If you try to use Python modules on the standard OS X Python path import statements will work fine. However, if you have non-standard modules that might be in a different location, or ones that you want to ship with, you will notice you can't just import them.

To bring them into the application bundle you'll have to go through a couple steps, but when it is all done the application will be able to use the modules, and you don't have to require the end user to install anything extra.

  1. Add the files to the Xcode project.

    • Select 'Project -> Add to Project' (option-command-a)
    • Select the Python module (directory) that you want to add.
    • On the next screen select "Copy items into destination group's folder (if needed) Add to Project dialog
    • Select the correct targets in 'Add to Targets'
    • Select "Create Folder References for any added folders"

And you're done. Nothing to difficult, but it does take some getting used to. Don't forget to import the module in the main.py file so you can use it.

<< Part4: Creating an Open Dialog

September 11, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Exaile 0.3 Roundup

A nice fellow emailed and asked me if I could post a monthly (possibly weekly) roundup on Exaile 0.3 so that people can follow what's going on. It sounded like a good idea to me, so here's the first one.

We've pretty much ironed out the storage details, and gotten playback/playlists figured out. What we have now is a fully functioning media player. The things that are still missing are:

  • Preferences dialog of some sort. We haven't even started on this, however, I feel that the one in 0.2 was pretty well written and could probably be used.
  • Cover art manager
  • Lyrics manager
  • Device manager plugins (for things like Ipods, other mp3 devices)
  • Visualizations
  • Rating system
With these items missing, there have been a lot of requests for an alpha release. I'm thinking we could probably get everything together and release 0.2.14 and 0.3alpha at the same time. Any comments?

September 6, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Django 1.0!!!

Django 1.0 is finally here!!!

I figured I'd just announce my excitement. So far, I've migrated two websites to it (one being this blog, the other being a much larger app for work), and haven't really had any problems. Following the Backwards Incompatable Changes on their Wiki made it fairly painless.

Congratulations to the Django Project!

P.S. I know I'm going to get some guff for this, but it's a breath of fresh air to be working in Python/Django at work instead of our hacked together CGI/Perl system.

June 7, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Exaile 0.3

Exaile is currently undergoing an almost complete rewrite. Why? Because the codebase could be better. Recently, thanks to Aren Olson, the 0.3 branch has been taking off. Already the code is a lot better, and will be a lot easier to add things to in the future.

As of this writing, you can create a collection, based on different libraries (directories). For each one of these directories, you can set a rescan interval, and/or have the library be watched by pyinotify for changes. You can create playlists, smart playlists, play these playlists in order or shuffle and/or on repeat. I am currently using it as my default player.

However: none of this can be done using a gui yet. This can all be done easily by using Exaile 0.3's pretty good looking internal API. Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python

import exaile as ex
from xl.playlists import Playlist
from xl.collection import Library

ex.main()
exaile = ex.exaile

# scan my music directory
exaile.collection.add_library(Library("/home/synic/media/music"))
exaile.rescan_libraries()

# Create a playlist with the artist Thievery Corporation, but exclude anything
# from the Versions album

pl = Playlist()
tracks = exaile.collection.search('artist=="Thievery Corporation" NOT '
    'album="Versions"')

pl.add_tracks(tracks)
pl.toggle_random()  # I usually play my music on shuffle :)

exaile.queue.set_current_playlist(pl)
exaile.queue.next() # start playback of the playlist

# ok, let's quit.  This will save the collection to the database, settings,
# etc.
exaile.quit()


Developing this way will make it much easier to add a gui (or even more than one type of gui. Someone could create a wxPython gui while we're creating the familiar pygtk gui).

We're also adding a test suite which should make for stabler releases once the first 0.3 release is ready.

If you'd like to track the status of 0.3 developing, you can watch this file: PLANNING. This is the planning document that we will be using until we're ready to start adding tickets to launchpad.

I'm excited, and if you're an Exaile fan, you should be too. Exaile 0.3 will be pretty awesome.

P.S. Thanks Aren :)

April 17, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Exaile LastFM Proxy Plugin

A few versions ago, Exaile had Last.FM streaming support using LastFMSource - a pygst plugin created by Philippe Normand of Elisa. It worked... sort of. Every other time you tried to connect to LastFM station, Gstreamer would lock up entirely, taking Exaile out with it. Not being able to fix this problem, it was eventually removed from Exaile entirely.

Enter: LastFM Proxy. This is a program written in python created to connect to LastFM and start streaming the music to a proxy that you can connect to on your local machine using any music player that supports HTTP streaming.

After a bit of hacking (and really, this is some seriously hackish stuff), I've created a plugin for Exaile called "LastFM Radio" that (mostly) seemlessly integrates LastFMProxy into Exaile. To the user, it appears to just be a Radio Panel plugin like the current "Shoutcast Radio" plugin. The user just clicks on the station they want to listen to, and it starts playing. They can "Skip", "Ban", or "Love" tracks just like in the LastFM native player.

It still needs some work, but overall, I'm pretty pleased with how well it works. Give it a try!

Note: You must be using the latest bzr version of Exaile for this plugin to work. You can get instructions on doing that from Exaile's downloads page.

September 15, 2008

Dennis Muhlestein
nonic
All My Brain
» Sharing git branches

I've been learning git lately. Here are a few tips for sharing branches I've collected during the past few weeks. Create a branch In git, branches are stored on your local machine. Even the commonly named "master", is just a branch on your local machine. Master is simply set up to track a branch [...]

September 11, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Exaile 0.3 Roundup

A nice fellow emailed and asked me if I could post a monthly (possibly weekly) roundup on Exaile 0.3 so that people can follow what's going on. It sounded like a good idea to me, so here's the first one.

We've pretty much ironed out the storage details, and gotten playback/playlists figured out. What we have now is a fully functioning media player. The things that are still missing are:

  • Preferences dialog of some sort. We haven't even started on this, however, I feel that the one in 0.2 was pretty well written and could probably be used.
  • Cover art manager
  • Lyrics manager
  • Device manager plugins (for things like Ipods, other mp3 devices)
  • Visualizations
  • Rating system
With these items missing, there have been a lot of requests for an alpha release. I'm thinking we could probably get everything together and release 0.2.14 and 0.3alpha at the same time. Any comments?


Hans Fugal
no nic
The Fugue :
» Touch Typing

Steve Yegge has posted an funny, irreverent, and above all excellent argument for touch typing. I highly recommend it even if you do touch type.

I am downright flabbergasted by some of the comments though. There are hunt-and-peck folks defending their inability to touch type as lifestyle choice based on the belief that they will get RSI. People justifying typing slow because it saves them from wasting time chatting or writing long emails. There are some interesting claims from 2–4 finger typists that they can type without looking at 70wpm (this is certainly possible), and choosing not to learn to touch type the "right way" because it will give them RSI (this is certainly ludicrous).

Typing is a vital skill if you work in IT, especially programming. Of this there is no doubt, rationalizing strangers aside. I simply cannot imagine being stuck typing at 10wpm or less. It would be like being stuck behind a pair of tractors on the freeway going 20 mph. For the rest of your life.

Last I checked I type about 65 wpm on average. I could probably go faster, but I never have felt the need. I can type as fast as I think when programming. If I were a stream-of-consciousness novelist or a secretary, I could probably make use of a faster typing speed. As it is, 60–70wpm seems to be a sweet spot for me.

I'd like to discuss the ridiculous RSI claims. Yes, if you type all day without breaks you can get RSI. There are certain things you can do to mitigate or exacerbate this for a given amount of typing and typing speed. If you tried to go lightning fast all the time you might hasten the onset of RSI. But I argue that the absolute worst thing you can do if you're afraid of RSI is to not touch type. RSI means Repetitive Stress Injury, from repetitively performing certain motions until your body starts to break down. Smaller more relaxed motions are less stressful on your body than large stiff motions. If you touch type well, your hands are relaxed, your fingers float over the keys, and movement is minimal. Of course you still need to take care—take breaks, spend some time thinking without typing or drawing pictures on paper, proper nutrition, etc. But the biggest thing you can do to prevent RSI is to have proper form. And maybe learn dvorak (I still use qwerty because I find sysadmin and programming to be tedious with dvorak, but I don't spend most of my time actually typing).

On the other hand, if you hunt and peck 24/7 guess how much more movement—repetitive movement—your body is enduring? Ever heard of tennis elbow? RSI isn't the exclusive privilege of touch typists. If you type slow enough that you can't possible get RSI, you are irrelevant. If you type fast enough to be productive but don't have good form, you are setting yourself up for RSI. If you're RSI-prone or just paranoid, go learn dvorak now or find a job that doesn't require much typing.

I'd add to Steve's exhortation to learn to touch type, that if you do touch type but you feel your form is off, you have low accuracy, or you feel that your fingers are stiff, do some conscientious practice. Focus on accuracy and relaxation first, then speed. Enhancing your typing skills is a great benefit if you spend a lot of time typing, although learning to touch type in the first place is obviously a much bigger payoff.

Let's continue to learn from musicians: correct form (including relaxed posture and keep those wrists off the keyboard/desk), accuracy, then speed.


Scott Paul Robertson
spr
Spr: The Ramblings
» Rambling on Git

So during my UTOSC presentation I add some spare time, and ended up doing a "Git in Five Minutes" demo. I've done a written version for everyone to enjoy. So yes, I've written a Git tutorial.

Oh, and this Git Magic tutorial is pretty good too.

September 6, 2008

Dennis Muhlestein
nonic
All My Brain
» Custom Derived Classes for wxPython XRC resources

First of all, this isn't a topic that is bran new or which requires new documentation. I have learned a few quirks about the process for creating custom controls, panels, frames, and other elements with XRC files in wxPython and I thought I'd write up a little post. Let me point you to the two [...]


Adam Olsen
synic
Vimtips Latest Articles
» Django 1.0!!!

Django 1.0 is finally here!!!

I figured I'd just announce my excitement. So far, I've migrated two websites to it (one being this blog, the other being a much larger app for work), and haven't really had any problems. Following the Backwards Incompatable Changes on their Wiki made it fairly painless.

Congratulations to the Django Project!

P.S. I know I'm going to get some guff for this, but it's a breath of fresh air to be working in Python/Django at work instead of our hacked together CGI/Perl system.

August 9, 2008

Dennis Muhlestein
nonic
All My Brain
» How much overhead does C++ bring compared to straight C?

The other day, I had a conversation about putting C code onto an embedded chip. I wondered if it was possible to put C++ code on there. The gist of the conversation was that the C++ libraries had a lot of overhead and the executable size would be too large for the space [...]

August 6, 2008

Dennis Muhlestein
nonic
All My Brain
» 3 Optimizations for speeding Visual C++ compiled code.

For fun, I participated in a programming contest. Instead of describing the process this time, I thought I'd include a function. Can you guess what it does? I'm changing some of the variable names so it isn't obvious.   unsigned short result [dim][dim]; void foo(const string& info1, const string& info2, string& ret_val) {   for (int [...]

July 20, 2008

Doran Barton
fozzmoo
Fozzolog
» Perl Basics: Using CGI.pm

Perl is over twenty years old, but it continues to evolve as a programming language. When Perl 6 is released to the world, we're going to see an incredibly modern language that is adaptable to tackle many of the challenges faced by programmers today including internationalization/localization, Internet networking, object orientation, and more.

But this blog post isn't about Perl 6. This is the first in a series of posts designed to help people ease into Perl as a web development language and is influenced largely by tutorials and seminars I've given in person and online about using Perl as a web development tool.

Perl was embraced for web development in the early and mid 1990s because it had already become a powerful language for text-processing and system administration. As such, it was a natural first choice for developing web applications.

Perl programmers at the time adapted public domain algorithms into Perl code to process HTML forms, but the results were not pretty.


my $hashRef = {};
my $buffer = "";

if ($ENV{'REQUEST_METHOD'} eq 'GET') {
    $buffer = $ENV{'QUERY_STRING'};
}
else {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}

foreach (split(/&/, $buffer)) {
    my($key, $value) = split(/=/, $_);
    $key   = decodeURL($key);
    $value = decodeURL($value);
    %{$hashRef}->{$key} = $value;
}

sub decodeURL {
    $_ = shift;
    tr/+/ /;
    s/%(..)/pack('c', hex($1))/eg;
    return($_);
}

No wonder Perl is often labeled as "unreadable!"

Thankfully, Lincoln Stein came along and gave us CGI.pm-- a Perl 5 module that makes several tasks the Perl web developer is commonly faced with, easier:

  • Generating good HTTP headers
  • Parsing form data
  • Generating HTML
  • Handling file uploads
  • Debugging HTML form processes
  • ...and more

Web developers often fail to realize they take on a greater level of responsibility when they leave the realm of static HTML pages, images, MP3 files, etc. served up by a HTTP server like Apache and enter the world of dynamic content generation, interactive web applications, and forms and form processors.

Web developers must write code to generate headers for the client that would otherwise be handled by the web server. This includes, at a minimum, a Content-type header, but may also include Content-length, Content-disposition, or Location. Developers must also provide the client with an HTTP status code (e.g. 200, 404, 302, etc.).

You may use CGI.pm using object-oriented syntax or not. I prefer to use the object-oriented syntax because it means I'm in step with other Perl modules I employ in my code.


use CGI;

my $q = new CGI;
print   $q->header('text/html'),
        $start_html(    -title =>   'React' );

my $answer = $q->param('foo');
if($answer eq 'bar') {
    print $q->p("You answered correctly!");
}
else {
    print $q->p("That is incorrect.");
}

print $q->end_html;

This example generates different content based on the value of a form variable (foo) passed in. If this script were named react.cgi then it might be called with a URL like react.cgi?foo=bar.

Notice the code above uses the header() function to generate a valid HTTP header. There are many options you may pass to this function but if you pass one scalar string as in this example, it will use that data to generate a Content-type header.

The above above demonstrates some of CGI.pm's HTML-generation capabilities (the use of the p() function to generate paragraph tags around content and the use of the start_html() and end_html() functions to properly form the beginning and end of an HTML document and generate the necessary title tags in the header.)

The above example also shows how you may use CGI.pm to access form variables (the param() function).

For a couple years, I used CGI.pm quite heavily in my web development tasks. I grew very attached to its HTML-generation capabilities and the fact that if your HTML is generated from CGI.pm code, it will always be valid, start tags will always have matching end tags, and so forth. For example, here is a snippet of code I wrote circa 1999-2000:


print   $q->start_form(
           -method=> 'POST',
            -action => 'add_event.cgi'),
         $q->hidden({-name=>'r'}),
         $q->table(
            $q->Tr(
                $q->td(
                    _event_form($q)),
                $q->td({
                    -valign=>'top',
                    -align=>'left'}),
                    $q->submit({
                        -name=>'c',
                        -value=>'Save Event Info'}),
                    $q->br,
                        $q->submit({
                            -name=>'c',
                            -value=>'Cancel'}))),
         $q->end_form;

There are definite advantages to writing code this way, but the disadvantages are numerous, especially if you intend for your application to be maintained by someone other than yourself. If you intend to have a web designer who has no Perl competence work on the layout, this type of code will have them running away, screaming, and flailing their arms wildly.

That being said, if you need to throw together a simple, self-encapsulated interactive web page, doing everything with CGI.pm isn't a bad way to go.

In most cases, CGI.pm is already installed on your Linux system. To read all about it, type perldoc CGI at your shell command prompt, or go to http://search.cpan.org/perldoc?CGI with your favorite web browser.

What's next?

Well, what's next partly depends on the type of feedback I get from this post, if any. Generally, I plan to talk about templating, database interaction, and more. But, if people have some specific things they would like to see my spin on, I'd be more than happy to oblige.

July 5, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Building Cocoa GUIs in Python with PyObjC, Part Four

Creating an Open Dialog

Our controller doesn't really do anything at this point. We'll begin by adding an open dialog for the user. This will require us to really delve into the Objective C bridge provided by PyObjC. We'll start by reading some documentation that ships with Xcode.

Let's launch the local documentation browser in Xcode. Under "Help" click "Documentation". In the newly opened documentation browser select the "Mac OS X 10.5" documentation set and search for NSOpenPanel. This is the class we'll be working with to create our open dialog. Have a look through the documentation, then let's code.

First we do some basic stuff, creating the object and setting some permissions. A modified open method on our controller.py looks like this:

filetypes = ('mp3', 'ogg', 'mp4', 'flac', 'm4a', 'm4p')

@IBAction
def open_(self, sender):
    panel = NSOpenPanel.openPanel()
    panel.setCanChooseDirectories_(NO)
    panel.setAllowsMultipleSelection_(NO)

This gives us an NSOpenPanel object, turns off directory selection and multiple selections. The filetypes tuple contains the extensions that we allow the user to select, which will be used when we start the dialog.

The first open dialog we'll write will be modal. Modal dialogs block other actions in the application until the window finishes. It is the easiest way to do an open dialog. Have a look at the function runModalFortypes: in the documentation. Now to add to the open method:

    ret_value = panel.runModalForTypes_(self.filetypes)
    if ret_value:
        print "Open %s" % panel.filenames()
    else:
        print "Canceled"

Go ahead and run this code.

open window

A few things to note:

  • The only files that could be selected are contained in the filetypes tuple.
  • The return value is not the button clicked, rather it is 1 on "Open" and 0 on "Cancel".

Since our app really doesn't need to take up so much screen real estate we'll use a sheet instead. This is attached to the window that creates it, and looks a whole lot cooler. Unfortunately it is more difficult to use. Have a look at beginSheetForDirectory:file:types:modalForWindow:modalDelegate:didEndSelector:contextInfo: in the documentation. Now put in this code in place of what we just added:

    panel.beginSheetForDirectory_file_types_modalForWindow_modalDelegate_didEndSelector_contextInfo_(
            os.getcwd(), None, self.filetypes, NSApp().mainWindow(),
            self, 'openPanelDidEnd:panel:returnCode:contextInfo:', 0)

We'll need a new method on the class controller:

@AppHelper.endSheetMethod
def openPanelDidEnd_panel_returnCode_contextInfo_(self, panel, returnCode,
        contextInfo):
    if returnCode:
        print "Open: %s" % panel.filenames()
    else:
        print "Cancel"

Run this and you'll see the lovely open sheet that behaves like our previous modal dialog.

open sheet

Items of note:

  • This really demonstrates "replace : with _" for method names. Method names get really long very quickly.

  • The @AppHelper.endSheetMethod decorator is a convience shortcut for the type signature decorator @signature('v@:@ii').

  • The SEL type converts to a correctly formatted string. The Objective C

    @selector(openPanelDidEnd:panel:returnCode:contextInfo:)
    

    becomes

    'openPanelDidEnd:panel:returnCode:contextInfo:'
    

By looking through the official documentation on NSOpenPanel and this you should be able to get a very good feeling for how to translate between Objective C and PyObjC. The code for this step is available in git as always.

In the next installment we'll get QuickTag reading and writing audio tags, finishing the controller.

References

<< Part3: Writing A Python Controller

June 25, 2008

Jordan Gunderson
jordy
Jordy Blog
» Math Puzzle: Enumerating Combinatorial Result Sets

Warning: Big-time nerder alert! If you find overt nerdyness offensive, zone out now or just click right on through.

I’m neither a computer scientist not a mathematician (and it probably shows), but I’m curious enough to poke around a bit. Lately I’ve been having fun with combinatorics.

One of the programs I often write as I’m learning a new programming language is a cryptogram maker. A cryptogram is basically it a word puzzle where each letter of a piece of text has been replaced by another letter according to a randomized substitution cipher. Here’s an example:

BEFORE: The quick brown fox jumped over the lazy dogs.
AFTER : QGF JKHDY ZESRP WSV CKUIFN SOFE QGF BMXL NSTA.
LETTER : ABCDEFGHIJKLMNOPQRSTUVWXYZ
CYPHER : MZDNFWTGHCYBUPSIJEAQKORVLX

Anyway, I’ve long known the total number of possible cypher keys (supposing that any letter can be replaced with itself), but I’ve spent several boring church meetings thinking about another simple combinatorics problem. Of course, it’s probably pretty basic to one who has studied combinatorics, but I’ll put it to you just the same.

The question was:

How do I process any given cypher key so that an ordered ’solution number’ can be derived from it (or vice versa) without iterating through the possible cyphers (or solutions).

After having the answer suddenly dawn on me the other night, I now put you to the test. And to make it only slightly more interesting, the first person to comment with the answers and an accurately described algorithm (complete with the basic math behind it) wins a whopping $5 cash prize mailable by me. Note that just writing a script to cycle through does not count because the whole point is not to iterate through all the cyphers. Also, I shrunk the alphabet to make it nicer on you. :)

Solution Number Cypher
1 ABCDEFGHIJ
2 ABCDEFGHJI
3 ABCDEFGIHJ
4 ABCDEFGIJH
5 ABCDEFGJHI
6 ABCDEFGJIH
7 ABCDEFHGIJ
? HDICAGEJFB
3096542 ?
? JIHGFEDCBA

Show your logic!  (Hint you can easily do the math on half a sheet of paper once you know the algorithm.)


Aside: This is not a particularly problematic problem (since I really had no need for a solution), but the math is fun just the same. I tried to think of a story problem that would make the math more compelling and less numerically intensive (without truncating the alphabet), but I sort of got bored of writing it. Maybe I’ll share what I came up with later.

June 24, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Building Cocoa GUIs in Python with PyObjC, Part Three

Writing A Python Controller

First let's add your new controller into the GUI. Add an object from "Objects & Controllers" into your GUI. Now click on it and bring up the "Identity" tab in the inspector. The first drop-down lets you select a class, find "controller" and pick it.

Now Open up your newly created controller.py with your favorite text editor, and we'll begin.

#
#  controller.py
#  QuickTag
#
#  Created by Scott Paul Robertson on 6/11/08.
#  Copyright (c) 2008 __MyCompanyName__. All rights reserved.
#

from objc import YES, NO, IBAction, IBOutlet
from Foundation import *
from AppKit import *

class controller(NSWindowController):
    pass

There are two parts we will be adding, the Outlets (variables) and Actions (methods). first lets add a few outlets to the class controller.

    name = IBOutlet()
    artist = IBOutlet()
    albumArtist = IBOutlet()
    album = IBOutlet()
    ...

These class variables can now be connected to various fields in your GUI. In Interface Builder you simply control-click your controller object and drag to the text field that you want to attach that variable to. Wire up the fields as you would expect.

Next we start by adding some actions to the controller. First we add the method awakeFromNib which is called at window creation, allowing us to act at application start time.

    def awakeFromNib(self):
        print "awake"

Now let's write a method that we will wire the "Save & Close" button to.

    @IBAction
    def save_(self, sender):
        print "Save"

    @IBAction
    def saveClose_(self, sender):
        print "Saving and Closing"
        self.save_(sender)

Connect these to buttons or menu entries by control-clicking the button and dragging to the controller. Now if we run the application the console will print messages every time we hit a connected button.

We'll go ahead and write similar functions for our other actions and wire them up. controller.py is the final result of this process.

In the next part we'll look into doing something useful with our controller.

<< Part 2: Starting A Cocoa-Python Application | Part 4: Creating an Open Dialog >>

June 13, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Drafts Do Not Go Into The Feed

Remember kids, do not feed your feed drafts. It is unprofessional.

Blog updated to filter out drafts in the RSS feed.

June 12, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Building Cocoa GUIs in Python with PyObjC, Part Two

Starting A Cocoa-Python Application

Getting started is easy. First, install the Developer Tools if you haven't yet. Now launch Xcode and start a new project. Select "Cocoa-Python Application". You'll be presented with the following window.

xcode project window

Before we begin, go ahead and double-click on "MainMenu.xib (English)" and put together your interface. We're going to make a tag editor, so give yourself a window with:

  1. Text fields for things like: Name, Artist, Album, Track Number, Genre.
  2. Buttons for two actions: Revert and Save & Close.
  3. Menu items for: Open, Save, Revert to Saved, Close. Keep the edit menu, window menu, and help.

If you prefer, use mine. It already as all the needed connections made, the code is all that is missing.

Now we will start the controller. Create a new file for the project of the type "Python NSWindowController subclass". Name it something like "controller.py".

To tell the system to actually use our controller code we need to make a quick edit. Our first edit will be to main.py. Add the following where the other import statements are:

import controller

Some PyObjC Basics

We're ready to start building our controller. But first let's go over a few basics.

  1. Outlets. If we want to attach values to variables we need to have outlets. You add these as class variables to the controller and assign them the value returned from the function IBOutlet:

    form_field = IBOutlet()
    
  2. Actions. If we want to attach actions to functions we need to inform the system what methods are eligible. This is done by adding the IBAction decorator to a method:

    @IBAction
    def clickButton_(self, sender):
    
  3. Colons. Objective C loves colons. It uses them to separate return values, method names, and arguments. The method:

     - (IBAction)convert:(id)sender;
    

    becomes

    @IBAction
    def sender_(self, sender):
    

    So we simply change colons to underscores. Easy.

Part 3: Writing A Python Controller >>

» Building Cocoa GUIs in Python with PyObjC, Part One

Introduction

Building GUIs for Apple OS X traditionally meant you would code in Objective C. To overcome this issue people have made programming bridges to allow development in other languages. PyObjC is the project that enables Python programmers to take advantage of Cocoa, Apple's development environment. I recently began learning how to use PyObjC, and how to make (almost) pure Python GUI applications.

PyObjC isn't new, it has been around for a while, and there is actually a pretty good tutorial for wiring an interface up with Python. Leopard (10.5) ships with Python 2.5 and PyObjC 2.0, meaning there is nothing we need to install. Additionally Apple has also shipped support for Python in Xcode. This makes certain things much easier.

The current tutorial directs a user to build an interface, and then take the generated Nib file* and run a script that generates the appropriate controller. From here the user can create a fully working app bundle without needing Objective C. There are a few annoying things:

  • To get your various view to controller connections you have to create Objective C header files and wire with that. Those then are translated to the generated Python file where you implement them.
  • Every time you change the way the interface is wired to the controller, you need to re-generate the Python file, and merge in your changes.

Xcode 3.0, which ships with Leopard, provides support for Python, allowing the controller to be developed completely in the language. Interface Builder knows how to understand Python files, so you can attach actions and variables directly, with only a few necessary tricks.

In this series I will go through the steps to build a simple, but useful, application. There will be no Objective C written, only Python.

* Xcode 3.0 defaults to version 3 Nib files, which will not work with the PyObjC tutorial. You'll have to Save As a version 2 Nib file.

Part 2: Starting A Cocoa-Python Application >>

» Build Cocoa GUIs in Python with PyObjC, Part Two

Starting A Cocoa-Python Application, the basics of PyObjC

Getting started is pretty easy. First, install the Developer Tools if you haven't yet. Now launch Xcode and start a new project. Select a "Cocoa-Python Application". You'll be presented with the following window.

xcode project window

Before we begin, go ahead and double-click on "MainMenu.xib (English)" and put together your interface. If you prefer, use mine.

Now we will start the controller, create a new file for the project of the type "Python NSWindowController subclass". Name it something like "controller.py". Our first edit is to main.py, add the following where the other import statements are:

import controller

We're ready to start building our controller. But first let's go over a few basics.

  1. Outlets. If we want to attach values to variables we need to have outlets. You add these as class variables to the controller and assign them the value of IBOutlet:

    form_field = IBOutlet
    
  2. Actions. If we want to attach actions to functions we need to inform the system what methods are eligible. This is done by added the IBAction decorator to a method:

    @IBAction
    def clickButton_(self, sender):
    
  3. Colons. Objective C loves colons. It uses them to separate return values, method names, and arguments. The method:

     - (IBAction)convert:(id)sender;
    

    becomes

    @IBAction
    def sender_(self, sender):
    

    So we simply change colons to underscores. Easy.

» Build Cocoa GUIs in Python with PyObjC, Part One

Introduction

Building GUIs for Apple OS X traditionally means you will code in Objective C. To overcome this issue people have made programming bridges to allow development in other languages. PyObjC is the project that enables Python programmers to take advantage of Cocoa, Apple's development environment. I recently began learning how to use PyObjC, and how to make (almost) pure Python GUI applications.

PyObjC isn't news. It has been around for a while, and there is actually a pretty good tutorial for wiring an interface up with Python. Of course with OS X Leopard (10.5) Apple has shipped with Python 2.5, and the latest version of PyObjC. With that, they have also shipped with support for Python in Xcode. This allows the programmer to more easily develop in Python, skipping a few tedious steps.

The current tutorial directs a user to build an interface, and then take the generated Nib file (a version 2.0 save which is not the default in Leopard) and run a script that generates the appropriate controller. From here the user can create a fully working app bundle without needing Objective C. Except for building the interface. To attach methods to actions you have to make an Objective C header. That's not so bad, but it can be annoying. Additionally if you change things in the interface, or add actions you will have to regenerate the Python controller and merge it with your previous version.

Xcode 3.0, which ships with Leopard, provides support for Python, allowing the controller to be developed completely in the language. Interface Builder knows how to understand Python files, so you can attach actions and variables directly, with only a few necessary tricks.

In this series I will go through the steps to build a simple, but useful, application. There will be no Objective C written, only Python.

Part 2: Starting A Cocoa-Python Application, the basics of PyObjC

September 23, 2008

Dennis Muhlestein
nonic
All My Brain
» Timing C/C++ Code on Linux

For my last post, I played around with C++ and a little programming competition. While on the topic, I decided I'd get slightly more serious and enter the next challenge. One of the things that slightly annoyed me during the process is having to compile/run the program on Windows to enter the competion, while I'm [...]

June 9, 2008

John Anderson
sontek
sontek ( John M. Anderson )
» Debugging Mono with Trace.WriteLine and Debug.WriteLine

The point of Trace.WriteLine and Debug.WriteLine is to give you the ability to monitor certain areas of your code when debugging or tracing but avoid cluttering your screen or hard drive with useless output when you aren’t. When most people stumble upon Trace/Debug they think it should “Just work”–without any setup–this isn’t the case.

Another great benefits of using Trace/Debug instead of the old Console.WriteLine is you can define exactly where to log to in your app config or with environment variables, so sometimes you might want direct output to the Console but other times you might want to log to a file.

To get your output from Trace/Debug you first need to define either DEBUG or TRACE in your preprocessor directives.

You can do this in code by placing:

#define TRACE

in your code or by passing it at compile time:

gmcs -d:TRACE

after you have your preprocessor directives setup, you have to define where to log to. You can do this by defining it in your app config:

<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="TextWriterOutput.log" />
        <remove name="Default" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

or you can define it with the environment variable MONO_TRACE_LISTENER:

export MONO_TRACE_LISTENER=Console.Out

and then you can start your logging with System.Diagnostics.Trace.WriteLine(”Hello World”).

To learn more about Trace/Debug check out:the docs here and here. To learn more about other environment variables you can use with mono ‘man mono’ or click here.

June 7, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Exaile 0.3

Exaile is currently undergoing an almost complete rewrite. Why? Because the codebase could be better. Recently, thanks to Aren Olson, the 0.3 branch has been taking off. Already the code is a lot better, and will be a lot easier to add things to in the future.

As of this writing, you can create a collection, based on different libraries (directories). For each one of these directories, you can set a rescan interval, and/or have the library be watched by pyinotify for changes. You can create playlists, smart playlists, play these playlists in order or shuffle and/or on repeat. I am currently using it as my default player.

However: none of this can be done using a gui yet. This can all be done easily by using Exaile 0.3's pretty good looking internal API. Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python

import exaile as ex
from xl.playlists import Playlist
from xl.collection import Library

ex.main()
exaile = ex.exaile

# scan my music directory
exaile.collection.add_library(Library("/home/synic/media/music"))
exaile.rescan_libraries()

# Create a playlist with the artist Thievery Corporation, but exclude anything
# from the Versions album

pl = Playlist()
tracks = exaile.collection.search('artist=="Thievery Corporation" NOT '
    'album="Versions"')

pl.add_tracks(tracks)
pl.toggle_random()  # I usually play my music on shuffle :)

exaile.queue.set_current_playlist(pl)
exaile.queue.next() # start playback of the playlist

# ok, let's quit.  This will save the collection to the database, settings,
# etc.
exaile.quit()


Developing this way will make it much easier to add a gui (or even more than one type of gui. Someone could create a wxPython gui while we're creating the familiar pygtk gui).

We're also adding a test suite which should make for stabler releases once the first 0.3 release is ready.

If you'd like to track the status of 0.3 developing, you can watch this file: PLANNING. This is the planning document that we will be using until we're ready to start adding tickets to launchpad.

I'm excited, and if you're an Exaile fan, you should be too. Exaile 0.3 will be pretty awesome.

P.S. Thanks Aren :)

June 17, 2008

Dennis Muhlestein
nonic
All My Brain
» The Difference Between Dijkstra’s Algorithm and A*

Over the last couple weeks, I've had an interest in brushing up my C++ skills. Friday, I came across a programming challenge that looked somewhat interesting and I thought I'd give it a shot. The object was to find the lowest cost route between 10 cities encoded in a map of integers. Each integer [...]

August 6, 2008

Dennis Muhlestein
nonic
All My Brain
» GTK+ programs with GtkBuilder and dynamic signal handlers.

Well, I decided to review some GTK+ and Gnome development lately. With GTK+, a nice way to create a user interface is with the Glade Interface Designer. Glade produces an xml file with a glade-interface element that can be loaded by libglade. You can then change attributes of the user interface without [...]

May 11, 2008

John Anderson
sontek
sontek ( John M. Anderson )
» Python with a modular IDE (Vim)

On Thursday, May 9th, 2008 the Utah Python User Group decided to settle the debate that has plagued us developers since the beginning of time: If you were a programming language, what editor would you use?

I was tasked with showing Eclipse with the PyDev plugin in all its glory–but we all know–real men / developers don’t use IDE’s, so we are going to talk about using Python and Vim together, reaching a state of Zen that the Dalai LLama would be jealous of and establishing more Feng Shui than Martha Stewart’s Kitchen.

Freely jump between your code and python class libraries

There are 2 ways to add your ability to jump between python class libraries, the first is to setup vim to know where the Python libs are so you can use ‘gf’ to get to them (gf is goto file). You can do this by adding this snippet to your .vimrc:

python << EOF
import os
import sys
import vim
for p in sys.path:
    if os.path.isdir(p):
        vim.command(r"set path+=%s" % (p.replace(" ", r"\ ")))
EOF

With that snippet you will be able to go to your import statements and hit ‘gf’ on one of them and it’ll jump you to that file.

Continuing accessibility of the Python class libraries we are going to want to use ctags to generate an index of all the code for vim to reference:

$ ctags -R -f ~/.vim/tags/python.ctags /usr/lib/python2.5/

and then in your .vimrc

set tags+=$HOME/.vim/tags/python.ctags

This will give you the ability to use CTRL+] to jump to the method/property under your cursor in the system libraries and CTRL+T to jump back to your source code.

I also have 2 tweaks in my .vimrc so you can use CTRL+LeftArrow and CTRL+RightArrow to move between the files with more natural key bindings.

map <silent><C-Left> <C-T>
map <silent><C-Right> <C-]>

You can also see all the tags you’ve been to with “:tags”

Code Completion

To enable code completion support for Python in Vim you should be able to add the following line to your .vimrc:

autocmd FileType python set omnifunc=pythoncomplete#Complete

but this relies on the fact that your distro compiled python support into vim (which they should!).

Then all you have to do to use your code completion is hit the unnatural, wrist breaking, keystrokes CTRL+X, CTRL+O. I’ve re-bound the code completion to CTRL+Space since we are making vim an IDE! Add this command to your .vimrc to get the better keybinding:

inoremap <Nul> <C-x><C-o>

Along with code completion, you will also have call tip support. Here is a screenshot:

Vim with Code Completion
Documentation

No IDE is complete without the ability to access the class libraries documentation! You’ll need to grab this vim plugin. This gives you the ability to type :Pydoc os.path or use the keystrokes <Leader>pw and <Leader>pW to search for the item under the cursor. (Vim’s default <Leader> is “\”). Here is a screenshot:

Vim with PyDoc integration

Syntax Checking

Vim already has built in syntax highlighting for python but I have a small tweak to vim to give you notifications of small syntax errors like forgetting a colon after a for loop. Create a file called ~/.vim/syntax/python.vim and add the following into it:

syn match pythonError "^\s*def\s\+\w\+(.*)\s*$" display
syn match pythonError "^\s*class\s\+\w\+(.*)\s*$" display
syn match pythonError "^\s*for\s.*[^:]$” display
syn match pythonError “^\s*except\s*$” display
syn match pythonError “^\s*finally\s*$” display
syn match pythonError “^\s*try\s*$” display
syn match pythonError “^\s*else\s*$” display
syn match pythonError “^\s*else\s*[^:].*” display
syn match pythonError “^\s*if\s.*[^\:]$” display
syn match pythonError “^\s*except\s.*[^\:]$” display
syn match pythonError “[;]$” display
syn keyword pythonError         do

Now that you have the basics covered, lets get more complicated checking added. Add these 2 lines to your .vimrc so you can type :make and get a list of syntax errors:

autocmd BufRead *.py set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%')\"
autocmd BufRead *.py set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m

You will have the ability to to type :cn and :cp to move around the error list. You can also type :clist to see all the errors, and finally, sometimes you will want to check the syntax of small chunks of code, so we’ll add the ability to execute visually selected lines of code, add this snippet to your .vimrc:

python << EOL
import vim
def EvaluateCurrentRange():
eval(compile('\n'.join(vim.current.range),'','exec'),globals())
EOL
map <C-h> :py EvaluateCurrentRange()

Now you will be able to visually select a method/class and execute it by hitting “Ctrl+h”.

Browsing the source

Moving around the source code is an important feature in most IDE’s with their project explorers, so to get that type of functionality in vim we grab the Tag List plugin. This will give you the ability to view all opened buffers easily and jump to certain method calls in those buffers. Here is a screenshot of it in action:

Vim TagList Plugin

The other must-have feature of an IDE when browsing code is being able to open up multiple files in tabs. To do this you type :tabnew to open up a file in a new tab and than :tabn and :tabp to move around the tabs. Add these to lines to your .vimrc to be able to move between the tabs with ALT+LeftArrow and ALT+RightArrow:


map <silent><A-Right> :tabnext<CR>
map <silent><A-Left> :tabprevious<CR>

Debugging

To add debugging support into vim, we use the pdb module. Add this to your ~/.vim/ftplugin/python.vim to have the ability to quickly add break points and clear them out when you are done debugging:

python << EOF
def SetBreakpoint():
    import re
    nLine = int( vim.eval( 'line(".")'))

    strLine = vim.current.line
    strWhite = re.search( '^(\s*)', strLine).group(1)

    vim.current.buffer.append(
       "%(space)spdb.set_trace() %(mark)s Breakpoint %(mark)s" %
         {'space':strWhite, 'mark': '#' * 30}, nLine - 1)

    for strLine in vim.current.buffer:
        if strLine == "import pdb":
            break
    else:
        vim.current.buffer.append( 'import pdb', 0)
        vim.command( 'normal j1')

vim.command( 'map <f7> :py SetBreakpoint()<cr>')

def RemoveBreakpoints():
    import re

    nCurrentLine = int( vim.eval( 'line(".")'))

    nLines = []
    nLine = 1
    for strLine in vim.current.buffer:
        if strLine == ‘import pdb’ or strLine.lstrip()[:15] == ‘pdb.set_trace()’:
            nLines.append( nLine)
        nLine += 1

    nLines.reverse()

    for nLine in nLines:
        vim.command( ‘normal %dG’ % nLine)
        vim.command( ‘normal dd’)
        if nLine < nCurrentLine:
            nCurrentLine -= 1

    vim.command( ‘normal %dG’ % nCurrentLine)

vim.command( ‘map <s-f7> :py RemoveBreakpoints()<cr>’)
EOF

With that code you can now hit F7 and Shift-F7 to add/remove breakpoints. Then you just launch your application with !python % (percent being the current file, you can declare your main file here if its different).

Another tweak I use is to have my vim inside screen with a horizontal split, that way I can see the python interpreter and debug while still having vim there so I can easily fix my code. Here is a screenshot of that in action:

Vim with Screen

Snippets

A great time saver with stanard IDE’s is code snippets, so you can type a few key strokes and get a lot of code out of it. An example of this would be a django model, instead of typing out the complete declaration you could type ‘mmo<tab><tab>’ and have a skeleton of your model done for you. To do this in vim we grab the Snippets EMU plugin.

Check out a great screencast of snippetsEmu in action here

You can get my full setup here

Emacs

Here is a great post on how to do the same with Emacs.

April 29, 2008

Dennis Muhlestein
nonic
All My Brain
» Using YUI to Create Nested Tabs

Recently, I was browsing the YUI JavaScript forums and found a post about nesting the tab control. I haven't done that before personally, but have done things where my tabs had Ajax or DHTML dependencies inside the tabs. I decided I'd take a whack at this one and see what I could come [...]

April 25, 2008

Dennis Muhlestein
nonic
All My Brain
» Using Multiple Python Environments With Gentoo

It's been some time since Python 2.5 became stable and released. Version 2.5 has plenty of new features that have helped me in deciding that it was time to go ahead and start using it for primary development of all my new projects. One of the reasons I was still using version [...]

April 19, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Full Code Navigation: Cscope

Not long ago we discussed ctags here, and how it can quickly let you navigate your code, helping you find definitions of variables and functions. You'll have taken notice that sometimes you want to navigate in the reverse: where is this function called, who includes this file, etc. Cscope builds a database of such information (and more). We can include it with ctags and have very impressive code searching.

If you want a detailed introduction, there is a great cscope and vim tutorial available. I'll just give you a quick run down of using it.

  1. At the base of your C or C++ source tree run cscope -R -b -q

  2. Add this to your .vimrc:

    if has("cscope")
      set cst
      set csto=1
      if filereadable("cscope.out")
        cs add cscope out
      endif
    endif
    
  3. Start Vim in the same directory as the generated cscope.out file. (If not, just do :cs add <cscope.out file>).

  4. To find where a function is called do :cs find c <function>. To find where a symbol is defined do :cs find s <symbol. You'll notice that if there are multiple matches a menu pops up to let you pick. This is the case for using CTRL-] on symbols as well.

  5. Make some handy mappings:

    nmap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
    nmap <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
    

Cscope can do many other searches. See the tutorial or just type :he cscope in Vim.

April 17, 2008

Adam Olsen
synic
Vimtips Latest Articles
» Exaile LastFM Proxy Plugin

A few versions ago, Exaile had Last.FM streaming support using LastFMSource - a pygst plugin created by Philippe Normand of Elisa. It worked... sort of. Every other time you tried to connect to LastFM station, Gstreamer would lock up entirely, taking Exaile out with it. Not being able to fix this problem, it was eventually removed from Exaile entirely.

Enter: LastFM Proxy. This is a program written in python created to connect to LastFM and start streaming the music to a proxy that you can connect to on your local machine using any music player that supports HTTP streaming.

After a bit of hacking (and really, this is some seriously hackish stuff), I've created a plugin for Exaile called "LastFM Radio" that (mostly) seemlessly integrates LastFMProxy into Exaile. To the user, it appears to just be a Radio Panel plugin like the current "Shoutcast Radio" plugin. The user just clicks on the station they want to listen to, and it starts playing. They can "Skip", "Ban", or "Love" tracks just like in the LastFM native player.

It still needs some work, but overall, I'm pretty pleased with how well it works. Give it a try!

Note: You must be using the latest bzr version of Exaile for this plugin to work. You can get instructions on doing that from Exaile's downloads page.


John Anderson
sontek
sontek ( John M. Anderson )
» Printing in GTK#

I just finished porting Tomboy’s print code to GTK so that we would be more portable and I thought other Mono apps looking to move from libgnomeprint or wanting to add printing support might find a code example helpful.

First, To start printing you do something like:

private void PrintButtonClicked (object sender, EventArgs args)
{
Gtk.PrintOperation op = new PrintOperation ();
op.BeginPrint += new BeginPrintHandler (OnBeginPrint);
op.DrawPage += new DrawPageHandler(OnDrawPage);

op.Run (Gtk.PrintOperationAction.PrintDialog, this.Window);
}

after the PrintOperation is set off you need to handle the BeginPrint event. The main things that need to be done are finding out how many lines will fit on a page and how many lines you have:

public void OnBeginPrint(object sender, Gtk.BeginPrintArgs args)
{
PrintOperation op = (PrintOperation)sender;
lines_per_page = (int)Math.Floor ((double)args.Context.Height / (double)font_size);
Gtk.TextIter start_iter, end_iter;
this.Buffer.GetBounds (out start_iter, out end_iter);
lines = this.Buffer.GetText (start_iter, end_iter, false).Split ('\n');
op.NPages = (int)Math.Ceiling ((double)lines.Length / (double)lines_per_page);
}

Finally, now that you have the printing setup, you need to actually render the data to be printed:

public void OnDrawPage(object sender, Gtk.DrawPageArgs args)
{
PrintOperation op = (PrintOperation)sender;
Cairo.Context cr = args.Context.CairoContext;

int line = args.PageNr * lines_per_page;
int num_lines = 0;
if (args.PageNr+1 != op.NPages)
num_lines = line + lines_per_page;
else
num_lines = lines.Length;

cr.MoveTo (0, 0);

for (int i = 0; i < lines_per_page && line < num_lines; i++)
{
Pango.Layout layout = args.Context.CreatePangoLayout ();
Pango.FontDescription desc = Pango.FontDescription.FromString (”sans ” + font_size);
desc.Size = (int)(font_size * Pango.Scale.PangoScale);
layout.FontDescription = desc;

layout.SetText (lines[line]);
Pango.CairoHelper.ShowLayout (cr, layout);
cr.RelMoveTo (0, font_size);
line++;
}
}

This does not take into account styles but will give you the basic idea of what needs to be done.

April 11, 2008

Dennis Muhlestein
nonic
All My Brain
» Using YUI components in a templated environment

If you develop sites anything like I do, you'll end up setting up a site wide layout and theme before you start coding any individual pages. I like to add YUI components where they are useful, but I've come across a couple little quirks that were annoying me. Here are my observations and [...]

April 7, 2008

Hans Fugal
no nic
The Fugue :
» Functional Floundering

Levi pointed me to a presentation on Clojure, "a dynamic programming language for the JVM". That's actually a pretty bland description. I'd describe it at least as a dynamic functional concurrency-oriented lispy language for the JVM. The presentation was interesting, though I wish I had been able to follow the ant colony demo (it's audio-only).

It awakened the oft-recurring "functional floundering" feeling. I've written a semester worth of scheme in a programming languages course. I've read the Erlang book and written a little Erlang code. I recently went through a graduate course in programming languages with emphasis on denotational semantics. I understand the lambda calculus, functional programming, etc. But I feel completely stymied whenever I think about actually programming in a functional language.

I'm not sure what the root is, but I'm sure it boils down to lack of practice. That undergraduate course aside, I haven't had any practice. And since that course was very handholding (too much in retrospect), I don't feel like I took any practical skill away from it. Yet I feel that in the future functional programming for concurrency will be important, even if I'm not convinced it will be essential.

So I don't have time right now to really rectify the situation, but that doesn't stop me from wondering—how does one learn practical functional programming? What problem sets do you work through to get the needed practice? I suppose the question can apply to learning any new language, but there is much paradigm carry-over between imperative languages (and probably between functional languages). Are there certain problems that will aid that paradigm shift? If you feel like you've developed functional chops, in any functional language, I'd like to hear in the comments how you got there, what you'd change in retrospect, and your advice for me and others like me.

April 2, 2008

Dennis Muhlestein
nonic
All My Brain
» Serving JavaScript Fast

I found this excellent writeup on serving JavaScript files posted on Digg.com. I think I'll convert some of those ideas to Python but I thought it worth posting here in the mean time with the link to the story. The next generation of web apps make heavy use of JavaScript and CSS. We’ll show you [...]

March 22, 2008

Scott Paul Robertson
spr
Spr: The Ramblings
» Navigating Man Pages in Vim

If you program in C you probably look to the man pages as a prime reference. There are a lot of different functions in the standard library. For example, what does this all mean?

sscanf(str, "%*d: %12[^a-zA-Z] 0x%4x %n", ...)

Luckily in Vim I can just press K over sscanf and in a window split I'll have the man page. Now this isn't a new feature, except that the man page opens in a Vim window not in a pager. This is a feature enabled by enabling a plugin that ships with Vim.

As an additional bonus the man page has syntax highlighting and is tagged so you can travel between man pages with CTRL-] and CTRL-T. Now when you see the references (like getc(3)) you can just scroll over and hit CTRL-] to view it.

To enable this plugin, and map K to use it, add to your .vimrc:

runtime ftplugin/man.vim
nmap K :Man <C-R>=expand("<cword>")<CR><CR>

Now you'll always have man pages at your finger tips without ever leaving Vim!

March 21, 2008

Paul Tomlinson
Keighvin
Wide Niche
» Persistence

Not too long ago I was fortunate enough to pick up an iPod Touch (bonus had come in from last year's work). The device has been remarkable, smaller than it looks and packing a nice little portable media punch. It also happens to be a fairly robust mobile computing platform, as evidenced by the strength of community development for the device even prior to the release of the official SDK. Being


John Anderson
sontek
sontek ( John M. Anderson )
» Debugging with strace

I was helping a friend debug a problem with gksu (gnomesu alternative) today and we chose to use strace which allows you trace system calls an application makes.

To monitor all system calls an application makes you can redirect the output to a file like so:

strace <command> 2> <file name>
or
strace <command> -o <file name>

These commands return the exact same results, the first command redirects stderr (standard error, which has the file descriptor 2) to the file, strace sends all output to stderr by default, the second command uses the built in -o argument which is much cleaner.

One of the first things I like to do with strace is to check if it is having trouble accessing a file, which I see a lot because the file doesn’t exist or the user executing the command does not have permission to access it, you can do that with these commands:

strace <command> 2>&1 |grep open
or
strace <command> -e open

Again, these commands will return similar results. The first command redirects stderr to stdout so you can use grep to filter the output. The second command is the preferred method because it actually uses the built in -e argument which will trace only the named system call (this is a comma separated list so you can do strace -e open,read).

The only other arguments that I’ve found really helpful are -ff which when used with -o will append the pid (process id) to the file name and -F which will also trace children.

March 20, 2008

Phil Windley
pjw
Phil Windley's Technometria
» Visualizing Workflow and Transparent Systems

I thoroughly enjoyed Jon Udell's interview with Ward Cunningham on IT Conversations. They talk a lot about Ward's efforts at the Eclipse Foundation to build transparent workflow systems. That is, as Jon puts it:

But what if you could find out, before pressing the Save button, what's going on in that black box? And what if your way of finding out wasn't by reading bogus documentation, but instead by probing the system itself using its own test framework?
From Ward Cunningham's Visible Workings « Jon Udell
Referenced Thu Mar 20 2008 08:42:43 GMT-0600 (MDT)

You'll want to read Jon's description of Ward's visible workings along with the podcast to get the most out of it. Better yet, I'd love to have a screencast of the system at work.

At one point Jon and Ward talk about how this might apply to eGovernment. Think about a button you could push at any point that would tell you how your current interaction with a government Web site was likely to proceed. I'd love to see it.

Tags: testing programming workflow itconversations egovernment