Printing Selectric

This is an IBM  Printing Selectric I plan to restore. It is probably an OEM version of the IBM 2741 it is a ruggedized teleprinter version of a regular IBM selectric typewriter. I do not have the control electronics. I am searching for a service manual. The only thing I’ve found is an operators manual

 A mouse apparently took up residence.  

This will take a while to trace so I’d prefer to find the manual

Label says MT/ST Model 775

This is the I/O connector I need to trace

Contact me bob.coggeshall at gmail dot com or @bobcoggeshall on twitter if you can help

A 50 year-old Teletype Powered by a Raspberry Pi

2014-03-18 21.00.09 I’ve been a nerd for a very long time; As a teenager in the 1970’s I drove up to the Western Union office in my hometown of Buffalo, New York and asked if they had any old teletypes they’d like to get rid of; The next thing I knew I was driving my VW bus away, full of Teletype Gear.


I became with familiar with them; Basically they were like remote typewriters; The keyboard on one would control the printer on another. The process could be automated with paper tape punches and readers.  These machines were the mains-stay of printed communication until they were supplanted by fax machines in the eighties. Somewhere over the course of several moves during college, I parted with my big, heavy teletypes.


Wind the clock forward to Maker Faire NYC 2013. NYC Resistor had a Model 15 as part of their Future Crew exhibit. We struck up a conversation about teletypes. I told them how I regretted having parted with my teletypes. They were gracious enough to offer me one of their spares. That is how I once again I was reunited with a Teletype Model 15; I promised to reactivate it and show it off at hamfests and makerfaires.

How To Drive A Teletype

Brushing the dust off some seriously aged neurons, I started sketching what I recalled of the Teletypes wiring.. By modern-day gadget standards, it is astoundingly simple: ttyschematic

A synchronous AC motor drives all the mechanics. Then there is a data relay which must be driven on and off at precisely 45 times per second. This relay closes at around 150ma of current. A readily-available 24VDC Wall-wart with a series resistor is capable of supplying this. The orginal standard called for a higher voltage and a lower current, so this is a bit of a cheat from the original standard, but it works.


One Easy Drive Method: A Relay Board

I came upon the following readily-available board which pretty much fit the bill with only slight modification kootekRelayBoard

Kootek® 2-channel 5V Relay Module

An opto-isolated relay board allows you to control a relatively large (line voltage) circuit safely. Here is the overall schematic including the Kootek relay board, slightly modified: raspi_teletype_sch n-chanmosfetThere are two independent channels. VCC, typically +5V, and GND are connected from the control source (raspi). The IN lines can then be tied to any GPIO line from the source. I used 7 and 8. When the line is set to logic 0, the relay will close and the K* lines will be connected together. So we can turn the motor on and off with one channel and run the data relay with the other channel. Wonderful.

But wait. There is one minor issue with driving the data relay. We need to drive it fairly fast (45 times per second), which is faster than the Kootek’s relay will go (I know. I tried). So we are going to have to do a small mod. It just entails hijacking the output of the optoisolator.  We just need to solder one wire to the correct trace. We then use this to drive the gate pin of our own N-Channel MOSFET and a series resistor, mounted in the wiring harness, which will do the job of turning the Teletype’s data relay on and off (see schematic). We connect +5V and ground of the Raspi to the relay board. We also tie a GPIO (GPIO7) to IN1 of the relay board and GPIO8 to IN2 The K1a and K1b contacts are put in series with the hot side of the 110VAC line voltage and the TTY Motor. +24VDC from the wall wart is tied to one side of the data relay The special tap off of the relay board labelled modification, is then tied to the gate input of our external n-channel mosfet. A 200 ohm, 1 watt resistor is tied from the drain of the mosfet to the other side of the teletype data relay. The source of the mosfet is tied to ground. All other ground connects including the wall wart’s minus side are are tied together to ground.


Here is a picture of the RasPi and the relay board: TTYDriver Here is the bottom side showing location of ‘modification’ on the schematic. The MOSFET and series resistor for the data relay are on the wiring to the teletype inside some heat shrink. TTYDriver2


Partial Bill of Materials


On With The Code

I used the Raspbian Wheezy distro, but webiopi should run on other Raspi Linux distros as well. See Follow the usual procedures to create an SD card image for the pi and boot it. I run my raspi’s headless so I only need to supply it with power and ethernet.  If you’ve never done this for you might find this article useful: For any pi, after installing wheezy, you should do the updates.. This takes a while

sudo apt-get install rpi-update;
sudo rpi-update; 
sudo apt-get update; 
sudo apt-get upgrade;  # go get a coffee

I also recommend running sudo raspi-config; and doing these things:

  • turn off desktop (just command prompt),
  • advanced->memory split, set GPU to 16 (lowest),
  • change it’s name to something besides raspi

Installing WebIOPi  Download their .tgz into /tmp/ on the pi, with curl or wget and follow their installation tutorial, basically:

cd /tmp/
tar zxvf WebioPI.tgz
cd WebIoPi
sudo ./

At this point you should be able to start the stock webiopi with

sudo /etc/init.d/webiopi start

.. and access it from a browser on your PC with http://<raspi-ip-addr>:8000 login webiopi password raspberry. Once you have verified it works, stop it with

sudo /etc/init.d/webiopi stop

Install teletype-pi from github

git clone

Run teletype-pi

cd teletype-pi

At this point you can browse to http://<raspi-ip-addr>/ and you will see the basic interface


Make teletype-pi start on boot

Add this to the end of /etc/rc.local

(cd /home/pi/webiopi/teletype; python

Additional Links

More about the Model 15

Another good teletype restoration web site

About baudot code

National Data Communications Museum

Teletype Mailing List

Barcodatron – A barcode reader / label generation environment



barcodatron is a system for reading and generating barcodes using common low-cost scanners and printers. I use it for tracking electronic components for assembly. It certainly has a wide variety of other applications, so I thought I would open-source it. It consists of python scripts which can operate stand-alone or be called as functions. They are called from the command line or, from a web interface. The web interface is implemented using Flask web server framework which is written in python.  A low-cost hand-held scanner is used to read barcodes from labels, reports, and cheat-sheets. The web interface can be used to look-up parts in an external database via RESTful http GET calls. Printed barcodes are generated using the reportlab python library which generates pdfs. The system also recognizes barcodes to generate labels which are sent to Zebra  printers, which are commonly used for shipping labels. The current environment runs under Windows XP, however it could easily be ported to IOS or Linux. The Flask framework is very lightweight and would run very well on a raspberry pi or beaglebone black



The following diagram describes the overall architecture


A web server running locally delivers .html, js, and css to render the UI. When a barcode is scanned, it will parse the request and send it to the local server which will either forward the request to an external server if it is a database look-up, or execute locally if it is a command to generate a label on the printer.


To run barcodatron you will need the following installed on your system:

Python 2.7

Available from

Git for windows

Available from You could skip it and just use the windows command prompt, but my instructions assume you are using the git bash command prompt.

Once you’ve installed git, go to into windows->control panel->system->Advanced->Environment ->Variables and add C:\python27\;C:\python27\scripts; to your $PATH


Again, not strictly necessary, but the easy_install script makes it much easier to install python libraries

From here on out the instructions assume you’ve started git bash and are entering from the command line

curl >; 

Flask & Flask Bootstrap

Available from 

easy_install flask
easy_install flask-bootstrap


Reportlab is a huge magical blob of python which lets you generate postscript (.ps,.pdf) and actually works most of the time. Documentation:

easy_install reportlab

Win32 API

Win32api allows much better access the windows API from python. We use it to call acrobat to generate the pdfs


Requests is an http protocol toolkit for python

easy_install requests


Check it out from github

git clone

Try it out

cd barcodatron

At this point you should be able to navigate to http://localhost/ and see the UI:


Print out barcode_list.pdf It contains a sheet of sample barcodes and commands. If it doesn’t exists, you can generate another one with python You can look at the source code to get an idea of how to use reportlab to generate reports and cheat-sheets with barcodes on them. The system works with triplets of information; Two nouns – A Job number and a Part number, and a Verb – A command to generate a certain kind of label. Scan the sample Job Number, then the Sample Part Number from the barcode list, then scan a command to preview a label. At this point acrobat will start and show you an image of the label.

External Database Access

The script is in charge of making queries to the external DB, but in this example, it is stubbed out and responds locally to the sample part queries that are in barcode_list.pdf At the top of the script you will see where to add a URL and key to make calls to an external web server. In my case, it is a wordpress plugin which makes use of the wordpress ajax api

# server constants
server_ajax_url = '' # server's ajax api
server_auth_key = 'fake_query' #  replace w/an auth key your server checks for

This is the work-horse script which generates the pdf for the barcode labels. It may be invoked from the command line. Use python -h to get list of commands:

python -h


    -t [ 0 = no test, 1 = test 1, 2 = test 2 ]
    -v [ 0 = no verbose, 1 = verbose ]
    -s [ 0 = 8.5 x 11 paper, 1 = 4 x 6 labels, 2 = 2.25 x 1.25 labels 3 = 3.5 x 1 ]
    -p [ <printer name>, acrobat = send to previewer ]


  Print 2 sheets of test labels on 8.5 x 11 paper to the acrobat reader:

     python -s 0 -t 1 -p acrobat -v 1

  Print 1 4x6 test label:

     python -s 1 -t 1 -p acrobat -v 1

  Print 1 2.25 x 1.25 test label:

     python -s 2 -t 1 -p acrobat -v 1


  Takes input on stdin of the format:

  First token is one of [logo,barcode,keyval]

  LOGO w/no arg renders logo512x512.png
  LOGO C renders the a very large character C in its place
  BARCODE f1 f2 renders a barcode consisting of f1:f2, then renders 'f1:f2' underneath the barcode in plain text
  KEYVAL f1 f2 f3 fn renders 'f1:' in bold, followed by 'f2 f3 fn', wrapping text lines if necessary

  See tgetl.testlines in source code for example input

Raspberry Pi Web Cam on

Google returns over 300k results for “raspberry pi webcam”, but only 3 if you add “”. So here is some guidance to getting your camera on


Get a Pi and a Web Cam

2014-01-10 10.21.11

First off, shameless plug for adafrult industries in NYC. Great supplier of all things Pi.  Besides the Pi, you will also need a webcam, 4gb sd card,  wi-fi dongle, and maybe a pi case. The raspi also has its own direct-connect camera. Compatible wi-fi dongles are available from adafruit. Unless you got an SD card with a Linux distro pre-loaded, you will have to load it with your PC. The following instructions uses Raspbian –, one of the most popular distros.

*Most* common Webcams will work, Microsoft HD web cams definitely work.

Follow the instructions at . My variation: Forget the keyboard and display. Just give it power and an ethernet connection onto a dhcp served net, then look at my /finding-your-raspi-using-nmap/ Alternately, you can just log into your router (which is probably doing your DHCP grants), and look at the DHCP table for raspberry pi foundation. I then use an ssh client to log onto the pi (login: pi password: raspberry)

From here on out we assume you have a shell prompt

Run this first set of commands. It’ll take a while..

sudo apt-get install rpi-update
sudo rpi-update
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install motion

Edit /etc/motion/motion.conf using vi or nano

sudo nano /etc/motion/motion.conf

Here are some things you will want to change:

# set resolution
width 640
height 480

# how many frames to save per motion event (0 == just one)
minimum_frame_time 0

# text to overlay on image

# make text double size
text_double on

# name of file
jpeg_filename %Y_%m_%d_%H%M%S_%v_my_sensr_net_camera

# The mini-http server listens to this port for requests (default: 0 = disabled)
webcam_port 8081

# TCP/IP port for the http server to listen on (default: 0 = disabled)
control_port 8080

# allow control (port 8080) via non-local hosts
control_localhost off

# execute this script when motion frame is captures
on_picture_save /home/pi/bin/ %f

Create the script which does the dirty work of uploading to the

# create bin directory in case you haven't already
mkdir ~/bin
cd ~/bin
# set proper modes on
chmod ug+x

The script should look like this:

# upload file to replace CAMID and PASSWORD with your camera's id
curl -T $1 --user CAMID:PASSWORD
rm $1

Next, plug in your camera (if you haven’t already and restart the motion service:

sudo service motion restart
On your PC, navigate to <strong>http://<<em>your pi's ip address</em>>:8081</strong> . You should be able to see your camera..

Other things you are going to want to do

# put user daemon in group motion so it can read the files
sudo usermod -g motion daemon

# open up motion's data director to daemon
sudo chmod g+rwx /tmp/motion

At this point files should be getting uploaded to If not there’s a few things to check. You can run motion directly on the command line with

sudo service motion stop
sudo motion

You can also test the upload script by itself:

sudo su daemon
touch /tmp/motion/foo.jpg
/home/pi/bin/ /tmp/motion/foo.jpg

You can also connect to  http://<your pi’s ip address>:8080,  and tweek configuration parmeters on the fly.

Finding Your Headless DHCP’d RasPi using nmap

I like as few cables as possible. And besides, many of my spare monitors don’t have an HDMI connector. So when I’m hooking up a raspi for the first time, my preferred method is to just attach ethernet and power and use nmap.

Now, if you are lucky you *might* be able to just do a ping raspberrypi, or raspberrypi.local But this depends on your DHCP server. This worked for me at the windows 7 cmd prompt, at least.

Nmap probes networks and it runs on just about any platform you can download from here

Exactly how you invoke nmap will vary from platform to platform, but here is how you would do it under the windows command prompt.

C:\"Program Files (x86)"\Nmap\nmap.exe -sP

You will also need to change your IP address range (, to your IP address range (more commonly: or

Nmap scan report for raspberrypi.home (
Host is up (0.0020s latency).
MAC Address: B8:27:EB:28:97:88 (Raspberry Pi Foundation)

If you want it to just print out the address without having to search the listing you could add this on the end:

nmap -sP | awk '/^Nmap/{ip=$NF}/B8:27:EB/{print ip}'

And there you have it. My raspi is at, I can now ssh to that address using putty, for instance.

More info on here:

Less To CSS ? You Jest.

I’ve spent the last several hours shaving a yak


The term refers to the act of getting completely side-tracked from your goal because one of the intermediate steps to the ultimate goal sucked all your time.

What is Less ?

Apparently, web UI programmers decided that straight css was either evil and not high-level enough or both,  so they invented a pre-processor on top of it called  less. Problem is, there are a number of less to css compilers out there. Some have become dusty, old and broken, or they don’t run on your platform, or require you to install large amounts of stuff I didn’t actually need.
Here are just a few Less compilers I ran across:

  • Pretty- MAC and Windows tools like simpless.
  • There is a php based one called lessphp
  • There  is one written in  ruby
  • There is one written in python

NONE of these worked for  my simple requirements – Linux-based, command line. In my attempts to work with boostrap3, font-awesome and the bonestheme frameworks. All three of these are packaged up as a baseline, no-frills wordpress theme and called brew which is just what I needed.

The tool I ended up using was a javascript compiler written in the node.js  framework. I haven’t been involved with node.js but I will acknowledge it is a possible wave of the future, as it further detaches the business  logic of a web site from the rendering.

I attempted to install node.js from source under Centos 5 and gcc 4 following these instructions, but they led to a dead end like the rest and I was running out of time.

Finally, I installed the binary distribution of node.js which worked fine. It also installs the node.js package manager npm So the final step was to install the less compiler with with:

npm install less --global

Finally, this is all I needed to generate the bonestheme css:

#!/bin/bash -v
$LESSC $SRC/ie.less $DST/ie.css
$LESSC $SRC/login.less $DST/login.css
$LESSC $SRC/style.less $DST/style.css

I keep this script down in a child-theme of brew, in /library/, whenever I update one of the less files, I just run the script.

I was not able to google this exact recipe, so I thought I’d post it.

UPDATE: I was able to get a smooth install from source on a Centos 6 box following these instructions then finishing up with:

npm install less --global

Rasberry PI Out of Box Experience



Goal: Just wanted to hook this thing up to power and ethernet and ssh into it. That’s all.

Tried to d/l and install Downloaded Debian Image


Image Writer for Windows

Must manually extract. No self-installer.. Put in C:\win32-image-writer\

Unzippeded Write archlinux-hf-2013-01-22.img to an SD card

Booted, then discovered it had no ssh out of the box. *sigh*

Did a little actual reading and discovered it archlinux-hf doesn’t ship with ssh enabled See

Looked at the Adafruit RasPi Distro –

D/L’d unzipped and wrote to SD card. Power-cycled pi. Comes up. Will ask for a DHCP address on your ethernet

How to ssh onto your Pi

Some people like the putty ssh client. Others like me like poderosa. The simplest approach I find is to use the ssh  that comes w/Git for Windows. Just install it then run Git Bash command line tool

How to discover the IP address allocation

You can go to your DHCP server, which is typically your gateway router and try to find it..

Or… *if* you have itunes installed you also have a magical bonjour service installed which allows for auto-discovery..

So at the command prompt you can type

ssh pi@raspberrypi.local
password: raspberry
Linux raspberrypi 3.1.9adafruit+ #10 PREEMPT Thu Aug 30 20:07:05 EDT 2012 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

Type 'startx' to launch a graphical session

Last login: Fri Aug 31 13:37:57 2012 from ladyada301-pc.local

NOTICE: the software on this Raspberry Pi has not been fully configured. Please run 'sudo raspi-config'

Please change your password using 'sudo /usr/bin/raspi-config'

And *BAM* you are in.

Plug In Bar Code Reader

I wanted to mess with a bar code reader..

My generic $39 bar code scanner from amazon

Do a tail -f /var/log/messages then plug in the scanner. You should see:

[ 2685.578555] snd_bcm2835_playback_close:167 Alsa close
[ 2834.526579] usb 1-1.2: new low speed USB device number 4 using dwc_otg
[ 2834.631871] usb 1-1.2: New USB device found, idVendor=05fe, idProduct=1010
[ 2834.631908] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2834.631930] usb 1-1.2: Product: WIT 122-UFS V2.02
[ 2834.631945] usb 1-1.2: Manufacturer: WIT Electron Company
[ 2834.649637] input: WIT Electron Company WIT 122-UFS V2.02 as /devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/input/input0
[ 2834.649784] generic-usb 0003:05FE:1010.0001: input: USB HID v1.10 Keyboard [WIT Electron Company WIT 122-UFS V2.02] on usb-bcm2708_usb-1.2/input0

Take note of the input0, Now go into /dev/input and you should see an event0 entry.

pi@raspberrypi /dev/input $ ls /dev/input
./  ../  by-id/  by-path/  event0  mice

Now it is just a matter of writing a little python script:

[cc lang=”python” width=370]
print “barcode scanner tests”
def k():
byte = []
f = open(‘/dev/input/event0’, ‘r’)
while True:
for bit in
if len(byte) == 8:
print byte
byte = [

Installing The Adafruit Web IDE

Then I went ahead and kept following the Adafruit instructions –

pi@raspberrypi:~$ curl | sudo sh   
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3786  100  3786    0     0   7657      0 --:--:-- --:--:-- --:--:-- 13330
**** Downloading the latest version of the WebIDE ****
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 22.2M  100 22.2M    0     0   416k      0  0:00:54  0:00:54 --:--:--  181k
**** Installing required libraries ****
**** (redis-server git restartd libcap2-bin avahi-daemon i2c-tools python-smbus) ****
Get:1 wheezy InRelease [7,737 B]
Get:2 wheezy InRelease [12.5 kB]
Get:3 wheezy/main armhf Packages [6,421 B]
Get:4 wheezy/main armhf Packages [7,403 kB]
Ign wheezy/main Translation-en_GB
Ign wheezy/main Translation-en
Get:5 wheezy/contrib armhf Packages [23.3 kB]
Get:6 wheezy/non-free armhf Packages [47.8 kB]
Get:7 wheezy/rpi armhf Packages [14 B]
Ign wheezy/contrib Translation-en_GB
Ign wheezy/contrib Translation-en
Ign wheezy/main Translation-en_GB
Ign wheezy/main Translation-en
Ign wheezy/non-free Translation-en_GB
Ign wheezy/non-free Translation-en
Ign wheezy/rpi Translation-en_GB
Ign wheezy/rpi Translation-en
Fetched 7,500 kB in 1min 8s (110 kB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
avahi-daemon is already the newest version.
i2c-tools is already the newest version.
python-smbus is already the newest version.
The following extra packages will be installed:
  libjemalloc1 libpam-cap
Suggested packages:
  git-daemon-run git-daemon-sysvinit git-doc git-el git-arch git-cvs git-svn git-email git-gui gitk gitweb libcap-dev
The following NEW packages will be installed:
  libcap2-bin libjemalloc1 libpam-cap redis-server restartd
The following packages will be upgraded:
1 upgraded, 5 newly installed, 0 to remove and 231 not upgraded.
Need to get 6,206 kB of archives.
After this operation, 946 kB of additional disk space will be used.
Get:1 wheezy/main libjemalloc1 armhf 3.0.0-3 [87.3 kB]
Get:2 wheezy/main git armhf 1: [5,864 kB]
Get:3 wheezy/main libcap2-bin armhf 1:2.22-1.2 [21.1 kB]
Get:4 wheezy/main libpam-cap armhf 1:2.22-1.2 [10.0 kB]
Get:5 wheezy/main redis-server armhf 2:2.4.14-1 [213 kB]
Get:6 wheezy/main restartd armhf 0.2.2 [11.0 kB]
Fetched 6,206 kB in 4s (1,487 kB/s)
debconf: unable to initialize frontend: Dialog
debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
debconf: falling back to frontend: Readline
Selecting previously unselected package libjemalloc1.
(Reading database ... 56026 files and directories currently installed.)
Unpacking libjemalloc1 (from .../libjemalloc1_3.0.0-3_armhf.deb) ...
Preparing to replace git 1: (using .../git_1%3a1.7.10.4-1+wheezy1+rpi1_armhf.deb) ...
Unpacking replacement git ...
Selecting previously unselected package libcap2-bin.
Unpacking libcap2-bin (from .../libcap2-bin_1%3a2.22-1.2_armhf.deb) ...
Selecting previously unselected package libpam-cap:armhf.
Unpacking libpam-cap:armhf (from .../libpam-cap_1%3a2.22-1.2_armhf.deb) ...
Selecting previously unselected package redis-server.
Unpacking redis-server (from .../redis-server_2%3a2.4.14-1_armhf.deb) ...
Selecting previously unselected package restartd.
Unpacking restartd (from .../restartd_0.2.2_armhf.deb) ...
Processing triggers for man-db ...
debconf: unable to initialize frontend: Dialog
debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
debconf: falling back to frontend: Readline
Setting up libjemalloc1 (3.0.0-3) ...
Setting up git (1: ...
Setting up libcap2-bin (1:2.22-1.2) ...
Setting up libpam-cap:armhf (1:2.22-1.2) ...
debconf: unable to initialize frontend: Dialog
debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
debconf: falling back to frontend: Readline
Setting up redis-server (2:2.4.14-1) ...
Starting redis-server: redis-server.
Setting up restartd (0.2.2) ...
Starting process checker: No processes defined in config file. Exiting.
**** Create webide user and group ****
**** Adding webide user to sudoers ****
/etc/sudoers.tmp: parsed OK
/etc/sudoers.d/README: parsed OK
**** Adding default .bashrc file for webide user ****
**** Installing the WebIDE as a service ****
**** (to uninstall service, execute: 'sudo update-rc.d -f remove') ****
update-rc.d: using dependency based boot sequencing
**** Starting the server...(please wait) ****
**** The Adafruit WebIDE is installed and running! ****
**** Commands: sudo service {start,stop,restart} ****
**** Navigate to http://raspberrypi.local to use the WebIDE

The WebIDE did come up at http://raspberrypi.local

List of Handy Python Links for the Padawan Learner


Programming is my principal occupation and one of my obsessions. For the last 12 years or so, my scripted language of choice has been Perl. As programming languages go, it is starting to show its age. Here’s an interesting graph of language popularity based on github checkins. Now that there are over 26,000 98,000 python modules, you can pretty much do anything in Python. So a while ago, I decided to retool my brain to think in Python.

With that, here is my collected list of useful Python-related things I have found out on ye old Interweb.

Update 2017: Here’s another list of python tutorials

Learn Python The Hard Way, 2nd Edition. Essentially A list of guided homework assignments. I like this approach

A Beginner’s Guide To Programming Languages – While not python-specific, this is an excellent resource for someone just starting out

Pythontutor. Visualizes the data structures as you code them. Pretty cool.


IBM developerWorks has a bunch of Python articles.


Tuples, Lists and Dictionares. Python’s 3 basic data structures.


An Introduction to Python Lists. The data structure type that probably gets used the most.


Python Tutorials. A bunch of them. (What’s with the girl ?)

Google’s Introduction To Python

PyPI – the Python Package Index. You can do anything with Python because of the wealth of Packages available.


Unofficial Windows Binaries for Python Extension Packages.


Configuration for setting up Vim to work with PythonStyleGuide. Useful if, like me,  Vi is your Editor of Choice.


The best Python IDE’s you can use for development. For people who prefer modern IDEs


Python Sending Email using SMTP. Who doesn’t want to send a little robo-mail ?


PyGTK. The way to create multiplatform GUIs in Python.


Chirp is a complete PyGTK application for programming amateur radios.


A better way to process binary data in Python.


Python Cheat Sheet. A handy programming reference card for Python


Python Books. If you prefer actual books.


Debugging in Python


Python Module of the Week. A bloggy tour of some Python modules.


Easy Install. How you add Python Packages to your system


Python Podcasts.


Nullege is a search engine for Python source code. When google isn’t enough.


Working with Python subprocess – Shells, Processes, Streams, Pipes, Redirects and More


Learning Python.  A real book. Sample Chapter 9: Common Tasks in Python


Python-script. A skeleton example of what well-styled python script might look like


Pylons Project.  A Python web meta framework.


Django. Django is a Python-based web framework. Might be good for a total green-field project.


Ajax Form Submission in Django. This is a rabbit hole I briefly went down.


Twisted – Python-based network engine.


An sshv2 implementation in Python written w/Twisted