Tuesday, March 31, 2009

Reading battery status on an N800/N810

For one of my projects I need to be able to read out the energy levels of the battery on my Nokia Internet Tablet (N810) - and I need to be able to do so from within a Python program, so that I may continuously monitor the energy usage of my program. After reading this blog post and talking to my friend Jussi, who had spent some days implementing such functionality in a C++ program of his, I spent about five minutes porting it to Python (thanks Jussi!). The result is shown below:

import dbus

bus = dbus.SystemBus()
hal_obj = bus.get_object ('org.freedesktop.Hal',
'/org/freedesktop/Hal/Manager')
hal = dbus.Interface (hal_obj, 'org.freedesktop.Hal.Manager')
uids = hal.FindDeviceByCapability('battery')
dev_obj = bus.get_object ('org.freedesktop.Hal', uids[0])

print 'charge level percentage',\
dev_obj.GetProperty('battery.charge_level.percentage')
print 'charge current', dev_obj.GetProperty('battery.reporting.current')
print 'charge design', dev_obj.GetProperty('battery.reporting.design')
print 'charge last full',\
dev_obj.GetProperty('battery.reporting.last_full')
print 'charge unit', dev_obj.GetProperty('battery.reporting.unit')
print 'voltage current', dev_obj.GetProperty('battery.voltage.current')
print 'voltage design', dev_obj.GetProperty('battery.voltage.design')
print 'voltage unit', dev_obj.GetProperty('battery.voltage.unit')

This little snippet of Python code talks to the HAL layer through D-Bus, and in that way is capable of coming up with quite a lot of information about the battery. Check the complete HAL battery API for more information about what can be read through these calls.

Monday, March 30, 2009

Excellent article about securing Python

It seems that there is in fact people out there that are actively trying to create a secure Python; as in a Python that can be used to execute untrusted code within, without endangering your trusted code (or filesystem for that matter).

I was google "securing python" out of interest, to see if something has happened in this respect since the time when I was looking into it when designing my Scavenger system, and it seems that there have been some important progress since then. I found this great article by Tav (Vageesan Sivapathasundaram). It describes how a security system based on object capabilities can be built (and is in fact being built) within the Python interpreter. Some of the ideas are reminiscent of my approach - but what they are doing here is way cooler than what I was playing around with ;-)

By the way they are having a hack-attack, exactly like I did when I was testing Scavenger's security system :-)

Saturday, March 28, 2009

Building Stackless Python on a Mac

I use Stackless Python for some of my work (and also for my open source project Scavenger). Seeing as I do most of my development on a Mac I have a number of times had the need to build Stackless Python from source. Doing that there is one thing that you should know: you need to add the configure option called --enable-stacklessfewerregisters, otherwise you will get the following error when compiling:

./Stackless/platf/switch_ppc_macosx.h:51: error: PIC register 'r31'
clobbered in 'asm'

Wednesday, March 25, 2009

YASnippet LaTeX bundle

I have started using YASnippet for Emacs and one thing that I immediately noticed was the shocking lack of LaTeX snippets. Yes, I know that the auxtex package lets you do everything by using some keyboard shortcuts, but I find it much more intuitive working with tab completed snippets. I have therefore begun a project of creating a proper LaTeX bundle for YASnippet - you may find the snippets I create here [old link!].

Update: The snippets have been moved to a GitHub project - you may find it here http://github.com/madsdk/yasnippets-latex/

It is still a work in progress, but as soon as I find my bundle to be complete enough I will start releasing versioned "builds". As of right now you have to download the snippets individually from the download section of the homepage.

Great article about the Python GIL

I just stumbled upon this article about the Global Interpreter Lock in Python by Jesse Noller.

I was benchmarking my Stackless Python execution environment to see whether it was actually able to utilize my multi-core CPU fully - and it wasn't... In it I spawn a thread per CPU core and thus maintain separate stackless schedulers so that I may schedule multiple tasklets for execution at the same time - or so I thought :-)

The article by Jesse Noller is very nice, and I suggest that anyone interested in using threading in Python to do heavy lifting should read it. If you are using threads solely to get more responsiveness when doing blocking I/O calls there is no need to read it; just continue doing what it is you are doing ;-)

Friday, March 20, 2009

More Python YASnippets

I found that snippets were missing for try- and with-statements as well, so I created some:

# contributor: Mads D. Kristensen
# name: try
# --
try:
$0
except ${1:Exception}, ${2:e}:
pass


# contributor: Mads D. Kristensen
# name: with
# --
with ${1:lock}:
$0

These are very simple snippets but I find them immensely useful and I hope you will too :-)

Python property snippet for YASnippet

I have recently begun using YASnippet for Emacs (AquaMacs on Mac actually). YASnippet adds powerful snippet support to Emacs reminiscent of the snippet support in TextMate. Using YASnippet you may for example in Python mode type "class" and then hit the Tab-key which would expand into a class-definition snippet where all of the boiler-plate code has already been written for you.

While YASnippet is quite powerful is does lack a number of standard snippets (or templates) in its standard library. For example I was missing a proper Python property snippet, so I wrote one:

# contributor: Mads D. Kristensen
# name: prop
# --
def ${1:foo}():
doc = """${2:Doc string}"""
def fget(self):
return self._$1
def fset(self, value):
self._$1 = value
def fdel(self):
del self._$1
return locals()
$1 = property(**$1())

$0

Using this snippet you can write "prop" and press the Tab-key. Now you only need to provide a name for the property and, if you like, a doc string for the property. The snippet then creates a getter, setter, and deleter method for the property.

Thursday, March 19, 2009

New blog

I have decided to move part of my blogging to this blogspot.com site instead of my original blog. My old blog will still hold all my research related blogging, but any tech/development/personal blogging will from now on reside on this blog.

The first thing I will do, when I get the time, is to migrate old (relevant) blog posts from my old blog to this new site.

By the way, I will be writing on this blog in both English and Danish. I have therefore created both an "english" and a "danish" category, and I will try to remember to apply one of these to all posts. This way you may e.g. create an English-only feed if you should so desire.

Friday, March 6, 2009

Comparing and the __cmp__ method in Python

Sometimes it would be nice to be able to ask questions such as “does this array hold an object that has its instance variable ‘foo’ set to 42?” in a simpler way than by iterating through the entire array whilst comparing each objects ‘foo’ attribute to 42. This can be done quite easily in Python by overloading the __cmp__ method in your classes. The following example shows how that works in practice:

class Foo(object):
def __init__(self, a_string, an_integer):
self.my_string = a_string
self.my_integer = an_integer

def __cmp__(self, other):
if type(other) == type(self):
return cmp(self.my_string, other.my_string) and\
cmp(self.my_integer, other.my_integer)
elif type(other) == int:
return cmp(self.my_integer, other)
elif type(other) == str:
return cmp(self.my_string, other)
else:
raise TypeError('Unable to compare %s to %s'%(type(self), type(other)))

f1 = Foo('hello', 1)
f2 = Foo('world', 2)
f3 = Foo('!', 3)
my_list = [f1, f2]
print f1 in my_list # Prints "True"
print f3 in my_list # Prints "False"
print 1 in my_list # Prints "True"
print 42 in my_list # Prints "False"
print 'hello' in my_list # Prints "True"
print 'mojn' in my_list # Prints "False"
try:
(1+0j) in my_list # Raises a TypeError
except TypeError, e:
print e.message