== Write text to a file (not safe) == {{{ #!python #how to write text to a file (not safe) open('foo.txt', 'w').write('hello') }}} == Loop a certain number of times == {{{ #!python for x in range(10): print x }}} == Concetenate a number and a string == {{{ #!python x = 1 print str(x) + " is a string" print "%s is a string" % x }}} == Test if a string contains another string == {{{ #!python my_string = "abcdef" if "abc" in my_string: has_abc = True }}} == Check if an item is in a list or dictionary or tuple or set == {{{ #!python my_list = [1, 2, 3, 4, 5] if 1 in my_list: has_one = True my_dict = {"a": 1, "b": 2, "c": 3} if "a" in my_dict: has_a = True }}} == Anonymous functions (lambda) == {{{ #!python add = lambda x, y: x + y print add(3, 4) # prints "7" }}} == Reduce == {{{ #!python from functools import reduce # remove this line on 2.x def factorial(x): return reduce(lambda accum, x: accum * x, range(1, x + 1), 1) }}} == Non-destructive sort on key == {{{ #!python people = [ ... list of people objects ... ] people_by_age = sorted(people, key=lambda person: person.age) }}} == Ternary expression == === Python 2.5 or later === {{{ #!python # Ternary expression (i.e. "BOOLEAN ? IF_TRUE : IF_FALSE") print "a" if x == 1 else "b" }}} === Python 2.4 or earlier === {{{ #!python print (x == 1) and "a" or "b" }}} == Printing stuff nicely == {{{ #!python from pprint import pprint pprint('Complex thing') }}} == Generators / Iteration == {{{ #!python # generators/iteration def generate_stuff (): yield "x" yield "y" yield "z" for item in generate_stuff (): print item }}} == How to test if a string begins or ends with another string == {{{ #!python my_string = "abcdef" if my_string.startswith("abc"): starts_with_abc = True if my string.endswith("def"): ends_with_def = True }}} == How to catch exceptions == {{{ #!python grades = ['A', 'A-', 'B', 'C'] try: grades.index("F") except ValueError, inst: # Print the error information print inst.args }}} == Catching multiple exceptions == {{{ #!python try: "do something" except (ExceptionOne, ExceptionTwo): # Note: The parens are important. "handle the exception" }}} == Convert a file:/// URL to a file path in a shell script == {{{ deurledfile = `python -c 'import sys, urlparse, urllib; print urllib.unquote(urlparse.urlparse(sys.argv[1]).path)' $1` }}} == Change / update value in a file with '=' == {{{ #!python try: fin = file('file1', 'r') fout = file(fin.name + '.new', 'w') for line in fin: fields = line.split('=') # Separate variable from value if "keyname" == fields[0].strip(): line = "%s='%s'\n" % (fields[0], "newvalue") fout.write(line) fout.close() fin.close() os.rename(fout.name, fin.name) except (OSError, IOError), e: print("can't update the file") }}} == How to make money in open source == 1. get developers 1. bzr commit 1. ??? 1. profit == How to generate pretty charts == See http://yokozar.org/blog/archives/48 {{{ #!python import cairoplot # Appears at the top of the chart produced at the end chartTitle = "Simulated model of Wine development" chartData = {"Working Apps" : [], "Happy Users" : []} for x in xrange(100): chartData["Working Apps"].append(float(x)) chartData["Happy Users"].append(float(x)) x_labels = [ "Project start", "25% bugs solved", "50% bugs solved", "75% bugs solved", "All bugs solved"] y_labels = ["0%", "25%", "50%", "75%", "100%"] cairoplot.dot_line_plot( "wine-model-results", chartData, 600, 600, x_labels = x_labels, y_labels = y_labels, axis = True, grid = True, x_title = chartTitle, y_title = "Percentage", series_legend=True ) }}} == How to play a sound == {{{ #!python import gst player = gst.element_factory_make("playbin", "player") player.set_property("uri", "file:///usr/share/sounds/ubuntu/stereo/bell.ogg") player.set_state(gst.STATE_PLAYING) # or import pygame pygame.mixer.init() pygame.mixer.music.load("music.ogg") pygame.mixer.music.play() }}} == notify-osd == {{{ #!python import pynotify pynotify.init('someName') n = pynotify.Notification("message name", "message", "icon") n.show() }}} # more notify-osd stuff == Get the output of a command == {{{ #!python import subprocess date = subprocess.Popen(['date', '+%c'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = date.communicate() print 'exit code', date.returncode }}} == Open a link in a web browser == {{{ #!python import webbrowser url = 'http://google.com/' webbrowser.open_new(url) }}} == Get the text for an HTML page from the web == {{{ #!python import urllib f = urllib.urlopen(day_url) html = f.read() }}} == Create a stock cancel button and pack it into the vbox == {{{ #!python cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) cancel_button.show() cancel_button.connect("clicked", on_cancel_clicked) }}} == Parse XML file == {{{ #!python import xml.dom try: dom = xml.dom.minidom.parseString(xml_content) except ExpatError, e: print >> sys.stderr, 'Invalid XML:', e for p_node in dom.getElementsByTagName('p'): print 'class of paragraph', p.attributes['class'] for child in p_node.childNodes: print 'XML child node:', child }}} == Search a text for a pattern and do something with every match == {{{ #!python import re text = "bug 1: first bug\nbug 2: duplicate of bug 1\nbug 999: the last bug" for m in re.finditer('bug (\d+):', text): print 'bug number: '+ m.group(1) }}} == Download an URL and process it line by line == {{{ #!python import urllib for line in urllib.open('http://foo'): print line }}} == Grep all versioned files in a Bazaar tree == {{{ # Best command ever bzr ls -VR --kind=file --null | xargs -0 grep -In }}} == Grep all versioned files in a Git tree == {{{ git grep }}} == Creating a Gtk+ TreeView == {{{ #!python # Instantiate the tree store and specify the data types store = gtk.TreeStore(str, gtk.gdk.Pixbuf, int, bool) # Create a TreeViewColumn col = gtk.TreeViewColumn("File") # Create a column cell to display text col_cell_text = gtk.CellRendererText() # Create a column cell to display an image col_cell_img = gtk.CellRendererPixbuf() # Add the cells to the column col.pack_start(col_cell_img, False) col.pack_start(col_cell_text, True) # Bind the text cell to column 0 of the tree's model col.add_attribute(col_cell_text, "text", 0) # Bind the image cell to column 1 of the tree's model col.add_attribute(col_cell_img, "pixbuf", 1) col2 = gtk.TreeViewColumn("Size") col2_cell_text = gtk.CellRendererText() col2.pack_start(col2_cell_text) col2.add_attribute(col2_cell_text, "text", 2) # Create the TreeView and set our data store as the model tree = gtk.TreeView(store) # Append the columns to the TreeView tree.append_column(col) tree.append_column(col2) }}} == Make a new ListStore when columns are calculated at runtime == {{{ #!python col_count = 100 self.list_store = gtk.ListStore( *[gobject.TYPE_STRING for i in range(col_count)]) }}} == Put data into desktop CouchDB == {{{ #!python from desktopcouch.records.server import CouchDatabase from desktopcouch.records.record import Record as CouchRecord db = CouchDatabase("dbname", create=True) record = CouchRecord( {"a": 1, "b": 2}, record_type="http://recordtypeurl", record_id=XXX) db.put_record(record) }}} == Call a desktop CouchDB view == {{{ #!python view = """function(doc) { if (doc) emit(doc._id, doc); }""" if not self.messages.view_exists("myview", "myapp"): self.messages.add_view("myview", view, None, "myapp") result = self.messages.execute_view("myview", "myapp") }}} == Listen to changes in CouchDB == {{{ #!python from desktopcouch.records.server import CouchDatabase # we are going to be listening to the changes def changes_cb(seq=None, id=None, changes=None): print seq print id print changes db = CouchDatabase("fosdem") # better, use glib main loop or twisted task! while True: db.report_changes(changes_cb) time.sleep(30) }}} == Add attachments in CouchDB == {{{ #!python from desktopcouch.records.record import Record from desktopcouch.records.server import CouchDatabase db = CouchDatabase("fosdem") record = Record(record_type="url") record.attach("/path/to/image/avatar.jpg", "blob", "image/jpg") db.put_record(record) }}} == Creating a new Tomboy note == {{{ #!python def create_tomboy_note(text): bus = dbus.SessionBus() obj = bus.get_object("org.gnome.Tomboy", "/org/gnome/Tomboy/RemoteControl") tomboy = dbus.Interface(obj, "org.gnome.Tomboy.RemoteControl") n = tomboy.CreateNote() tomboy.DisplayNote(n) tomboy.SetNoteContents(n, text) }}} == Set Pidgin status == {{{ #!python def set_pidgin_status_text(message): bus = dbus.SessionBus() obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject") purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface") current = purple.PurpleSavedstatusGetType(purple.PurpleSavedstatusGetCurrent()) status = purple.PurpleSavedstatusNew("", current) purple.PurpleSavedstatusSetMessage(status, message) purple.PurpleSavedstatusActivate(status) }}} == Embed a WebKit renderer in an application == {{{ #!python import gtk, webkit gtk.gdk.threads_init() window = gtk.Window() window.connect("destroy", gtk.main_quit) web = webkit.WebView() web.open("http://ubuntu.com") window.add(web) window.show_all() gtk.main() }}} == Put an icon in a Gtk+ text entry == {{{ GtkWidget *entry = gtk_entry_new(); gtk_entry_set_icon_from_stock( GTK_ENTRY(entry), // specify which entry widget GTK_ENTRY_ICON_SECONDARY, // put the icon at the end GTK_STOCK_ABOUT); // make it display the "about" icon }}} == Display a progress bar in a Gtk+ entry == {{{ GtkWidget *entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), "This is a test"); gtk_entry_set_progress_fraction(GTK_ENTRY(entry), 0.5); }}} == Get Gtk+ theme colors == {{{ #!python def get_theme_colors(w): d = {} for i in ["base", "text", "fg", "bg"]: d[i] = Color.from_gtk_color( getattr(w.get_style(), i)[gtk.STATE_NORMAL].to_string()) d["%s_selected" % i] = Color.from_gtk_color( getattr(w.get_style(), i)[gtk.STATE_SELECTED].to_string()) return d }}} == Draw a rounded rectangle in Cairo == {{{ #!python c = self.window.cairo_create() x,y,w,h = w.allocation # x, y, width, height c.move_to(x+r,y) c.line_to(x+w-r,y); c.curve_to(x+w,y,x+w,y,x+w,y+r) c.line_to(x+w,y+h-r); c.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h) c.line_to(x+r,y+h); c.curve_to(x,y+h,x,y+h,x,y+h-r) c.line_to(x,y+r); c.curve_to(x,y,x,y,x+r,y) c.close_path() c.fill() }}} == A Gtk+ label that supports text wrapping with fluid reflow == {{{ #!python import gtk, pango, gobject class WrapLabel(gtk.Frame): def __init__(self, markup = None, text = None): gtk.Frame.__init__(self) self.set_shadow_type(gtk.SHADOW_NONE) self.pango_layout = self.create_pango_layout(text or "") if markup: self.pango_layout.set_markup(markup) self.pango_layout.set_wrap(pango.WRAP_WORD_CHAR) ev = gtk.EventBox() ev.set_visible_window(False) self.add(ev) def do_expose_event(self, event): gtk.Frame.do_expose_event(self, event) self.set_size_request(-1, (self.pango_layout.get_size()[1] // pango.SCALE + 10)) x,y,w,h = self.allocation gc = self.window.new_gc() self.pango_layout.set_width(w * pango.SCALE) self.window.draw_layout(gc, x, y, self.pango_layout) gobject.type_register(WrapLabel) w = gtk.Window() w.connect("destroy", gtk.main_quit) label = WrapLabel("This is a test") w.add(label) w.show_all() gtk.main() }}} == Build a Gtk+ toolbar with UIManager == {{{ #!python def on_action(action): print "Action performed!" actions = gtk.ActionGroup("Actions") actions.add_actions([ ("bold", gtk.STOCK_BOLD, "_Bold", "B", None, on_action), ("italic", gtk.STOCK_ITALIC, "_Italic", "I", None, on_action), ("underline", gtk.STOCK_UNDERLINE, "_Underline", "U", None, on_action), ]) ui_def = """ """ ui = gtk.UIManager() ui.insert_action_group(actions) ui.add_ui_from_string(ui_def) vb = gtk.VBox() vb.pack_start(ui.get_widget("/toolbar_format"), False) vb.pack_start(editor, True) }}} == What to do instead of using eval() [this is safe security-wise] == {{{ #!python import ast ast.literal_eval ('[1,2,3,(4,5,6)]') }}} == How to use doctests well == Don't. == Getting your packages updated == {{{ #!python import os os.system('evolution mailto:seb128@debian.org?subject=hi') # actually, he'll notice by himself. from time import sleep sleep (8 * 60 * 60) # go to bed }}} == How to set up a threaded GTK+ app == {{{ #!python import pygtk pygtk.require('2.0') import gobject import gtk from threading import Thread class Window(gtk.Window): '''GtkWindow wrapper''' def __init__(self): gtk.Window.__init__(self) self.set_title("Threaded GTK+ Sample") self.set_default_size(320, 240) Thread(target=self.timeout_thread).start() def timeout_thread(): '''Threaded timeout demo''' gtk.gdk.threads_enter() self.show() gtk.gdk_threads_leave() if __name__ == "__main__": gobject.threads_init() gtk.gdk.threads_init() try: win = Window() win.show() gtk.gdk.threads_enter() gtk.main() gtk.gdk.threads_leave() except KeyboardInterrupt: gtk.main_quit() }}} == Set the text on a pygtk widget in a Quickly app == {{{ #!python widge = self.builder.get_object("object_name").set_text(my_string) }}} == Get the text for a pygtk widdget in a Quickly app == {{{ #!python self.builder.get_object("object_name").get_text(my_string) }}} == Download an image from the web and save it == {{{ #!python import urllib img_stream = urllib.urlopen(url) img_file = open(fname,'w') img_file.write(img_stream.read()) del img_file }}} == Download a large file using a read buffer, saves memory == {{{ #!python import urllib img_stream = urllib.urlopen(url) img_file = open(fname,'w') while True: buf = img_stream.read(4096) if buf == "": break img_file.write(buf) del img_file }}} == Compute the md5sum of a file without loading it all in memory == Still dealing with large files. {{{ #!python import hashlib f = open(filepath) digest = hashlib.md5() while True: buf = f.read(4096) if buf == "": break digest.update(buf) f.close() print digest.hexdigest() }}} == Use couchgrid and change the label of the column == {{{ #!python from desktopcouch.records.couchgrid import CouchGrid db="db name" record_type="record type" #the keys field is for to label the column and give a discription of what is in that column keys=["key","another key"] self.couchgrid=CouchGrid(db,record_type=record_type,keys=keys) self.couchgrid.show() #put the couchgrid into a vbox self.builder.get_object("vbox1").pack_end(self.couchgrid) self.couchgrid.editable=True #change the name of the couchgrid column couchgrid.get_column(0).set_title("some name") #make the couchgrid column name dissapear self.couchgrid.set_headers_visible (False) }}} == Get stuff from a desktop couch db == {{{ #!python from desktopcouch.records.server import CouchDatabase from desktopcouch.records.record import Record __couchdb = CouchDatabase("db name",create=True) record_type="record type" results = __couchdb.get_records(record_type=record_type,create_view=True) #this takes the output of results and puts it into a string x x=" ".join(r.value["key"] for r in results) }}} == PDB tip == {{{ pp locals() }}} == Parse a line-based text file with separators == Not that advanced, but I seem to have to write this all the time. {{{ #!python def parse_line(lines, separator): for line in lines: yield [token.strip() for token in line.split(separator)] }}} == Create a pygtk window on the fly == {{{ #!python test_window = gtk.Window(gtk.WINDOW_TOPLEVEL) test_window.connect("destroy", gtk.main_quit) test_window.set_title("my title") test_window.set_default_size(200,75) test_window.show() }}} == Reading a bunch of stuff out of a function == {{{ #!python total = [] for chunk in iter(lambda: file.read(4096), ''): total.append(chunk) result = ''.join(total) }}} == Printing to a physical printer on linux == {{{ #!python import os printer=os.popen('lp','w') printer.write('sometext') printer.close() }}} == Transposing a list of lists == {{{ zip(*list_of_lists) }}} == Easy sorted merging of two lists (works also for dicts) == Not exactly efficient. {{{ #!python l1 = [4, 5, 6] l2 = [4, 6, 7] for item in sorted(set(l1)|set(l2)): do_a_thing(item) }}} == Add a message indicator == {{{ #!python import indicate, time def display(indicator): print "Ah, my indicator has been displayed" def server_display(server): print "Ah, my server has been displayed" server = indicate.indicate_server_ref_default() server.set_type("message.im") server.set_desktop_file("/usr/share/applications/empathy.desktop") server.connect("server-display", server_display) indicator = indicate.Indicator() indicator.set_property("subtype", "im") indicator.set_property("sender", "IM Client Test") indicator.set_property_time("time", time.time()) indicator.show() indicator.connect("user-display", display) }}} == Post a microblog message using Gwibber == === In Karmic === {{{ #!python bus = dbus.SessionBus() db_mb_obj = bus.get_object("com.Gwibber", "/com/gwibber/Microblog") microblog = dbus.Interface(db_mb_obj, "com.Gwibber") import gwibber, gwibber.config accounts = gwibber.config.Accounts() args = ["This is a test message"] for account in accounts: if account["send_enabled"]: acctid = account["id"] microblog.operation({ "source": "my app name", "id": "send-%s-%s" % (acctid, time.time()), "accountid": acctid, "args": args, "opname": "send", }) }}} === In Lucid (not yet uploaded) === {{{ #!python import gwibber.utils foo = gwibber.utils.GwibberPublic() foo.post("This is a test message") }}} == Parse command line arguments == {{{ #!python import optparse op = optparse.OptionParser('%prog [options] inputfile') op.add_option('-f', '--force', action='store_true', dest='force', default=False, help='Delete my files without asking') op.add_option('-o', '--output-file', dest='outfile', help='Output file path; if not given, output to stdout') (opts, args) = op.parse_args() if opts.force: print 'force enabled' input_file = args[0] if opts.outfile: outfile = open(opts.outfile, 'w') else: outfile = sys.stdout }}} == SQLite == {{{ #!python import sqlite3 as dbapi2 db = dbapi2.connect('mydb.sqlite') cur1 = db.cursor() cur1.execute('CREATE TABLE friends (name VARCHAR(255), phone int)') cur1.commit() cur1 = db.cursor() cur1.execute('SELECT phone FROM friends WHERE name = ?', ['Fred']) # does proper quoting for (phone) in cur1: print 'Fred has telephone number', phone }}} == Apply file rights from src to dest == {{{ #!python import os, stat st = os.stat(src_file_name) mode = stat.S_IMODE(st.st_mode) os.chmod(dest_file_name, mode) }}} == Translations using gettext == {{{ #!python import gettext # Print 'hello' (it needs to be translated first though). print gettext.gettext("hello") }}} == A really simple unittest module. == {{{ #!python import unittest class TestThing(unittest.TestCase): def setUp(self): super(unittest.TestCase, self).setUp() self.data = [2, 3, 5] def test_list_reversal(self): backwards = reversed(self.data) self.assertEqual([5, 3, 2], backwards) def tearDown(self): del self.data }}} Note that you wouldn't really use setUp and tearDown for something this simple. Use them when you have something fairly complicated to set up. == Look for a program that is already registered over dbus == {{{ #!python import dbus session_bus = dbus.SessionBus() if session_bus.request_name ('net.soft.name') != 1: print 'someone already has this name' exit() }}} == Open a file from a dialog == {{{ #!python dialog = gtk.FileChooserDialog( "Select a file", w, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) if dialog.run() == gtk.RESPONSE_OK: fn = dialog.get_filename() if os.path.exists(fn): print fn dialog.destroy() }}} == Create a TextEntry with auto-completion in PyGTK == {{{ #!python import pygtk import gtk import gobject # contains the data for autocomplition, can be dynamic options = ("Friends", "Family", "Person", "Test") def entry_changed (editable, *user_data): comp = user_data[0] text = editable.get_text() matches = [] if text: for current_option in options: if current_option.startswith(text): matches.append(current_option) model = comp.get_model() model.clear() for match in matches: model.append([match]) win = gtk.Window() entry = gtk.Entry() completion = gtk.EntryCompletion() entry.set_completion(completion) liststore = gtk.ListStore(gobject.TYPE_STRING) completion.set_model(liststore) completion.set_text_column(0) win.add(entry) entry.connect("changed", entry_changed, completion) win.connect("delete-event", gtk.main_quit) win.show_all() gtk.main() }}} == Check if script runs as root == {{{ #!python import os, sys if os.geteuid() != 0: print 'You must be root to run this script' sys.exit(0) }}}