Spinsels op het web
actions » SearchLogin 310 articles • 05 Feb 2012

Recent articles in 'Python'

Tuesday, 29 Nov 2011

permalink Compiling Python from source on Ubuntu 11.x multiarch

Ubuntu 11.x has changed the location for 64/32 bits libraries ("multiarch") and this can cause some hiccups when trying to build Python from source. Make sure to sudo apt-get install dpkg-dev to get the dpkg-architecture tool installed. Otherwise you'll get compile errors because some system libs can't be found (zlib, ssl, etc).

See also http://bugs.python.org/issue11715

And, ofcourse, you'll need to install various -dev packages such as zlib1g-dev to satisfy Python's library dependencies. You can see which ones you're missing by taking a look at the compile output where it complains about failed modules.

• Wrote irmen at 23:03 | read 11× | 0 Comments

Sunday, 27 Nov 2011

permalink pickle efficiency when dealing with binary data

For my Pyro project I recently wrote in some detail about the pickle efficiency of various types when dealing with binary data. I've added it to the Pyro documentation but it is also useful when dealing with pickle in general.

So, here is a short overview of the pickle wire protocol overhead for the possible types you can use when transferring binary data:

  • str
    Python 2.x: efficient; directly encoded as a byte sequence, because that’s what it is. Python 3.x: inefficient; encoded in UTF-8 on the wire, because it is a unicode string.
  • bytes
    Python 2.x: same as str. Python 3.x: efficient; directly encoded as a byte sequence.
  • bytearray
    Inefficient; encoded as UTF-8 on the wire (pickle does this in both Python 2.x and 3.x)
  • array("B") (array of unsigned ints of size 1)
    Python 2.x: very inefficient; every element is encoded as a separate token+value. Python 3.x: efficient; uses machine type encoding on the wire (a byte sequence).

Your best bet seems to be to use the bytes type (and possibly the array("B") type if you’re using Python 3.x) and stay clear from the rest. It’s strange that the bytearray type is encoded so inefficiently by pickle.

A bytearray is pickled (using max protocol) as follows:

>>> pickletools.dis(pickle.dumps(bytearray([255]*10),2))
    0: \x80 PROTO      2
    2: c    GLOBAL     '__builtin__ bytearray'
   25: q    BINPUT     0
   27: X    BINUNICODE u'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
   52: q    BINPUT     1
   54: U    SHORT_BINSTRING 'latin-1'
   63: q    BINPUT     2
   65: \x86 TUPLE2
   66: q    BINPUT     3
   68: R    REDUCE
   69: q    BINPUT     4
   71: .    STOP

>>> bytearray("\xff"*10).__reduce__()
(<type 'bytearray'>, (u'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff', 'latin-1'), None)

Most notably, the actual *bytes* in the bytearray are represented by an UTF-8 string. This needs to be transformed into a unicode string and then encoded back into bytes, when unpickled. The thing being a bytearray, I would expect it to be pickled as such: a sequence of bytes. And then possibly converted back to bytearray using the constructor that takes the bytes directly (BINSTRING/BINBYTES pickle opcodes).

The above occurs both on Python 2.x and 3.x.

I have no idea yet why this is. Maybe I'll write a patch to improve it, doesn't seem that hard to do.

    • Read more »
• Wrote irmen at 15:39 (edited 2×, last on 30 Nov 2011) | read 20× | 0 Comments

Tuesday, 08 Nov 2011

permalink Package install tools: pip and easy_install, by means of distribute

This article is in English because it is about a topic that can be useful for a lot of people. It is about getting easy_install and pip going on your different Python versions.

Note: easy_install originally comes from the setuptools package, that has recently been superseded by distribute. Distribute is where it all starts, see its homepage: http://packages.python.org/distribute/

(>) TL;DR

  1. use your system's package manager if possible, to skip step 2-4 and perhaps even 5
  2. download and install distribute via its bootstrap script distribute_setup.py
  3. use easy_install to install pip (or use its bootstrap script get-pip.py)
  4. use pip to install virtualenv
  5. create and active a virutalenv and install the rest of your packages there

Read on for more details about each of these steps.

(!) Before everything else: use your package manager!

If your system provides a package manager it is strongly advised to use that if it provides the packages you need. Don't screw around by installing stuff yourself if the package manager can do it for you. We're talking about the following:

  • python-distribute
  • python-setuptools (only if there's no python-distribute!)
  • python-pip
  • python-virtualenv

(or similar names). Notice that often this only provides these packages for the system default python, so if you have another python version installed, read on. If you don't have a a package manager because you are on Windows or Mac OS X, read on.

    • Read more »
• Wrote irmen at 00:09 (edited 6×, last on 08 Nov 2011) | read 452× | 0 Comments

Sunday, 01 May 2011

permalink Jenkins als CI server voor Python

Jenkins is een CI-server. (Zie remoteother article voor de installatie ervan) De focus is Java maar hij kan ook andere jobs aan. Dat wilde ik wel uitproberen omdat ik nieuwsgierig was hoe dat werkt voor Python projecten. :-)

Ik wil een continuous build job en een nightly build job maken. De continuous build job is bedoeld voor het continuous integration aspect. De nightly build is bedoeld om daadwerkelijk buildresultaten op te leveren, die je kunt publiceren (de zogenaamde artefacts).

We beginnen met de continuous builds. Lees hieronder verder hoe dat in zijn werk gaat.

    • Read more »
• Wrote irmen at 22:54 (edited 2×, last on 01 May 2011) | read 88× | 0 Comments

Wednesday, 30 Mar 2011

permalink Dynamic Programming met Python. Deel 3: named tuples.

Interessante voorbeelden van Dynamic Programming met Python.

  1. inleiding & de Fibonacci reeks; remoteother article
  2. rich comparison; remoteother article
  3. named tuples.

Tuples (immutable sequence) zijn handig maar niet handig genoeg: alle elementen kun je alleen met een indexnummer benaderen, en als er in de toekomst een verandering aan volgorde of aantal plaatsvindt, moet je moeilijk zoeken door je code om de indexering te fixen.

Vandaar collections.namedtuple: Een tuple waarbij de velden ook een naam hebben en niet alleen een numerieke index. En met een paar handige extra methods. Voorbeeld:

>>> import collections
>>> Vector=collections.namedtuple("Vector", "x y")
>>> v=Vector(4,7)
>>> v.x
4
>>> v.y
7
>>> v[0]
4
>>> v[1]
7
>>> v._asdict()
OrderedDict([('x', 4), ('y', 7)])

Het lijkt een beetje op een struct of enum uit andere programmeertalen maar het biedt meer (zoals gewoonlijk).

  • het is een gewone class dus je kunt ervan overerven (de onderliggende class wordt tijdens runtime gegenereerd).
  • en named tuple heeft 0 runtime memory overhead t.o.v. een normale tuple.
  • je kunt aan een bestaande named tuple velden toevoegen.
  • je kunt ze on-de-fly definiëren op basis van een sequence (of string) van veldnamen.
  • handig om te weten: ze zijn pickleable.

Meer interessante dingen (subclassing, csv-files lezen) met named tuples hieronder:

    • Read more »
• Wrote irmen at 00:07 | read 22× | 0 Comments

Monday, 28 Mar 2011

permalink Dynamic Programming met Python. Deel 2: rich comparison.

Interessante voorbeelden van Dynamic Programming met Python.

  1. inleiding & de Fibonacci reeks; remoteother article
  2. rich comparison.

Je kunt een eigen ordening definieren tussen objecten van een zelfgemaakte class. Daarmee kun je de sorteervolgorde bepalen, en ook zorgen dat vergelijkingen zoals obj1 <= obj2 een zinvol resultaat geven. Voorheen kon je dat redelijk eenvoudig doen door __cmp__ te implementeren in je class, maar dat is deprecated omdat Python nu Rich Comparison semantics heeft. Helaas is daarvan het gevolg dat als je volledig correct werkende comparisons wilt hebben (met eigen gedrag), je alle rich comparisons methods moet definieren. Dus: __lt__, __le__, __gt__, __ge__, __eq__, __ne__. Dat is vervelend en foutgevoelig.

Stel we maken een Student class als volgt, waarbij we willen dat je 'm kan sorteren op naam, zonder dat we verschil willen tussen hoofd- en kleine letters:

class Student(object):
    def __init__(self, name):
        self.name=name
    def __eq__(self, other):
        return self.name.lower()==other.name.lower()
    def __lt__(self, other):
        return self.name.lower() < other.name.lower()

assert Student("Zoe") >= Student("Henry")    # simpele check faalt

Dit is een aardig begin maar de assert faalt, dus deze code is niet voldoende om alle comparisons correct te laten zijn!

Lees verder om te zien hoe je dit in Python met 1 regel code extra kunt oplossen.

    • Read more »
• Wrote irmen at 00:17 (edited 3×, last on 30 Mar 2011) | read 23× | 1 Comments

Sunday, 27 Mar 2011

permalink Dynamic Programming met Python. Deel 1: fibonacci.

Interessante voorbeelden van Dynamic Programming met Python.

Wat is Dynamic Programming?

Wikipedia beschrijft het als a method for solving complex problems by breaking them down into simpler subproblems. Oftewel: als we een bepaald ingewikkeld probleem moeten oplossen, kunnen we dat doen door het op te delen in kleinere, simpelere, problemen. Deze lossen we dan per stuk eenmalig op. Meestal betekent dat dat we dan uiteindelijk minder inspanning kwijt zijn, omdat het vaak gebeurt dat die kleinere problemen vaker voorkomen (in dezelfde of vergelijkbare vorm). Merk op dat b.v. mergesort niet beschouwd wordt als een dynamic programming problem, omdat de deelproblemen veel simpeler zijn als het hoofdprobleem (het samenvoegen van twee reeksen van getallen is triviaal ten opzichte van de sorteer actie zelf).

Wat is een Dynamic Programming Language?

Dit heeft niet direct iets te maken met Dynamic Programming. Wikipedia beschrijft het als a class of high-level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all. Oftewel: een dynamic programming language heeft directe ondersteuning om dingen zoals onderstaande tijdens runtime te kunnen doen:

  • aanpassen van eigenschappen van objecten of classes
  • aanpassen of toevoegen van code
  • veranderen van gedrag van het type system
  • geavanceerde 'reflection' op data
  • rebinding van names zodat ze naar iets anders kunnen wijzen.
  • ...en meer

Ook zijn veel dynamic programming languages dynamically typed. Let op: dat is iets anders als weakly typed of stringly typed!

Python is een prachtig voorbeeld van dit alles. En na het bekijken van een aantal presentaties van PyCon 2011 (remoteother article) leek het me leuk om een aantal inspirerende voorbeelden op een rijtje te zetten. Sommigen vallen onder dynamic programming, anderen misschien meer onder dynamic programming language, maar eingelijk doet het er niet zoveel toe. Wat er wel toe doet is dat het goeie voorbeelden zijn van dingen die je niet of nauwelijks voor elkaar kan krijgen in een ouderwetse (of gewone, zo je wilt) taal zoals Java of C#.

Deel 1 volgt hieronder en gaat over Fibonacci getallen.

    • Read more »
• Wrote irmen at 21:45 (edited 3×, last on 28 Mar 2011) | read 56× | 0 Comments

Tuesday, 22 Mar 2011

permalink Pycon 2011 presentaties

Interessante presentaties van Pycon 2011.

(>) Keynote speech Door Hilary Mason van bit.ly. Wat een vrolijk mens :-D En een leuke presentatie!

(>) How to sell Python Een panel discussie over hoe je Python 'verkoopt' binnen je organisatie. Panel bestond uit mensen uit de academische wereld, overheid, grote organisaties, kleine organisaties, en non-profit.

(>) Qtile Lightning Talk Lekker kort en droge humor over een Linux window manager. Door Matt Harrison. ("... and there is this one that's called Awesome. The cool thing is that it is written in LUA and thus it is indexed by 1 instead of zero, and that's awesome..." ;-) "Help Qtile grow exponentially. We only need about 2 of you")

(>) Algorithmic Generation of OpenGL Geometry leuke presentatie waarbij je schermen vol met draaiende kubusjes te zien krijgt. Mogelijk interessant: PyEuclid 3d-library

(>) How DropBox did it and how Python helped toch wel 1 van de meer indrukwekkende systemen die (vrijwel) geheel in Python zijn gebouwd...

(>) Disqus: 500 million users ...maar misschien is Disqus nog wel groter dan Dropbox ;-)

(>) Scaling Python past 100 Over de nieuwe Sourceforge.net die helemaal in Python gemaakt is (met Apache mod_wsgi als webserver en MongoDB als datastore).

(>) Running ultra large telescopes (arrays) with Python Leuke presentatie over het besturen van een telescope array in Zuid-Afrika dmv een Python interface

(>) Greasing the wheels of exploration besturen van de Mars rovers met Python

(>) Testing with Mock over de Mock library voor Python maar ook over mocking en unit testing in het algemeen.

Deze zijn nog van PyCon 2010 vorig jaar:

(>) A study of continuous integration systems Conclusie: "just use Hudson". Tevens: "Use Distribute and PIP".

(>) What every webdeveloper should know about database scalability Door Jonathan Ellis, van Apache Cassandra. ("You don't have to be a very successful web app to have a couple of million users. So that's why [...] every web app's scalability/performance bottle neck is the database." En over een mogelijk probleem met een caching strategie: "...It's a rare condition, but it still makes us not sleep well. because even rare conditions - when you have millions of users - are going to happen sometime.")

• Wrote irmen at 23:05 (edited 13×, last on 27 Mar 2011) | read 26× | 0 Comments

Tuesday, 15 Mar 2011

permalink Python compile probleem op OS X

Sinds Python 3.x krijg ik compile-errors als ik een 'framework' build wil maken from source; iets met undefined symbols. Wat geëxperimenteer met diversie compiler opties mocht niet baten.

Het blijkt een bugje in de makefile te zijn die zich manifesteert op Mac OS in dit specifieke geval (zie http://bugs.python.org/issue1099).

Oplossing: "The simplest workaround is to include the --enable-universalsdk option to configure, so something like this:

./configure --enable-framework --enable-universalsdk=/

That has the side effect of causing a universal build (ppc and i386). "

Gelukkig is het probleem kortgeleden in de Python hg repo verholpen. Je hoeft alleen de workaround van hierboven te doen als je de officiële release sources wilt compileren.

• Wrote irmen at 00:08 | read 10× | 0 Comments

Wednesday, 29 Dec 2010

permalink selecteer random element uit een grote lijst (of: regel uit file)

Als je van te voren weet hoe veel elementen je hebt om uit te kiezen, is het kinderlijk eenvoudig om 1 willekeurige daaruit te kiezen: Neem een willekeurig getal tussen 1...N en pak het zoveelste element.

Als je de complete verzameling zonder problemen in memory kan houden, kun je het in Python direct met random.choice(...) doen.

Het wordt lastiger als de verzameling elementen niet in 1 keer in memory gelezen kan worden (bijvoorbeeld omdat hij te groot is, of zelfs een onbekende grootte heeft). Een voorbeeld is dat je een willekeurige regel uit een tekstbestand wilt hebben waarbij je niet van tevoren weet hoe groot dat bestand is.

Je kunt proberen het hele bestand in te lezen en daarna 1 regel eruit te halen zoals boven beschreven, maar dat kost erg veel tijd en geheugen als het bestand groot is. Beter is om een slim algoritme te gebruiken:

import random

def random_line(afile):
    line = next(afile)
    for num, aline in enumerate(afile):
        if random.randrange(num + 2): continue
        line = aline
    return line

Dit is de Python implementatie van Waterman's "Reservoir Algorithm". Het loopt de complete file slechts 1 keer door en heeft nooit meer geheugen nodig dan de huidige regel lang is. Bron.

• Wrote irmen at 23:46 | read 83× | 0 Comments

10 shown; more articles may be found in the archives. The permalink icon is the article's permalink.
Process times: page=0.068 request=0.084 cpu=0.070