Twenty things to do with a python script
With a deferential bow to Seymour Papert & Cynthia Solomon's 1971 20 Things to do with a computer, here a selected listing of Python recipes that represent a range posible explorations that need not involve much more than 20 - 30 lines of code.
Papert & Solomon were key figures as early as the 1970s in the development of school curricula for using computers in the classroom. Through the development of the programming language LOGO, and the concept of turtle graphics, they promoted a constructivist approach to using programming to teach other concepts. In this approach, the computer provides a means of making "microworlds" in which typically "abstract" concepts (such as geometry and differential equations) can be approached in a concrete and (virtually) hands-on way rather than as abstract principles typical of convention maths teaching.
The python programming language has been used for many years as part of the PZI Media Design curriculum. Echoing the constructivism of Papert & Solomon, programming is used in the course to get "hands on" experience with the substance of software and digital media.
<slidy theme="aa" />
Make a turtle
import turtle
import random
def Poly(n,x):
angle = 360/n
for i in range(n):
turtle.forward(x)
turtle.left(angle)
def makeFlower(p):
for i in range(12):
Poly(9,p)
turtle.left(30)
def makeTriple():
turtle.speed(44)
for i in range(3):
i = (i+1)*5
turtle.color(random.random(),random.random(),random.random())
makeFlower(i)
xa = -255
y = -244
numberColumns = 5
numberRows = 5
turtle.penup()
turtle.setpos(xa,y)
for i in range(numberRows):
for c in range(numberColumns):
c=(c+1)*100
makeTriple()
turtle.penup()
turtle.sety(y+c)
turtle.pendown()
i=(i+1)*100
turtle.penup()
turtle.setpos(xa+i,y)
turtle.pendown()
Source: Lidia Pereira, Turtle Graphics Exercises
Create an Inkscape plugin to draw turtle graphics
See Seymour
Generate tactical hybrid texts
Using nltk
Source: Femke Snelting, http://snelting.domainepublic.net/files/EmmaWoodhouse.odt
Programmatically Manipulate Typefaces
Source: Eric Schrijver, http://i.liketightpants.net/and/programmatically-manipulating-typefaces
Spider texts and extract strategic search patterns
ective enforcement of intellectual property rights is critical to sustaining e or the enforcement of intellectual property rights , taking into account diffe procedures to enforce intellectual property rights do not themselves become ba em of infringement of intellectual property rights , including infringement ta ensive enforcement of intellectual property rights than is required by this Ag etween enforcement of intellectual property rights and enforcement of law in g lability and Scope of Intellectual property Rights 1 . This Agreement shall be , and maintenance of intellectual property rights . 2 . This Agreement does n ures where a right in intellectual property is not protected under its laws an rk for Enforcement of Intellectual property Rights ) are invoked ; ACTA / en 7 calendar days ; ( h ) intellectual property refers to all categories of intell to all categories of intellectual property that are the subject of Sections 1 rk for Enforcement of Intellectual property Rights ) are invoked ; ACTA / en 8 g to assert rights in intellectual property ; ( m ) territory , for the purpos rk for Enforcement of Intellectual property Rights ), means the customs territ - Related Aspects of Intellectual property Rights , contained in Annex 1C to RK FOR ENFORCEMENT OF INTELLECTUAL property RIGHTS SECTION 1 GENERAL OBLIGATIO ct of infringement of intellectual property rights covered by this Agreement , he enforcement of any intellectual property right as specified in this Section ng the enforcement of intellectual property rights , its judicial authorities he infringement of an intellectual property right from entering into the chann ng the enforcement of intellectual property rights , its judicial authorities s for infringement of intellectual property rights , a Party ' s judicial auth the right holder ' s intellectual property right in question and actually ass horization to use the intellectual property right in question . ACTA / en 14 A
import nltk
nltk.download()
corpus_root='/path/to/your/texts'
wordlists=PlaintextCorpusReader(corpus_root,'.*')
acta=nltk.text.Text(wordlists.words('ACTA.txt'))
import sys, nltk
from nltk.corpus import PlaintextCorpusReader
corpus_root=sys.argv[1]
print corpus_root
corpus=PlaintextCorpusReader(corpus_root,'.*')
interesting=['property','intellectual','right','measure','protection']
for fileid in corpus.fileids():
text=nltk.text.Text(corpus.words(fileid))
text.concordance('ACTA')
Uses: NLTK
Source: Nicolas Malevé, http://vj13.constantvzw.org/live/deskcam/
Run a web server
python -m SimpleHTTPServer
Permute the spellings of search terms
Source: Linda Hilfling, the experiments were developed later into the Misspelling generator browser plugin & project
Create a detourned search engine
Source: Sebastian Schmieg & Silvio Lorusso
Create a Traceroute Map
# imports the geoip database and the sys function
import pygeoip, sys, string
# creates a variable called "filename" that equals the first thing that
# has been put after the execution of "routetodot[dot]py"
filename = sys.argv[1]
#creates a variable of the geoip database from the file "GeoIP.dat"
GEOIP = pygeoip.Database('GeoIP.dat')
#create a variable called lastIp
lastNUM = None
# create a variable "line" from every line in the "filename"
# split this "line" into a variable called "data"
# check if "data" starts and ends with "(" ")"
# if so create a variable called "ip" that is "data" without "()"
# look up "ip" in the "GEOIP" variable
# checks if "a.country" returns none, it is then printed as "localhost"
# prints the variables "lastIp" and "ip"
# changes "lastIp" into "ip"
lineNUM = 0;
labels = "";
connections = "";
colorsbycountry = dict(US='blue',NL='orange',DE='grey',CN='red',localhost='pink',IE='green',FR='purple',GB='crimson', EU='sienna' )
colors = '"0.8396,0.4862,1.0" "0.8396,0.4862,0.8" "0.8396,0.4862,0.6" "0.8396,0.4862,0.4" "0.8396,0.4862,0.2" "0.8396,0.4862,0.0"'.split()
nodenamebyip = {}
nodenum=0
lastip = None
colorindex=0;
for line in open(filename):
parts = line.split()
NUM = parts[0]
lineNUM +=1
for data in parts:
#line[1]
if data.startswith("(") and data.endswith(")"):
ip= data.strip("()")
a= GEOIP.lookup(ip)
if a.country == None:
a.country = "localhost"
if a.country not in colorsbycountry:
colorsbycountry[a.country] = colors[colorindex]
colorindex+=1
labelcolor = colorsbycountry[a.country]
if ip not in nodenamebyip:
nodenum+=1
nodenamebyip[ip] = "node"+str(nodenum)
# first time, print label
nn = nodenamebyip[ip]
#labels+= nn +' [label="'+ip+' '+a.country+'" fontcolor="'+labelcolor+'" style="filled"]\n'
#labels+= str(lineNUM)+' [label="'+ip+' '+a.country+'" fontcolor='+labelcolor+' style=filled]\n'
labels+= str(lineNUM)+' [label="'+ip+' '+a.country+'" fillcolor='+labelcolor+']\n'
if lastNUM != None:
connections+= str(lastNUM)+"->"+str(lineNUM)+'\n'
# connections+= nodenamesbyip[lastip]+"->"+nodenamesbyip[ip]+'\n'
lastNUM = lineNUM
lastip = ip
graphname = filename;
if graphname.endswith(".txt"):
graphname = graphname.strip(".txt")
print "digraph iptrace {\n bgcolor = grey; \n node [shape=rect, fontname=Arial, fontcolor=white, style=filled] \n edge [style=dotted] \n"
print 'label=','"'+graphname+'"'
print labels
print connections
print "}"
Uses: pygeoip
Source: Roel Roscam Abbing, Documentation
Scrape Albert Heijn Loyalty Cards
Source: Birgit Bachler, http://www.birgitbachler.com/portfolio/?p=506
Create a custom joystick sound recorder
Uses: pygame
Source: Peter Westenberg, http://www.deschaarbeeksetaal.be/p/rugzak/
Slice & reorder an audio file by predominant frequency
http://kurenniemi.activearchives.org/spectrum/
Source: Nicolas Malevé and Michael Murtaugh
3D Cloud computing with Blender
A mod of the above script...
# The following function is adapted from
# Nick Keeline "Cloud Generator" addNewObject
# from object_cloud_gen.py (an addon that comes with the Blender 2.6 package)
# from : http://bathatmedia.blogspot.be/
def duplicateObject(scene, name, copyobj):
# Create new mesh
mesh = bpy.data.meshes.new(name)
# Create new object associated with the mesh
ob_new = bpy.data.objects.new(name, mesh)
# Copy data block from the old object into the new object
ob_new.data = copyobj.data.copy()
ob_new.scale = copyobj.scale
ob_new.location = copyobj.location
ob_new.rotation_euler = copyobj.rotation_euler
# Link new object to the given scene and select it
scene.objects.link(ob_new)
ob_new.select = True
return ob_new
Source: Julien Deswaef, Brussels Blender Group
Create a dotcom index using letter permuations
from itertools import product
chars = "abcdefghijklmnopqrstuvwxyz1234567890-"
for n in xrange(253):
for comb in product(chars, repeat=n):
i = ''.join(comb)
print 'http://www.'+i+'.com'
Source: User:Roelroscama, Documentation
Filter a subtitle file to highlight the unique words of a spoken text (Disappearance)
http://activearchives.org/wiki/Disappearance
#! /usr/bin/env python
# Copyright 2010 the Active Archives contributors.
# See the file AUTHORS for more details.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import re
from optparse import OptionParser
from textwrap import dedent
# inits usage and arguments
usage = "usage: %prog in.srt > out.srt"
parser = OptionParser(usage=usage)
(options, args) = parser.parse_args()
# checks the arguments length
if len(args) != 1:
parser.error("incorrect number of arguments")
# opens the subtitle file and reads its content
try:
f = open(args[0], 'r')
except IOError:
sys.exit(dedent("""\
Error: I can't open your subtitle file.
Are you sure it exists?\
"""))
else:
subtitles = f.read()
f.close()
pattern = re.compile(r'[a-zA-Z]+', re.UNICODE) # creates a pattern to search words
used_words = []
new_text = ""
previous_end = 0
# replaces all the occurrences of the words but the first one
for match in pattern.finditer(subtitles):
new_text += subtitles[previous_end:match.start()]
word = match.group()
if word.lower() in used_words:
#new_text += "*{w}*".format(w=word)
#new_text += "<del>{w}</del>".format(w=word)
#new_text += "--{w}--".format(w=word)
new_text += "{w}".format(w="".ljust(len(word), " "))
else:
new_text += word
used_words.append(word.lower())
previous_end = match.end()
new_text += subtitles[previous_end:len(subtitles)]
print(new_text)
Source: Alexandre Leray and Stéphanie_Vilayphiou
Create generative fugues
File:Fugue 01 20110608.oggFile:Fugue 04 20110530.oggFile:Fugue 01-octave4 20110608.ogg
#!/usr/bin/env python
import random
fugue = {}
fugue = {
"/l2/d4":["/l2/a4", "/l2/c+4"],
"/l2/a4": ["/l2/f4"],
"/l2/f4": ["/l2/d4", "/l8/f4"],
"/l2/c+4": ["/l4/d4"],
"/l4/d4": ["/l4/e4"],
"/l4/e4": ["/l2/f4"],
"/l8/f4": ["/l8/g4","/l8/e4"],
"/l8/g4": ["/l8/f4"],
"/l8/e4": ["/l2/d4"]
}
#here we print / place the timidity structure
print """
@head {
$time_sig 4/4
$tempo 220
}
@body {
@channel 1 {
$patch 1
$octave 4
$length 16
"""
tone = "/l2/d4"
for x in range(64):
print tone
#this new variable tone is overwriting the old tone! => variable as empty bowl symbolism
tone = random.choice(fugue[tone])
#here we print / place the timidity structure
print """
}
}
"""
Users: midge
Source: Natasa Siencnik User:Natasa_Siencnik/prototyping/markov
Use open clip art and a loop to make a book of patterns
print """<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
width="200px" height="50px"
viewBox="0 0 200 50"
zoomAndPan="disable" >"""
# vertical amount of elements
veramo = 20
# ydist increases the vertical distance
ydist = 10
for z in range(veramo):
transf = "transform=\"translate({0},{1})\">".format(0,z*ydist)
print "<g " + transf
# horizontal amount of elements
horamo = 20
# ydist2 increases the vertical distance
ydist2 = 10
# xdist increases the horizontal distance
xdist2 = 10
for x in range(horamo):
transf = "transform=\"translate({0},{1})\"".format(x*xdist,x*ydist2)
print "<rect " + transf + """ x="0" y="0" width="10" height="10" fill="black" />
print "</g>"
print "</svg>"
Source: Silvio Lorusso, A man of many parts
Generating Outline Fonts with 5 Lines of Code
import fontforge
font = fontforge.open('douar.sfd')
for glyph in font:
font[glyph].stroke('circular', 30, 'square', 'bevel', ('cleanup',))
font.generate('douar-new.ttf')
Uses: FontForge
Source: Ricardo Lafuente, http://blog.manufacturaindependente.org/2011/02/generating-outline-fonts-with-5-lines-of-code/
Create interactive vector graphics
http://www.stuartaxon.com/2013/03/20/natural-movement-in-python-part-3-particles/#more-331
Uses: Shoebot (http://shoebot.net/)
Source: Stuart Axon and Ricardo Lafuente
Generate an epub
http://www.ibm.com/developerworks/xml/tutorials/x-epubtut/
Other Modules to check out...
- Manipulate images with PIL
- use reportlab to generate a paginated PDF
- use subprocess to run FFMPEG and scrape audio/video info using a regular expression
- use html5lib to scrape HTML
- use glob to process a folder full of files
- use urllib2, urlparse and html5lib to spider HTML
- use json to parse results from web APIs
- use optparse to make a self-documenting command line utility
- use random to work with some noise
- use datetime to work easily with dates and intervals
- use OSC to talk to control other (realtime) programs
- use uuid to generate unique ids
- use zipfile
- use xml to read and extract data from an XML source