Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Tuesday, June 26, 2012

Python and Qt on BlackBerry [PlayBook]

I've just bought a BlackBerry PlayBook. After been spending some time with a borrowed PlayBook I decided to buy one myself. Many of you might wonder why the hell I did that but I really think it's a great device. The three top things that made me buy the PlayBook are:
  • Cheap! Good value for the money, the 32 Gb version for only €249
  • Awesome user experience. Really love those swipe gestures which only requires one finger so you can pretty much operate the device with only one finger :). It also gets addictive!
  • It runs Qt and Python!
You might argue that there are very little apps for the PlayBook but admittedly I mostly use the browser so that isn't such a big deal for me. The native PIM-apps integrates well with Google services, such as mail, calendar and contacts. The only thing that I'm missing is an official twitter client. There're a bunch of them on AppWorld but I haven't had time to checked them out yet. RIM do also claim that the PlayBook will be upgradeable to BlackBerry 10 so that should give some confidence of the PlayBook having an upgrade path :)

The PlayBook is powered by QNX which is a real-time micro kernel and supports a lot of POSIX APIs. This basically means that many open source apps/libs for Linux can be ported with little or no effort. What I think is rather cool is that Python 3.2 is pre-installed on the PlayBook which you can use to run Python application.

BlackBerry-Py is a project which goal is to build an environment to support application development in Python for the PlayBook and the upcoming BlackBerry 10 OS. BB-Py uses PySide (Python bindings for Qt) for the UI and the project is also working on support for Cascades. It's very easy to get started so I'll just point you to the "Hello World" example which describes every step you need to take to deploy an app to the device. And no, I didn't find it that hard to get the debug token which you need to install your app on the device :).

Currently the PlayBook OS doesn't include the Qt libraries so they, and PySide, need to be bundled with your app. BB10 is using Qt to a great extent (Cascades is built on top of Qt) and the libraries will be available on the filesystem, only PySide needs to be bundled.

Oh, you also need to download an SDK, for example the Native SDK, to get the required tools for packaging and deploying.

Wednesday, June 22, 2011

Nokia N9 and Python

Yet another great day to be a python coder! The new Harmattan/MeeGo device, Nokia N9, will be packed with support for Python!

For more info, look here

Yes, it seems that you can publish your python apps on ovi... Nokia Store too.

Sunday, June 19, 2011

QtQuick - From Bling Bling To Blink Blink

Probably most of you already know that QtQuick is used to create amazing blingalicous UIs without too much effort. The declarative QML language makes it very easy to create object instances and setup property bindings, animation, states etc. Lately I’ve been tinkering with my Velleman K8055 USB experiment board and wanted to create a nice UI to control the board. It didn’t take too long until I was thinking a little bit out side of the box and started experimenting with controlling the board with QtQuick but without a UI. I created a couple of QML components on the C++ side to control the input/outputs of the board and quickly realized the possibilities QML provides even for non-UI applications.

Basically what I did was to create a declarative engine and not a declarative view. By doing this you can have a QML file interpreted and access to the object instances created by the engine from within your C++ code. I see a lot of potential and possibilities, one thing that comes to my mind straight away is to utilize QML as a Dependency Injection container :)
QDeclarativeEngine *engine = new QDeclarativeEngine;
QDeclarativeComponent component(engine, QUrl("qrc:/example1.qml"));
Board *board = qobject_cast<board *>(component.create());
Example code to interpret a QML file
The source code is available at k8055tinker

Check out the video below which demonstrates my code:


I've also tagged this post with Python because it can be of interest for the planet python readers since this can also be accomplished with PySide.

Saturday, May 21, 2011

I wish that I had Jessie's girl...

Rick Springfield had a great hit with a song called Jessie's Girl and the same track is now used for the Nokia N9 teaser ad which popped up a couple of days ago.

I really hope this is a MeeGo device, or to be honest, I just hope it's a Linux + Qt/QtQuick enabled device with some MeeGo compliance.

I've had quite a lot of fun with QtQuick lately (both for desktop and my N8) and I really enjoy using it. It just open so much possibilities and lets you be creative.

Another thing that would be awesome is if Nokia actually puts PySide, the Nokia sponsored Qt-bindings for Python, on the handset. Having Python as a rapid back-end language combined with QtQuick for the view is just too sweet :)

Grr... I hate not knowing, but I just have to wait and see.

Tuesday, March 29, 2011

PySide and QML

It has been out there for a while but I haven't had time to try it out, PySide 1.0 with QML support!

This really gives you a über rapid app development environment. The power of Python combined with the awesomeness of the declarative language QML from the Qt framework.

Take a look and feel free to play with the example below:
from PySide import QtCore
from PySide import QtGui
from PySide import QtDeclarative

class Message(QtDeclarative.QDeclarativeItem):

    messageChanged = QtCore.Signal()

    def __init__(self, parent = None):
        QtDeclarative.QDeclarativeItem.__init__(self, parent)
        self._msg = u''

    def getMessage(self):
        return self._msg

    def setMessage(self, value):
        if self._msg != value:
            print "Setting message property to", value
            self._msg = value
            self.messageChanged.emit()
        else:
            print "Message property already set to", value

    message = QtCore.Property(unicode, getMessage, setMessage, notify=messageChanged)


def main():
    app = QtGui.QApplication([])

    QtDeclarative.qmlRegisterType(Message, "utils", 1, 0, "Message")

    win = QtDeclarative.QDeclarativeView()
    win.setSource("main.qml")
    win.setWindowTitle("Hello World")
    win.setResizeMode(QtDeclarative.QDeclarativeView.SizeRootObjectToView)

    win.show()
    app.exec_()

if __name__ == "__main__":
    main()
import Qt 4.7 // or QtQuick 1.0 if applicable

import utils 1.0

Rectangle {
    id: main

    signal clicked

    color: "black"
    width: 360; height: 360

    Message {
        id: msg

        message: "Click Me!"
        onMessageChanged: label.font.pixelSize = 40
    }

    Text {
        id: label

        anchors.centerIn: parent

        text: msg.message
        color: "white"
        font.pixelSize: 25

 Behavior on font.pixelSize {
            NumberAnimation { duration: 800; easing.type: Easing.OutBounce }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: msg.message = "Hello World"
        }
    }

}
For more information point your browser to http://www.pyside.org and download the package for your OS.

You'll also find useful information at http://developer.qt.nokia.com/wiki/Category:LanguageBindings::PySide

Happy hacking!

Saturday, November 6, 2010

Getting Interactive With PyQt

One of the cooler features with PyQt (IMHO) is the possibility to write Qt code interactively. It isn't actually something new and I'm sure it's been there for a while but some of you might not be aware of it. I find it very useful when I want to learn new things in Qt, so without further ado, here's a short introduction on using it.

Start an interactive python session by executing python in a shell:
$> python
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Let's create a simle top-level window (I wont add the '>>>' in case you would like to copy/paste the code):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
app = QApplication([])
window = QWidget()
window.resize(400, 300)
window.show()
Now you should have a window similar to the screen shot below:

Ok, let's create a push button:
button = QPushButton("Click Me!", window)
Hmm, no button shows up... Why? Well, that's because we need to make it visible after we have added it to the window:
button.show()
Ahh, sweet! We have added the button to the window interactively:
Let's put the button at the center of the window by using a layout manager:

layout = QHBoxLayout(window)
layout.addWidget(button)


And finally, let's see how 'layout.addStretch()' affects the layout:
layout.addStretch()

You can easily add a slot to the button's clicked signal:
def mySlot():
    print "Button Clicked"
button.clicked.connect(mySlot)
As you can see, it's an easy way to try out thing in Qt.

Thanks for reading!

Saturday, September 11, 2010

PyQt and Signal overloads

I almost spent half an hour trying to figure out why my code didn't work.

I used a QSignalMapper to connect a couple of clickable widgets to emit just one signal, widgetClicked(int index), instead of having multiple signals, one for each widget. I connected the widgetClicked signal to the mapped signal of the QSignalMapper class and did the required set up for the signal mapper, something like the following snippet:
self._signalMapper = QSignalMapper(self)
self._signalMapper.mapped.connect(self.widgetClicked)

for index, widget in enumerate(buttons):
    widget.clicked.connect(self._signalMapper.map)
    self._signalMapper.setMapping(widget, index)

Everything worked fine until I changed the signature of widgetClicked to pass a string instead of an int, it didn't work anymore. I only got the following print out: TypeError: connect() failed between 'mapped' and 'widgetClicked' and had no clue why because the mapped signal has a couple of overloads:
void mapped(int i)
void mapped(const QString & text)
void mapped(QWidget * widget)
void mapped(QObject * object)
I did also try changing widgetClicked to not receive any arguments and that worked, which was expected because the receiver is not required to match all arguments of a signal. Of course, it also worked if I changed back to int...

What the #@! is going on? Naturally, I had no option of searching for answers since I was sitting on the train back home from work and had no Internet connection.

Then it come to me, Python is not aware of the C++ signature overload. Python doesn't support overloading. Python/PyQt can't set up the right connection between widgetClicked and mapped. But how do you specify which of the overloads you want to connect to? By indexing:
# This connects your slot/signal to the string-overload
signalMapper.mapped[str].connect(...)
The int overload will be used default by PyQt, that's why my code worked when I connected widgetClicked to mapped w/o specifying which overload I wanted.

Wednesday, September 1, 2010

Python Koans - A Great Way to Learn Python!

I just found out about Python Koans by Greg Malcolm (thanks dude) after listening to the from python import podcast podcast (which I find amusing, thanks guys).

It's an awesome way to learn Python. Instead of just reading tutorials and/or books you learn Python by coding.

The interactive tutorial is built around unit-tests and you advance and gain new skills by passing tests and it's really funny. You do learn a lot about the Python language when doing the Koans so I recommend it even if you've been using Python for a while.

Another cool thing is that you learn how to do unit testing in Python, if you're not already familiar with it.



Tuesday, August 3, 2010

My python fix

It has been a while since I did something in Python. I've been coding C++, Qt and Qt Quick lately and I do enjoy it, especially Quick. I really like the declarative way of describing UIs.

But I still need my shot of Python now and then. Often I end up just doing small non useful snippets like list comprehensions stuff. I just love them, they are so beautiful and they make me happy :)
>>> # Find the longest words
>>> words = "Some random words in a text string"
>>> max([(len(w), w) for w in words.split()], key=lambda x:x[0])[1]

Thursday, June 10, 2010

QSignalMapper - at your service

The QSignalMapper class is very useful, for example, in situations were you have a couple of QPushButtons and you want to connect the clicked-signal of each button to a single slot and still be able to identify the sender. It's possible to find out which object emitted a signal by calling sender() inside the slot, but I don't think that's good practice because you introduce a strong coupling between the signaling object and the slot.

A better solution is to use the QSignalMapper class which re-emits the signal with an additional configurable parameter. The parameter can be one of the following types: int, QString, QObject or QWidget.

So without further ado, here's a self describing example:
#
# Example showing how QSignalMapper can be used to manage an arbitrary
# numbers of parameterless signals and re-emit them with an argument
# identifying the sender.
#
# Each signal is associated in the QSignalMapper with either an int,
# QString, QObject or a QWidget which is passed as argument to the slot
# connected to the QSignalMapper.
#
from PyQt4.QtCore import QSignalMapper, pyqtSignal
from PyQt4.QtGui import QApplication, QFrame, QGridLayout, QPushButton

class Grid(QFrame):
    """ Lay out widgets in a grid. """

    clicked =  pyqtSignal(int)
    """
    This signal will be emitted when on one of the grid items is clicked.
    The grid item's index will be passed as argument.
    """

    def __init__(self, items, colCount, parent=None):
        """
        Create Grid and setup QSignalMapper.

        Connect each item's 'clicked' signal and use the sequence index
        as map value which will be passed as argument when the Grid's
        clicked signal is emitted.

        items: sequence with widgets having a 'void clicked()' signal
        colCount: column count for each row
        parent: parent widget, default None
        """
        super(Grid, self).__init__(parent)

        # Create a grid layout.
        layout = QGridLayout()
        self.setLayout(layout)

        # Create the signal mapper.
        signalMapper = QSignalMapper(self)

        for cnt, item in enumerate(items):
            # Setup mapping for the item. In this case, the
            # mapping is the sequence index of the item.
            signalMapper.setMapping(item, cnt)

            # Connect the item's 'clicked' signal to the signal
            # mapper's 'map' slot.
            # The 'map' slot will emit the 'mapped' signal
            # when invoked and the mapping set previously will be
            # passed as an argument to the slot/signal that is
            # connected to the signal mapper's 'mapped' signal.
            item.clicked.connect(signalMapper.map)

            # Add the widget to the grid layout
            layout.addWidget(item, cnt / colCount, cnt % colCount)

        # Forward the signal mapper's 'mapped' signal via the Grid's
        # 'clicked' signal. This will handle all widgets' 'clicked'
        # ssignals.
        signalMapper.mapped.connect(self.clicked)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)

    # Create grid items
    items = (QPushButton('Open'), QPushButton('Close'),
             QPushButton('Read'), QPushButton('Write'),
             QPushButton('Delete'))

    win = Grid(items, 2)

    # Handle grid clicks here
    @win.clicked.connect
    def clicked(index):
        print "Button at:", index, " - text:", items[index].text()

    win.show()
    sys.exit(app.exec_())
Hope this was to any help.

Wednesday, May 26, 2010

ABCs - Abstract Base Classes

What's ABCs?
The abc (abstract base class) module was introduced in version 2.6 of Python. The module provides the infrastructure for defining an abstract base class and can typically be used in situations where frameworks need to specify a bunch of interfaces to be implemented to ensure the functionality. An example can be a database application where the framework requires you to provide a Data Access Object with basic CRUD operations and therefore defines an interface, call it UserDao, with the following methods:

UserDao

  • getById - Return a user entity with the specified id
  • store - store a user entity
  • remove - remove a user entity from the persistent storage
To ensure that developers follows the protocol an abc is introduced.

The UserDao abc
The following example will show you basic usage of the abc module. You should read the module documentation for more details.

Let's create the UserDao abc:
from abc import ABCMeta, abstractmethod

class UserDao:
    """
    This interface should be implemented to provide the framework with
    basic user CRUD operations.
    """
    __metaclass__ = ABCMeta

    @abstractmethod
    def getById(self, userId):
        """ Return the user with the user id. """

    @abstractmethod
    def store(self, user):
        """ Persist the user. """

    @abstractmethod
    def remove(self, user):
        """ Remove the user from the persistent storage. """
If we try to create an instance of this class we get the following error:
>>> dao = UserDao()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class UserDao with abstract methods getById, remove, store
In other words, we have a well defined interface to support CRUD operations for User entities and we also have an easy to read documentation of what's expected from a UserDao. If we would rely on duck typing instead of defining the abc, we would need to document the expected behavior for the UserDao elsewhere. I think that the biggest advantage of using ABCs is that you have the interface definition and documentation in one place.

Just to prevent flaming :) I enjoy duck typing and use it a lot but I think that ABCs are useful is some situations.

Implementing the abc
Implementing the UserDao can be done by sub-classing the UserDao.
class User(object):
    def __init__(self):
        self.id = None
        self.name = None

class UserDaoImpl(UserDao):

    def getById(self, userId):
        user = User()
        user.id = userId
        user.name = 'A User'
        return user

    def store(self, user):
        print "Storing: ", user.id, "-", user.name

    def remove(self, user):
        print "Removing: ", user.id
And to complete the example:
userDao = UserDaoImpl()
user = userDao.getById(10)
user.name = "New Name"
userDao.store(user)
Wrap up
I haven't investigated if ABCs introduces any performance overhead but I can't really see why they should. One advantage of using ABCs in frameworks is that you can have the documentation and interface details as a simple Python class. Another advantage is that Python will issue an error if a sub-class doesn't implement all abstract methods/properties of the abc, which is probably the author's intention.

Friday, March 19, 2010

Ternary operation

I'm a big fan of using ternary operations when possible but Python didn't introduced them until the 2.5 release, see Wikipedia page. Before the 2.5 release there existed options like using the and and or operator
x and y or z
or a lambda construction, but none if them are considered foolproof (see the wiki page for explanation). So how do you write the ternary operation in python?
a, b = 1, 2

# non ternary operation
if a > b:
    z = a
else:
    z = b

# rewritten to

z = a if a > b else b
Clean, readable and simple!

Saturday, February 20, 2010

QTabWidget - Hiding the bar

It has been a while since my last post. I've been sick, my son has been sick and so has my girlfriend. Now I'm back and have been coding on a private project for a couple of days.

While I was toying and trying some ideas I found out how to create tab bars with Qt that are only visible if you have more than one tab. This is quite popular in browser for example. So without further ado, here's the code:
from PyQt4 import QtGui

class TabWidget(QtGui.QTabWidget):
    def __init__(self, parent=None):
        super (TabWidget, self).__init__(parent)
        self.setTabsClosable(True)
        self.tabCloseRequested.connect(self.removeTab)

    def tabInserted(self, index):
        self.tabBar().setVisible(self.count() > 1)

    def tabRemoved(self, index):
        self.tabBar().setVisible(self.count() > 1)
As you can see, it isn't rocket science. I did some googling but couldn't find anything about it, that's why I want to share my findings. The magic is to only hide the TabBar associated with the TabWidget, not the TabWidget itself.

You can use the following snippet to see the TabWidget in action:
import sys
from PyQt4 import QtGui

class TabWidget(QtGui.QTabWidget):
    def __init__(self, parent=None):
        super (TabWidget, self).__init__(parent)
        self.setTabsClosable(True)
        self.tabCloseRequested.connect(self.removeTab)

    def tabInserted(self, index):
        self.tabBar().setVisible(self.count() > 1)

    def tabRemoved(self, index):
        self.tabBar().setVisible(self.count() > 1)

qApp = QtGui.QApplication(sys.argv)

tab = TabWidget()

button = QtGui.QPushButton('Hello')
@button.clicked.connect
def clicked():
    tab.addTab(QtGui.QLabel('Hello'), 'Hello')

tab.addTab(button, 'Button')

layout = QtGui.QHBoxLayout()
layout.addWidget(tab)

window = QtGui.QWidget()
window.setLayout(layout)
window.resize(600, 400)
window.show()

qApp.exec_()

Saturday, January 30, 2010

Named tuple

I recently read a post on planet python and the author mentioned something about named tuple which made my curious.

So what's a named tuple?
The namedtuple was introduced in Python 2.6. A named tuple is created using a factory function from the collections module and it extends the basic tuple by assigning a name to each position in a tuple but can still be used as a regular tuple. This makes it possible to access fields by name instead of an index. The named tuple should not require more memory, according to the documentation, than regular tuples since they don't have a per instance dictionary.

The factory function signature is:
collections.namedtuple(typename, field_names[, verbose])
The first argument specifies the name of the new type, the second argument is a string (space or comma separated) containing the field names and finally if verbose is true the factory function will also print the class generated.

Enough theory, I'll show you an example.

Example
Say you have a tuple containing username and password. To access the username you get the item at position zero and the password is accessed at position one:
credential = ('mario', 'secret')
print 'Username:', credential[0]
print 'Password:', credential[1]
There's nothing wrong with this code but the tuple isn't self-documented. You have to find and read the documentation about the positioning of the fields in the tuple. This is where named tuple can enter the scene. We can rewrite the previous example as following:
import collections
# Create a new sub-tuple named Credential
Credential = collections.namedtuple('Credential', 'username, password')

credential = Credential(username='mario', password='secret')

print 'Username:', credential.username
print 'Password:', credential.password
Nice, don't you agree?

If you are interested of what the code looks like for the newly created Credential-type you can add verbose=True to the argument list when creating the type, in this particular case we get the following output:
import collections
Credential = collections.namedtuple('Credential', 'username, password', verbose=True)

class Credential(tuple):                                     
        'Credential(username, password)'                     

        __slots__ = () 

        _fields = ('username', 'password') 

        def __new__(_cls, username, password):
            return _tuple.__new__(_cls, (username, password)) 

        @classmethod
        def _make(cls, iterable, new=tuple.__new__, len=len):
            'Make a new Credential object from a sequence or iterable'
            result = new(cls, iterable)                               
            if len(result) != 2:                                      
                raise TypeError('Expected 2 arguments, got %d' % len(result))
            return result

        def __repr__(self):
            return 'Credential(username=%r, password=%r)' % self

        def _asdict(t):
            'Return a new dict which maps field names to their values'
            return {'username': t[0], 'password': t[1]}

        def _replace(_self, **kwds):
            'Return a new Credential object replacing specified fields with new values'
            result = _self._make(map(kwds.pop, ('username', 'password'), _self))
            if kwds:
                raise ValueError('Got unexpected field names: %r' % kwds.keys())
            return result

        def __getnewargs__(self):
            return tuple(self)

        username = _property(_itemgetter(0))
        password = _property(_itemgetter(1))
The named tuple doesn't only provide access to fields by name but also contains helper functions such as the _make() function which helps creating an Credential instance from a sequence or iterable. For example:
cred_tuple = ('mario', 'secret')
credential = Credential._make(cred_tuple)
There are more interesting use-cases and examples in the documentation, so I suggest that you take a peek.

Comments
I think the named tuple is useful. They remove the error-prone indexing in tuples by providing access to fields by name without adding any memory overhead. They are also regular Python classes which means you can do anything you can do with classes.

Saturday, January 16, 2010

Calling Python from JavaScript in PyQt's QWebkit

QtWebKit makes it very easy to expose methods and properties implemented in Python to JavaScript. Qt will automatically expose Qt-slots and Qt-properties to a JavaScript when a QObject is made available in the frame's JavaScript context.

I think the code speaks for itself
import sys
from PyQt4 import QtCore, QtGui, QtWebKit

"""Html snippet."""
html = """
<html><body>
  <center>
  <script language="JavaScript">
    document.write('<p>Python ' + pyObj.pyVersion + '</p>')
  </script>
  <button onClick="pyObj.showMessage('Hello from WebKit')">Press me</button>
  </center>
</body></html>
"""

class StupidClass(QtCore.QObject):
    """Simple class with one slot and one read-only property."""

    @QtCore.pyqtSlot(str)
    def showMessage(self, msg):
        """Open a message box and display the specified message."""
        QtGui.QMessageBox.information(None, "Info", msg)

    def _pyVersion(self):
        """Return the Python version."""
        return sys.version

    """Python interpreter version property."""
    pyVersion = QtCore.pyqtProperty(str, fget=_pyVersion)

def main():
    app = QtGui.QApplication(sys.argv)

    myObj = StupidClass()

    webView = QtWebKit.QWebView()
    # Make myObj exposed as JavaScript object named 'pyObj'
    webView.page().mainFrame().addToJavaScriptWindowObject("pyObj", myObj)
    webView.setHtml(html)

    window = QtGui.QMainWindow()
    window.setCentralWidget(webView)
    window.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
Some references:

Thursday, January 14, 2010

New-style PyQt Signals and Slots

I was to lazy to take a look at the new-style signal and slot support which was introduced in PyQt 4.5 until yesterday. I did know that there were something called new-style signals and slots but that was the end of the story. Now I have taken the time and I think it's a cleaner solution than the old-style.

I'll just give you a short intro to whet your appetite, find all details here yourself.
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui

def clicked():
    print "Button Clicked"

qApp = QtGui.QApplication(sys.argv)

button = QtGui.QPushButton("Click Me")
QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), clicked)
button.show()

sys.exit(qApp.exec_())
This is the old way of connecting a signal to a slot. To use the new-style support just replace line 11 with following code
button.clicked.connect(clicked)
The new-style support introduces an attribute with the same name as the signal, in this case clicked.

If you need to define your own signal you'll do something like this (off the top of my head):
class X(QtCore.QObject):
    mySignal = QtCore.pyqtSignal(int)

    def emitMySignal(self):
        self.mySignal.emit(100)
And the old way:
class X(QtCore.QObject):
    def emitMySignal(self):
        self.emit(QtCore.SIGNAL('mySignal'), 100)

IMHO the new-style support is more pythonic and you don't have to specify your signals as strings when connecting. If you use pydev (eclipse) you'll also have completion support for signals.

Tuesday, January 5, 2010

Let's timeit!

Every now and then you might want to time snippets just to make sure that you choose the more efficient solution. In those cases you can use the timeit module to measure execution time for snippets.

Introduction
It's very easy to setup and measure the execution time for a snippet with timeit. The module contains a class, Timer, which is used to perform the measurement. The class has one constructor and three methods:
  • Timer([stmt='pass'[, setup='pass'[, timer=<timer function>]]]) - stmt is the statement to be timed and setup is called once before executing the main statement. A timer function can be specified and default is time.time() for all platforms but windows which is set to time.clock() instead (according to my timeit.py)
  • timeit([number=1000000]) - Executes the main statement passed to the constructor number of times and returns the result in seconds as a float.
  • repeat([repeat=3[, number=1000000]]) - Convenience function that calls timeit(number) repeat times. Returns a list with the results.
  • print_exc([file=None]) - Helper to print a traceback from the timed snippet.
Starting with Python 2.6 the timeit module also defines two convenience functions, timeit.timeit() and timeit.repeat(). They are basically wrappers around the Timer class.

Example
Suppose that I would like to create a list containing 100 'c':s like this ['c', 'c', ...]. There are at least two ways of doing this:
lst = ['c'] * 100
# or
lst = ['c' for i in xrange(100)]
Which one should I choose? Well, let's execute both statements with timeit and measure the execution time.
>>> import timeit
>>> t = timeit.Timer(stmt="lst = ['c'] * 100")
>>> print t.timeit()
1.10580182076
>>> t = timeit.Timer(stmt="lst = ['c' for x in xrange(100)]")
>>> print t.timeit()
7.66900897026
Ok, I think I'll stick with the first snippet :)

The result returned is the total execution time in seconds. In this particular case when we are executing the snippet 1000000 times the result is also the execution time in microseconds for one single pass (1000000*exe_time/1000000 == exe_time).

Normally, the timeit module doesn't have access to things that you have defined in your module. If you would like to measure a function that you have defined in your module you can specify the import statement in the setup parameter:
>>> def create_lst(size):
...    return ['c'] * size
...
>>> t = timeit.Timer(stmt="create_lst(100)", setup="from __main__ import create_lst")
>>> print t.timeit()
1.21339488029
This will introduce a little overhead since the create_lst() function is called in the measurement loop instead of just executing an inlined snippet.

Note: Timer.timeit() will by default disable garbage collection during timing. To enable GC you can pass 'gc.enable()' as a setup statement.

I find the timeit module as a simple and convenient way to measure execution time for small snippets.

Tuesday, December 29, 2009

When ctypes comes to the rescue

I recently purchased a DSLR (Canon 1000D) and almost at the same time I read an article about remote controlling your camera using gphoto. I tried it out and thought it was cool. During the holidays I had some time over to spend on hacking and wanted to try controlling my camera from Python. To my disappointment there were no Python bindings included with Ubuntu for gphoto. I did some googling but couldn't find any pre-compiled bindings, what to do?

Well, I could always try doing it with ctypes.

From the docs:
ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.
Note: I haven't done any serious stuff with ctypes nor gphoto before so if you find any errors etc please post a comment.

It amazed my how easy it is to use ctypes. Here's a snippet that will take a picture (from the first camera found), download the image to local storage and then delete it from the camera's storage.
import ctypes
import os

# gphoto structures
""" From 'gphoto2-camera.h'
typedef struct {
        char name [128];
        char folder [1024];
} CameraFilePath;
"""
class CameraFilePath(ctypes.Structure):
    _fields_ = [('name', (ctypes.c_char * 128)),
                ('folder', (ctypes.c_char * 1024))]

# gphoto constants
# Defined in 'gphoto2-port-result.h'
GP_OK = 0
# CameraCaptureType enum in 'gphoto2-camera.h'
GP_CAPTURE_IMAGE = 0
# CameraFileType enum in 'gphoto2-file.h'
GP_FILE_TYPE_NORMAL = 1

# Load library
gp = ctypes.CDLL('libgphoto2.so.2')

# Init camera
context = gp.gp_context_new()
camera = ctypes.c_void_p()
gp.gp_camera_new(ctypes.pointer(camera))
gp.gp_camera_init(camera, context)

# Capture image
cam_path = CameraFilePath()
gp.gp_camera_capture(camera,
                     GP_CAPTURE_IMAGE,
                     ctypes.pointer(cam_path),
                     context)

# Download and delete
cam_file = ctypes.c_void_p()
fd = os.open('image.jpg', os.O_CREAT | os.O_WRONLY)
gp.gp_file_new_from_fd(ctypes.pointer(cam_file), fd)
gp.gp_camera_file_get(camera,
                      cam_path.folder,
                      cam_path.name,
                      GP_FILE_TYPE_NORMAL,
                      cam_file,
                      context)
gp.gp_camera_file_delete(camera,
                         cam_path.folder,
                         cam_path.name,
                         context)
gp.gp_file_unref(cam_file)

# Release the camera
gp.gp_camera_exit(camera, context)
gp.gp_camera_unref(camera)
Ok, remember that I haven't done any wrapper or anything, it almost looks like 'C' code. I have also skipped all error checking for brevity.

You can always use a c_void_p if you don't need access to the data in Python (if you only need to pass a pointer between foreign functions). I'm using c_void_p instead of defining ctypes structures for gphoto's data types such as Camera and CameraFile. I still had to define CameraFilePath since I needed access to the data in Python.

I really like ctypes because I don't have to maintain code in C to access native functionality. Maybe you won't get the same performance as with traditional bindings but in this particular case it's not an issue.


Tuesday, December 22, 2009

Hello Planet Python!

I just got added to Planet Python and want to give the readers a quick introduction to myself.

My name is Mario and I live in Sweden. I've been working with Java development since 1999, mainly with enterprise systems. In 2007 I switched to embedded development and primary focusing on embedded Linux systems.

Early this year (2009) I got curious about developing KDE/QT applications since I've been using the KDE desktop for years now. I didn't want to use Java nor C++ for desktop development, I needed a language which was simple to use, feature rich and well supported by QT and KDE. There were two candidates for the job, Ruby and Python, guess which one I choosed.

I really like Python and it feels fun coding again, it's my first choice of programming language now.

On my blog you'll find posts about everything regarding Python, language features, APIs, frameworks, etc. I hope you'll enjoy reading.

Tuesday, December 15, 2009

try/for/while else... else what?

The Python language actually has support for else-clauses in some compound statements such as try, for and while.

So how do you use them?

I'll illustrate the for usage with an example:
def has_only_alpha_string(lst):
    for s in lst:
        if not s.isalpha():
            print '[{0}] contains non alphabetic character'.format(s)
            break
    else:
        print 'All strings contains only alphabetic characters'

lst = ['Hello', 'World!']

only_alpha_string(lst)
If lst is empty or exhausted the execution will continue in the else-clause. If the break is executed, the else-clause will not be executed. The same applies to while statements, the else is only executed if no break is executed within the while statement.

Note: It's valid to have a for/while-else without a break. In that case the else-clause will always be executed.

The first time I tried it I got it all wrong (before actually reading the documentation). I expected that the else-clause should be executed only if the list sequence was empty or exhausted, but it's the other way around.

What about try-else?

For me, at least, the try-else is probably a bit more intuitive.
try:
    f = None
    f = open('a_file', 'r')
except IOError as err:
    print err
else:
    print f.read()
finally:
    if f:
        print "Closing file..."
        f.close()
If the open call is successful the else-clause is executed and of course if the open call raises an IOError exception the else-clause isn't executed. Both open and read can raise IOError exceptions, the finally-clause will always be executed even if an exception occurs in the else-clause. In this particular case I'm only interested in catching the exception raised by open. If read raises an exception, it should be forwarded to the caller.

I could also write the code as following:
try:
    f = None
    f = open('a_file', 'r')
except IOError as err:
    print err
    # return or os.exit()

print f.read()
print "Closing file..."
f.close()
The problem with this solution is that file wouldn't be closed if read raises an exception.

Hope this post made the else-clause thing in combination with try/for/while more clear.