<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Riding python</title>
	<atom:link href="http://pygabriel.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pygabriel.wordpress.com</link>
	<description>Not all snakes are evil</description>
	<lastBuildDate>Mon, 27 Jun 2011 21:05:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='pygabriel.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Riding python</title>
		<link>http://pygabriel.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://pygabriel.wordpress.com/osd.xml" title="Riding python" />
	<atom:link rel='hub' href='http://pygabriel.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Writing pygtk applications with style, using pygtkhelpers</title>
		<link>http://pygabriel.wordpress.com/2010/05/24/writing-pygtk-applications-with-style-using-pygtkhelpers/</link>
		<comments>http://pygabriel.wordpress.com/2010/05/24/writing-pygtk-applications-with-style-using-pygtkhelpers/#comments</comments>
		<pubDate>Mon, 24 May 2010 16:52:02 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[pygtk]]></category>
		<category><![CDATA[pygtkhelpers]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=154</guid>
		<description><![CDATA[Introduction pygtkhelpers is an awesome library for writing pygtk applications, it was developed by pida developers and makes the pygtk programming experience much better, let&#8217;s start with the tutorial. I&#8217;ve used this library for my project, filesnake, I want to explain my workflow. GUIs like template In pygtkhelpers &#8220;glade&#8221; files and hand written GUI blends [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=154&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p><a href="http://packages.python.org/pygtkhelpers/index.html">pygtkhelpers</a> is an awesome library for writing pygtk applications, it was developed by <a href="http://pida.co.uk/pida">pida</a> developers and makes the pygtk programming experience much better, let&#8217;s start with the tutorial.</p>
<p>I&#8217;ve used this library for my project, <a href="http://bitbucket.org/gabriele/filesnake/wiki/Home">filesnake</a>, I want to explain my workflow.</p>
<h3>GUIs like template</h3>
<p>In pygtkhelpers &#8220;glade&#8221; files and hand written GUI blends together in a wonderful manner, in particular each piece of the GUI is separate from the rest and give you a lot of control, flexibility and mantainablity.</p>
<p>I started with glade, writing a &#8220;skeleton gui&#8221;. It&#8217;s a window with a VBox inside (3 slots). I packed in each slot of the VBox a gtk.EventBox (also another gtk.VBox would have been fine for the purpose), these EventBoxes serves as &#8220;placeholders&#8221; for other pieces of the GUI, the menu, the userlist and the status bar.</p>
<p><a href="http://pygabriel.files.wordpress.com/2010/05/filesnake-skeleton.png"><img class="aligncenter size-full wp-image-157" title="filesnake-skeleton" src="http://pygabriel.files.wordpress.com/2010/05/filesnake-skeleton.png?w=248&#038;h=271" alt="" width="248" height="271" /></a></p>
<p>I&#8217;ve written the very little code to make the GUI run:</p>
<pre class="brush: python;">
class FileSnakeGUI(WindowView):
    builder_file = &quot;main_win.glade&quot;

def test_run():
    fs = FileSnakeGUI()
    fs.show_and_run()

if __name__ == '__main__':
    test_run()
</pre>
<p>It&#8217;s time to write the three components:</p>
<ul>
<li>menu</li>
<li>userlist</li>
<li>statusbar</li>
</ul>
<h4>The Menu</h4>
<p>I&#8217;ve written another glade file that contains  a window with the menu inside, the library will handle the extraction of the menu from the &#8220;container&#8221; window for you.</p>
<p>To connect the events I&#8217;ve used the signal handling facilities provided by pygtkhelpers.</p>
<p>The connection is made automatically with the naming convention on_widget__signal,  this simple convention let us to eliminate the boilerplate code related to the &#8220;connect&#8221; methods.</p>
<pre class="brush: python;">
from pygtkhelpers.delegates import SlaveView

class Menu(SlaveView):

    builder_file = &quot;menu.glade&quot;

    def __init__(self, parent):
        SlaveView.__init__(self)
        self.parent = parent

    def on_quit__activate(self,*a):
        self.parent.hide_and_quit()

    def on_sendfile__activate(self, *a):
        self.parent.send_file()
</pre>
<h3>Handwritten GUIs</h3>
<p>I&#8217;ve written the statusbar and the userlist by hand, The code can be as complex as you want, demostrating the flexibility and &#8220;invisibility&#8221; of the framework, all the code is well packed and organized on its own place.</p>
<p>When subclassing a generic Slave/WindowView (subclasses of BaseDelegate) you can override this methods to customize the behaviour of the class  :</p>
<ul>
<li>create_ui: in this method you can manually write your GUI, usually you put there all the &#8220;add_slave&#8221; code</li>
<li> on_mywidget__event: these are the signal handlers, facilities that let<br />
you write cleaner code without all the self.connect stuff</li>
<li>__init__: you can pass custom initializer, and various control<br />
code not related to the gui code (nothing stops you to do that in<br />
the create_ui, it&#8217;s just to add a bit of conventions)</li>
</ul>
<p>Here&#8217;s the UserList code, you can add additional methods to simplify<br />
external access, like add_user(). This &#8220;additional method&#8221; would be<br />
used i.e. in the main controller (FileSnakeGUI). It&#8217;s a component, and it&#8217;s reusable.</p>
<pre class="brush: python;">
# Defining a user container
User = namedtuple(&quot;User&quot;, &quot;name icon address port&quot;)

# UserList section
class UserList(SlaveView):

    def create_ui(self):
        model = gtk.ListStore(object)
        treeview = gtk.TreeView(model)
        treeview.set_name(&quot;User List&quot;)

        iconrend = gtk.CellRendererPixbuf()
        inforend = gtk.CellRendererText()

        iconcol = gtk.TreeViewColumn('Icon', iconrend)
        infocol = gtk.TreeViewColumn('Info', inforend)

        iconcol.set_cell_data_func(iconrend, self._icon_data)
        infocol.set_cell_data_func(inforend, self._info_data)

        treeview.append_column(iconcol)
        treeview.append_column(infocol)
        treeview.set_headers_visible(False)

        self.store = model
        self.treeview = treeview
        self.widget.add(treeview)

    def _icon_data(self, column, cell, model, iter):

        row = model[iter]
        user = row[0]
        cell.set_property(&quot;pixbuf&quot;,gtk.gdk.pixbuf_new_from_file(user.icon))

    def _info_data(self, column, cell, model, iter):

        row = model[iter]
        user = row[0]

        template = &quot;&lt;big&gt;&lt;b&gt;{user}&lt;/b&gt;&lt;/big&gt;\n&lt;small&gt;&lt;i&gt;{address}:{port}&lt;/i&gt;&lt;/small&gt;&quot;
        label = template.format(user=user.name,
                                address=user.address,
                                port=user.port)
        cell.set_property(&quot;markup&quot;,label)

    def add_user(self, user):

        self.store.append([user])
</pre>
<p>The statusbar doesn&#8217;t introduce anything new. You can find the source following the link at the end of the article.</p>
<p>To pack together the gui, we&#8217;ll use the add_slave method, it adds to a container widget (the EventBoxes we placed)  the widget defined in the slave view, the resulting code is that:</p>
<pre class="brush: python;">
class FileSnakeGUI(WindowView):

    builder_file = &quot;main_win.glade&quot;

    def create_ui(self):
        self.userlist = UserList()

        self.add_slave(&quot;statusbar_cont&quot;, Statusbar())
        self.add_slave(&quot;menu_cont&quot;, Menu(self))
        self.add_slave(&quot;userlist_cont&quot;, self.userlist)

    def on_window1__delete_event(self, *a):
        self.hide_and_quit()
</pre>
<h3>pygtk signals facilities, now you haven&#8217;t any excuse</h3>
<p>It&#8217;s trivial to add your own signals to a BaseDelegate instance, let&#8217;s see<br />
how to add a &#8220;user-added&#8221; signal to my UserList:</p>
<pre class="brush: python;">
from pygtkhelpers.utils import gsignal

class UserList(SlaveView):

   gsignal(&quot;user-added&quot;,object)

   #   ... source code defined before...
   def add_user(self, user):
      self.emit(&quot;user-added&quot;, user)
      self.store.append([user])
</pre>
<p>It&#8217;s just one line of code and you can connect it like a gtk widget,<br />
implementing in the easiest way I&#8217;ve seen the observer pattern. It&#8217;s<br />
cool!</p>
<h2>Refactoring the UserList with pygtkhelpers.ui.objectlist.ObjectList widget</h2>
<p>One of the most useful feature of pygtkhelpers are ObjectList and ObjectTree, pythonic versions of the common gtk list/tree widgets. They automate the tedious task of setting up treeview widgets using a very powerful (yet customizable) manner.</p>
<p>In a few words, given an object, his attributes can be mapped to the treeview through Columns that almost automatically select the correct renderer for the data to be displayed, like in the following scheme:</p>
<p><a href="http://pygabriel.files.wordpress.com/2010/05/objectlist.png"><a href="http://pygabriel.files.wordpress.com/2010/05/objectlist1.png"><img class="aligncenter size-full wp-image-171" title="objectlist" src="http://pygabriel.files.wordpress.com/2010/05/objectlist1.png?w=502&#038;h=261" alt="" width="502" height="261" /></a></a></p>
<p>The resulting code, is much cleaner and readable:</p>
<pre class="brush: python;">
from pygtkhelpers.ui.objectlist import Column,ObjectList
from pygtkhelpers.delegates import SlaveView
import gtk

from collections import namedtuple
# This is the &quot;user object&quot;
User = namedtuple(&quot;User&quot;, &quot;name address port icon&quot;)

class UserList(SlaveView):

   def create_ui(self):
      # Columns are intended to map UserEntry object, with this signature: Column(&quot;attribute&quot;, type)
      self.users = ObjectList(columns = [Column(&quot;icon&quot;,gtk.gdk.Pixbuf),
                                         Column(&quot;info&quot;,str, use_markup=True)])

      self.users.set_headers_visible(False)
      self.widget.add(self.users)

   def add_user(self, user):
      self.users.append(UserEntry(user))

# The UserEntry is mapped by the treeview with the attributes info and icon
class UserEntry(object):

    def __init__(self, user):
        template = &quot;&lt;big&gt;&lt;b&gt;{user}&lt;/b&gt;&lt;/big&gt;\n&lt;small&gt;&lt;i&gt;{address}:{port}&lt;/i&gt;&lt;/small&gt;&quot;
        self.info = template.format(user=user.name,
                                    address=user.address,
                                    port=user.port)
        self.icon = gtk.gdk.pixbuf_new_from_file(user.icon)
</pre>
<p>There are also other interesting features that really boost the pygk GUI programming expecially regarding ObjectList, but also with the pygtkhelpers.ui.dialogs module: well cooked dialogs for common uses.</p>
<p>You can find the full sourcecode at the blog repo:</p>
<p><a href="http://bitbucket.org/gabriele/pygabriel-blogging/src/tip/pygtkhelpers/source/" target="_blank">http://bitbucket.org/gabriele/pygabriel-blogging/src/tip/pygtkhelpers/source/</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=154&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2010/05/24/writing-pygtk-applications-with-style-using-pygtkhelpers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>

		<media:content url="http://pygabriel.files.wordpress.com/2010/05/filesnake-skeleton.png" medium="image">
			<media:title type="html">filesnake-skeleton</media:title>
		</media:content>

		<media:content url="http://pygabriel.files.wordpress.com/2010/05/objectlist1.png" medium="image">
			<media:title type="html">objectlist</media:title>
		</media:content>
	</item>
		<item>
		<title>Profiling python C extensions</title>
		<link>http://pygabriel.wordpress.com/2010/04/14/profiling-python-c-extensions/</link>
		<comments>http://pygabriel.wordpress.com/2010/04/14/profiling-python-c-extensions/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 04:05:25 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=123</guid>
		<description><![CDATA[In last days I was optimizing some code I&#8217;ve written for PyQuante http://pyquante.sourceforge.net/. I had to do a lot of searches to find my way in profiling C extensions from python. I&#8217;ll also digress on various tools I&#8217;ve used in this case, feel free to skip on &#8220;The Solution&#8221; section. It&#8217;s all tested on Linux [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=123&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In last days I was optimizing some code I&#8217;ve written for PyQuante<br />
http://pyquante.sourceforge.net/. I had to do a lot of searches to find<br />
my way in profiling C extensions from python.</p>
<p>I&#8217;ll also digress on various tools I&#8217;ve used in this case, feel free to<br />
skip on &#8220;The Solution&#8221; section.</p>
<p>It&#8217;s all tested on Linux platforms, if you need help for other platforms<br />
I can see what I can do.</p>
<h1>The Test Case</h1>
<p>Let&#8217;s see a typical example, imagine that you have some data (numbers)<br />
you want to calculate something about that.</p>
<p>You have this data from some sources or generated by python control<br />
code, in this example we&#8217;ll use xml, but there are a lot of use cases.</p>
<p>Let&#8217;s see a snippet, this code can block your computer also for a small<br />
set of data (like 100 numbers)</p>
<pre class="brush: python;">
#!/usr/bin/python
# -*- coding: utf-8 -*-
import math
import xml.etree.ElementTree as ET

def parse_numbers(xmlfile):
    '''
    Parses numeric data from a dummy xmlfile
    '''

    tree = ET.parse('data.xml')
    root = tree.getroot()
    numbers = []

    for element in root:
        numbers.append(float(entry.text))
    return numbers

def stddev(numbers):
    res = 0
    for n in numbers:
        res += math.pow(n, 2)
    return math.sqrt(res)

import operator

def heavycrunch(numbers):
    res = 0
    for n1 in numbers:
        for n2 in numbers:
            for n3 in numbers:
                for n4 in numbers:
                    tocalc = (n1, n2, n3, n4)
                    res += stddev(tocalc)
    return res / len(numbers) ** 4

if __name__ == '__main__':
    numbers = parse_numbers('data.xml')
    result = heavycrunch(numbers)
</pre>
<p><strong>First point:</strong> Profile and optimize it in python, it&#8217;s<br />
not uncommon that you can reach enough speed in pure python, leaving it<br />
in python has a lot of advantages like ease of deploying and ease of<br />
testing. There is the cProfile profiler that&#8217;s pretty good.</p>
<p>This command lets me profile the code and sorts the results by time<br />
spent in the functions (excluded subfunctions):</p>
<pre>python -m cProfile -s time example.py

         77765214 function calls (77765107 primitive calls) in 173.175 CPU seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 12960000   89.673    0.000  156.182    0.000 example.py:33(stddev)
 51840000   53.832    0.000   53.832    0.000 {math.pow}
        1   16.961   16.961  173.143  173.143 example.py:39(heavycrunch)
 12960001   12.677    0.000   12.677    0.000 {math.sqrt}
        1    0.007    0.007    0.008    0.008 sre_compile.py:307(_optimize_unicode)
       61    0.003    0.000    0.004    0.000 ElementTree.py:1075(start)
        1    0.002    0.002  173.174  173.174 example.py:5()
        2    0.002    0.001    0.002    0.001 {range}
...........................................................</pre>
<ul>
<li>ncalls: number of calls</li>
<li>tottime: total time spent in this function, excluding the time spent in<br />
subfunctions. (this is the most important)</li>
</ul>
<p>This output tells me that 89 secs are spent in the inner cycle in stddev<br />
and maybe in the call overhead, 53 secs are spent in computing the<br />
powers and 16 seconds in the heavycrunch cycle.</p>
<p>This is well optimizable just in python, there are a lot of suggestions<br />
that comes in mind..</p>
<ul>
<li>Inlining the cycle inside of stddev</li>
<li>Substituting x*x instead of pow(x,2)</li>
<li>Using sum(map(operator.mul, numbers,numbers)) instead of all of this<br />
cycles.</li>
</ul>
<p>Let&#8217;s see what&#8217;s happening editing the interested lines:</p>
<pre class="brush: python;">
import operator

def heavycrunch(numbers):
    res = 0
    for n1 in numbers:
        for n2 in numbers:
            for n3 in numbers:
                for n4 in numbers:
                    res += sum(map(operator.pow, tocalc, tocalc))**0.5
    return res / (len(numbers)**4)
</pre>
<p>The profiling output:</p>
<pre>         25925214 function calls (25925107 primitive calls) in 79.984 CPU seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1   34.535   34.535   79.951   79.951 example.py:43(heavycrunch)
 12960000   29.576    0.000   29.576    0.000 {map}
 12960000   15.840    0.000   15.840    0.000 {sum}
        1    0.008    0.008    0.009    0.009 sre_compile.py:307(_optimize_unicode)
       61    0.003    0.000    0.004    0.000 ElementTree.py:1075(start)
        2    0.002    0.001    0.002    0.001 {range}</pre>
<p>We have mostly doubled the speed, but we can&#8217;t do much more than that.</p>
<p>Anyway, the profiling in python is not the main purpose of this article <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<h2>Writing the function and the wrapper in C</h2>
<p>Let&#8217;s implement the interesting functions in C, headers in example.h and<br />
sources in example.c</p>
<p>Nothing much to say, they&#8217;re just pure C functions.</p>
<pre class="brush: cpp;">
/* example.h */

double stddev(double *numbers, int len);
double heavycrunch(double *numbers, int len);

/* example.c */

#include &lt;math.h&gt;

double stddev(double *numbers, int len)
{
  double res =0;
  int i;
  for (i=0; i&amp;lt;len; i++)
    {
      res += pow(numbers[i],2);
    }
  return res;
}

double heavycrunch(double *numbers, int len)
{
  double res;
  double topass[4];
  int i,j,k,l;

  for (i=0; i&amp;lt;len; i++)
    {
      for (j = 0; j &amp;lt;len; j++)
        {
          for (k = 0; k&amp;lt;len; k++)
            {
              for (l=0; l&amp;lt;len; l++)
                {
                  topass[0] = numbers[i];
                  topass[1] = numbers[j];
                  topass[2] = numbers[k];
                  topass[3] = numbers[l];

                  res+=stddev(topass,4);
                }
            }
        }
    }
  return sqrt(res)/pow(len,4);
}
</pre>
<p>Now we have to implement the wrappers, we will just wrap heavycrunch<br />
because we don&#8217;t use stddev externally.</p>
<p>I used cython to wrap the extensions and I suggest you to do so, it<br />
makes the process of wrapping C stuff straightforward and fun <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<pre class="brush: python;">
# example_wrap.pyx
from stdlib cimport * # We need to allocate a double *

cdef extern from &amp;quot;example.h&amp;quot;:
    double cheavycrunch &amp;quot;heavycrunch&amp;quot; (double *numbers, int len)

def heavycrunch(numbers):
    cdef double *numarray

    numarray = &amp;lt;double *&amp;gt; malloc(sizeof(double)*len(numbers))
    for i,num in enumerate(numbers):
        numarray[i] = num

    res = cheavycrunch(numarray,len(numbers))
    free(numarray)
    return res
</pre>
<p>OK, sorry for the code spamming, you will find all at the end of the<br />
article so you can run a working example.</p>
<p>Let&#8217;s compile and run, I used scons to do that, however you can use the<br />
following commands (well, scons generated this for me).</p>
<pre>gcc -o example.os -c -fPIC -I/usr/include/python2.6 example.c
cython -o example_wrap.c example_wrap.pyx
gcc -o example_wrap.os -c -fPIC -I/usr/include/python2.6 example_wrap.c
gcc -o example_wrap.so -shared example_wrap.os example.os -lpython2.6</pre>
<p>We&#8217;ve finished with all this stuff, let&#8217;s test how much speed we&#8217;ve<br />
gained.</p>
<pre class="brush: python;">
from example_wrap import heavycrunch

if __name__ == '__main__':
    numbers = parse_numbers('data.xml')
    result = heavycrunch(numbers)
</pre>
<p>         5213 function calls (5106 primitive calls) in 0.402 CPU seconds</p>
<p>   Ordered by: internal time</p>
<p>   ncalls  tottime  percall  cumtime  percall filename:lineno(function)<br />
        1    0.369    0.369    0.369    0.369 {example_wrap.heavycrunch}<br />
        1    0.007    0.007    0.008    0.008 sre_compile.py:307(_optimize_unicode)<br />
       61    0.004    0.000    0.005    0.000 ElementTree.py:1075(start)<br />
        2    0.002    0.001    0.002    0.001 {range}</pre>
<p>Nice! But now starts the real purpose of the article. How to know<br />
profiling information *inside* of heavycrunch?</p>
<p>If you pass a big xml file with ~100 numbers we have still problem in C<br />
and you may want to profile and optimize it.</p>
<h1>gprof - Plain old way</h1>
<p>You can try to profile the functions independently from the python<br />
code. You can write a main.c file and implement some tests, this implies<br />
feed the data inside the function so you will need to use a C xmlparser.</p>
<p>After that you can profile your code with various C tools (like gprof).</p>
<p>This is a big work, "scripting" in C is somewhat difficult and you can<br />
lost a lot of time.</p>
<p>There should be another way to accomplish that, but I couldn't find how<br />
to do it. It consists compiling the whole python with the profiling<br />
flags, this can work as well but it's a bit overwhelming.</p>
<h1>The Solution - google-perftools</h1>
<p>There's a really nice library over there, google-perftools</p>
<p>http://code.google.com/p/google-perftools/</p>
<p>This library is not invasive, you can profile without particular needs<br />
and you can run the code under each condition. Nice!</p>
<p>The library works in this way:</p>
<pre>StartProfiler("logfile.log")
... code to profile ...
StopProfiler()</pre>
<p>And it dumps in logfile.log information about the code inside.</p>
<p>Question: But if we call this 2 functions *from python*?<br />
Answer: We can have profile information on what's happening inside this<br />
2 calls!</p>
<p>So, basically we have to install this library and wrap this 2 functions,<br />
it's quite easy with cython.</p>
<pre class="brush: python;">
# prof.pyx
cdef extern from &quot;google/profiler.h&quot;:
    void ProfilerStart( char* fname )
    void ProfilerStop()

def profiler_start(fname):
    ProfilerStart(&lt;char *&gt;fname)

def profiler_stop():
    ProfilerStop()
</pre>
<p>Compiling is something like that:</p>
<pre>cython -o prof.c prof.pyx
gcc -o prof.so -shared prof.c -fPIC -lpython2.6 -lprofiler -I/usr/include/python2.6</pre>
<p>Now that we have our profiling extension we can profile and analyze the<br />
output:</p>
<pre class="brush: python;">
from example_wrap import heavycrunch
from prof import profiler_start,profiler_stop
if __name__ == '__main__':
    numbers = parse_numbers('data.xml')
    profiler_start(&quot;heavycrunch.log&quot;)
    result = heavycrunch(numbers)
    profiler_stop()
</pre>
<p>OK, we have produced our profiling data, we can analyze in a lot of ways</p>
<p>http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html</p>
<p>Personally I like the graphical interface of kcachegrind.</p>
<pre>pprof --callgrind example_wrap.so heavycrunch.log &gt; heavycrunch.callgrind
kcachegrind heavycrunch.callgrind</pre>
<p>The graphical interface is quite intuitive, however look at the<br />
picture.</p>
<p><a href="http://pygabriel.files.wordpress.com/2010/04/kcache.png"><img class="aligncenter size-full wp-image-148" title="kcache" src="http://pygabriel.files.wordpress.com/2010/04/kcache.png?w=600&#038;h=375" alt="Kcachegrind example" width="600" height="375" /></a></p>
<p>There is a "Flat Profile" on the left, with fields:</p>
<ul>
<li>incl: the "time" (well it's more like a rate) spent in this<br />
function, subcalls included</li>
<li>self: "time" spent in the function, subcalls excluded, this is the<br />
most important field.</li>
<li>The other two are trivial</li>
</ul>
<p>There's a nice feature that gives you a graphical representation of all<br />
this stuff, on the right go on "Callee Map". This shows you graphically<br />
and interactively how the time is distributed between callers.</p>
<p>In our case is evident that we have to optimize stddev, (you guessed it<br />
yet) anyway we can cut this 75% off. But this is left as exercise.</p>
<p>If some reader has some questions or has suggestion for improve the<br />
article, I would be happy to answer quickly! Bye!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/123/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=123&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2010/04/14/profiling-python-c-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>

		<media:content url="http://pygabriel.files.wordpress.com/2010/04/kcache.png" medium="image">
			<media:title type="html">kcache</media:title>
		</media:content>
	</item>
		<item>
		<title>Emacs coding and &#8230; blogging</title>
		<link>http://pygabriel.wordpress.com/2010/03/29/emacs-coding-and-blogging/</link>
		<comments>http://pygabriel.wordpress.com/2010/03/29/emacs-coding-and-blogging/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 11:48:33 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=119</guid>
		<description><![CDATA[After sometime of intensive hacking here I am. I&#8217;ve just found some comments on another post so I&#8217;ve decided to write some thoughts&#8230; Well this is just a little test to write an entry on the blog directly in emacs using &#8220;weblogger-mode&#8221;. I guess that now I&#8217;ve to write a little tutorial about that. I&#8217;m [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=119&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After sometime of intensive hacking here I am. I&#8217;ve just found some<br />
comments on another post so I&#8217;ve decided to write some thoughts&#8230;</p>
<p>Well this is just a little test to write an entry on the blog directly<br />
in emacs using &#8220;weblogger-mode&#8221;. I guess that now I&#8217;ve to write a little<br />
tutorial about that.</p>
<p>I&#8217;m using also emacs as my development environment and it&#8217;s quite good<br />
at it, I&#8217;m packing toghether a lot of useful well-tested extensions in a<br />
bundle that I ship on my machine. Maybe this can be useful to other<br />
python developers!</p>
<p>See you for updates, Bye!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/119/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=119&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2010/03/29/emacs-coding-and-blogging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>Invites for Google Wave</title>
		<link>http://pygabriel.wordpress.com/2009/11/15/invites-for-google-wave/</link>
		<comments>http://pygabriel.wordpress.com/2009/11/15/invites-for-google-wave/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 15:17:00 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=114</guid>
		<description><![CDATA[If someone wants to be invited on google wave, I&#8217;ve 9 invites remaining, tell me if you need one!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=114&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If someone wants to be invited on google wave, I&#8217;ve 9 invites remaining, tell me if you need one!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/114/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=114&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/11/15/invites-for-google-wave/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>pygtkscintilla &#8211; version 0.1 released</title>
		<link>http://pygabriel.wordpress.com/2009/09/15/pygtkscintilla-version-0-1-released/</link>
		<comments>http://pygabriel.wordpress.com/2009/09/15/pygtkscintilla-version-0-1-released/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 14:12:16 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=109</guid>
		<description><![CDATA[pygtkscintilla is a python wrapper for Scintilla, it gives to pygtk a powerful source-editing widget with features such as: * Syntax highlighting for tons of languages * Autocompletion * Code Folding * Calltips * Annotations * Markers * Multiple selections (NEW!) It provides a nice pythonic API that looks and works better. Documentation: http://pygtksci.sourceforge.net/ Sourceforge [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=109&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>pygtkscintilla is a python wrapper for Scintilla, it gives to pygtk a powerful source-editing widget with features such as:</p>
<div>
<div>* Syntax highlighting for tons of languages</div>
<div>* Autocompletion</div>
<div>* Code Folding</div>
<div>* Calltips</div>
<div>* Annotations</div>
<div>* Markers</div>
<div>* <strong>Multiple selections</strong> (NEW!)</div>
<div>It provides a nice pythonic API that looks and works better.</div>
<div>Documentation:<br />
<a href="http://pygtksci.sourceforge.net/" target="_blank">http://pygtksci.sourceforge.net/</a></div>
<div>Sourceforge Page:</div>
<div><a href="https://sourceforge.net/projects/pygtksci/" target="_blank">https://sourceforge.net/projects/pygtksci/</a></div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/109/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=109&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/09/15/pygtkscintilla-version-0-1-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>pygtkscintilla, some documentation written</title>
		<link>http://pygabriel.wordpress.com/2009/09/02/pygtkscintilla-some-documentation-written/</link>
		<comments>http://pygabriel.wordpress.com/2009/09/02/pygtkscintilla-some-documentation-written/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 16:04:38 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[pygtkscintilla]]></category>
		<category><![CDATA[pygtk]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/2009/09/02/pygtkscintilla-some-documentation-written/</guid>
		<description><![CDATA[I&#8217;ve written some documentation about pygtkscintilla project (svn version) The sourceforge page: http://sourceforge.net/projects/pygtksci/ The documentation: http://pygtksci.sourceforge.net The wiki for bugs, status, other info: https://sourceforge.net/apps/trac/pygtksci/wiki<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=98&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written some documentation about pygtkscintilla project (svn version)<br />
The sourceforge page:<br />
<a href="http://sourceforge.net/projects/pygtksci/">http://sourceforge.net/projects/pygtksci/</a></p>
<p>The documentation:<br />
<a href="http://pygtksci.sourceforge.net">http://pygtksci.sourceforge.net</a></p>
<p>The wiki for bugs, status, other info:<br />
<a href="https://sourceforge.net/apps/trac/pygtksci/wiki">https://sourceforge.net/apps/trac/pygtksci/wiki</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/98/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=98&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/09/02/pygtkscintilla-some-documentation-written/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>pygtkscintilla preliminary version released 0.0.1</title>
		<link>http://pygabriel.wordpress.com/2009/08/10/scintilla-preliminary-version-released-0-0-1/</link>
		<comments>http://pygabriel.wordpress.com/2009/08/10/scintilla-preliminary-version-released-0-0-1/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 21:47:12 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[pygtkscintilla]]></category>
		<category><![CDATA[pygtk]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[wrapping]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=93</guid>
		<description><![CDATA[I&#8217;ve packaged in a rough manner the gtkscintilla module, follow the instruction in the trac wiki, if you have problem or want to tell me something, leave a comment!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=93&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve packaged in a rough manner the gtkscintilla module,<br />
follow the instruction in the <a href="https://sourceforge.net/apps/trac/pygtksci/wiki" target="_blank">trac wiki</a>, if you have problem or want to tell me something, leave a comment!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/93/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=93&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/08/10/scintilla-preliminary-version-released-0-0-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>Wrapping GObject for pygtk &#8211; a real world example</title>
		<link>http://pygabriel.wordpress.com/2009/08/01/wrapping-gobject-for-pygtk-a-real-world-example/</link>
		<comments>http://pygabriel.wordpress.com/2009/08/01/wrapping-gobject-for-pygtk-a-real-world-example/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 16:52:09 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[pygtk]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wrapping]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=83</guid>
		<description><![CDATA[How I wrapped scintilla In this article I will tell you my journey wrapping pygtkscintilla, I think this could be useful to tell other people which mistakes I made and how I&#8217;ve solved them. Know your enemy To solve a problem you have to gather all possible information relate to this problem. Scintilla has a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=83&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>How I wrapped scintilla</h2>
<p>In this article I will tell you my journey wrapping pygtkscintilla, I think this could be useful to tell other people which mistakes I made and how I&#8217;ve solved them.</p>
<h3>Know your enemy</h3>
<p>To solve a problem you have to gather all possible information relate to this problem. Scintilla has a scary interface that have nothing to do with a well-formatted gtk-widget.</p>
<p>The interface is a very important thing. If you wanto to wrap scintilla you have to learn the basics of its usage.  Fortunately there was bait, an example  to test scintilla, it&#8217;s cast gold.</p>
<p>Here&#8217;s the code:</p>
<pre class="brush: cpp;">
/* bait.c */
#include &lt;gtk/gtk.h&gt;

#include &lt;Scintilla.h&gt;
#include &lt;SciLexer.h&gt;
#define PLAT_GTK 1
#include &lt;ScintillaWidget.h&gt;

static int exit_app(GtkWidget*w, GdkEventAny*e, gpointer p) {
 gtk_main_quit();
 return w||e||p||1;    // Avoid warnings
}

int main(int argc, char **argv) {
 GtkWidget *app;
 GtkWidget *editor;
 ScintillaObject *sci;

 gtk_init(&amp;argc, &amp;argv);
 app = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 editor = scintilla_new();
 sci = SCINTILLA(editor);

 gtk_container_add(GTK_CONTAINER(app), editor);
 gtk_signal_connect(GTK_OBJECT(app), &quot;delete_event&quot;,
 GTK_SIGNAL_FUNC(exit_app), 0);

 scintilla_set_id(sci, 0);
 gtk_widget_set_usize(editor, 500, 300);

#define SSM(m, w, l) scintilla_send_message(sci, m, w, l)

 SSM(SCI_STYLECLEARALL, 0, 0);
</pre>
<p>And this is the Makefile associated:</p>
<pre class="brush: bash;">
##### Makefile #####
# Make file for bait on Linux or compatible OS
# Released to the public domain 2000 by Neil Hodgson neilh@scintilla.org
# This makefile tested with GCC 3.2 and GNOME 2.0

.SUFFIXES: .c .o .h .a

INCLUDEDIRS=-I../scintilla/include
CXXFLAGS= -DGTK -DSCI_LEXER -W -Wall -fPIC
LEXEROBJS=$(wildcard ../scintilla/gtk/Lex*.o)

all: bait

.c.o:
 gcc `pkg-config --cflags gtk+-2.0` $(INCLUDEDIRS) $(CXXFLAGS) -c $&lt; -o $@
bait: bait.o $(LEXEROBJS) ../scintilla/bin/scintilla.a
 gcc `pkg-config --libs gtk+-2.0 gthread-2.0` -lstdc++ -DGTK $^ -o $@
clean:
 rm -rf bait *.o
</pre>
<p>I noticed:</p>
<ol>
<li>How to initialize a scintilla editor</li>
<li>How to interact with it. It uses just the SSM macro:  scintilla_send_message function.</li>
<li>With the Makefile associated, how to compile and run it.</li>
</ol>
<p>Once I&#8217;ve done this,  I needed a good interface to respond codegen (utility used to wrap gtk widgets, explained in the <a href="http://pygabriel.wordpress.com/2009/07/22/wrapping-gobjects-for-pygtk/" target="_blank">wrapping tutorial</a>).</p>
<h3>It&#8217;s time to start wrapping</h3>
<p>There was 2 possibilities:</p>
<ol>
<li>Write myself the widget in C.</li>
<li>Search the web for someone that have already done this.</li>
</ol>
<p>I&#8217;m really lazy, I searched a lot on the web and I&#8217;ve found some alternatives:</p>
<ul>
<li>The geany editor: there was some files that wrapped the scintilla interface in a more convenient manner, however it wasn&#8217;t well-formatted because they don&#8217;t use intensively the C/GObject system.</li>
<li>The anjuta editor:  They use a well formatted editor widget that wraps scintilla but there were interdependencies related to anjuta.</li>
<li>The most natural GtkScintilla: someone have done this work long time ago, after some days I noticed that it was a very good starting point.</li>
</ul>
<p>note: I discovered all this things browsing in the project files, reading headers and source files ( I felt like a true hacker).</p>
<p>I haven&#8217;t modified the gtkscintilla.h header and I generated definition files. Next I wrote a simple override file and the initialization module (if you don&#8217;t understand this first read the <a href="http://pygabriel.wordpress.com/2009/07/22/wrapping-gobjects-for-pygtk/" target="_blank">wrapping tutorial</a>).</p>
<p>With no problem I generated the wrapper, cool! (pygtk team have done a great work with codegen, I&#8217;m sad they didn&#8217;t write any documentation)</p>
<p>Now comes the hard part&#8230;</p>
<h3>Compiling</h3>
<p>Welcome in the hell. Scintilla is distribuited as a static library, scintilla.a but the python module I needed was a shared library. I browsed in a sea of pain, errors, errors and errors, my module wouldn&#8217;t compile.</p>
<p>The problem is that you can&#8217;t link a static library to a shared library, the compiler tell you that you have to recompile your files with the -fPIC option. I ignored what the compiler told me, and I tried a lot of  dirty ways to make it work, without success&#8230;</p>
<p>After about 4 days of depression I was sorry with the wisdom of gcc compiler and I was gone in the scintilla/gtk directory to modify the makefile that compiles the scintilla stuff.</p>
<p>In the original makefile there was the compilation command without the -fPIC option and the command &#8220;ar&#8221; to make a static library.</p>
<p>The compilation commands:</p>
<pre class="brush: bash;">
.cxx.o:
 $(CC) $(CONFIGFLAGS) $(CXXFLAGS) -c $&lt;
.c.o:
 $(CCOMP) $(CONFIGFLAGS) $(CXXFLAGS) -w -c $&lt;
</pre>
<p>Becomes:</p>
<pre class="brush: bash;">
 .cxx.o:
 $(CC) $(CONFIGFLAGS) $(CXXFLAGS) -fPIC -c $&lt;
 .c.o:
 $(CCOMP) $(CONFIGFLAGS) $(CXXFLAGS) -fPIC -w -c $&lt;
</pre>
<p>And I modified the creation of the library from static (compressed with ar) to shared (compiled with gcc -shared)</p>
<p>Before:</p>
<pre class="brush: bash;">
COMPLIB= ../bin/scintilla.a
AR= ar
// other things //

$(COMPLIB): DocumentAccessor.o WindowAccessor.o KeyWords.o StyleContext.o \
 CharClassify.o Decoration.o Document.o PerLine.o CallTip.o \
 ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSet.o PlatGTK.o \
 KeyMap.o LineMarker.o PositionCache.o ScintillaGTK.o CellBuffer.o ViewStyle.o \
 RESearch.o RunStyles.o Style.o Indicator.o AutoComplete.o UniConversion.o XPM.o \
 $(MARSHALLER) $(LEXOBJS)
 $(AR) rc $@ $^
</pre>
<p>After:</p>
<pre class="brush: bash;">
COMPLIB= ../bin/scintilla.so # MODIFIED
AR= ar
// other things //

$(COMPLIB): DocumentAccessor.o WindowAccessor.o KeyWords.o StyleContext.o \
 CharClassify.o Decoration.o Document.o PerLine.o CallTip.o \
 ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSet.o PlatGTK.o \
 KeyMap.o LineMarker.o PositionCache.o ScintillaGTK.o CellBuffer.o ViewStyle.o \
 RESearch.o RunStyles.o Style.o Indicator.o AutoComplete.o UniConversion.o XPM.o \
 $(MARSHALLER) $(LEXOBJS)
 gcc -shared -o $@ $^ # MODIFIED
</pre>
<p>After recompiling scintilla I obtained my shared library scintilla.so !!! After this I clearly compiled and linked (reference the <a href="http://pygabriel.wordpress.com/2009/07/31/wrapping-pygtk-widgets-what-you-should-know/">basics tutorial</a>) my python module and run it without (too much) problems!</p>
<p>I post the pygtkscintilla makefile that compiled and linked the python module:</p>
<pre class="brush: bash;">
DEFS=`pkg-config --variable=defsdir pygtk-2.0`
CFLAGS=-I/usr/include/python2.6 `pkg-config --cflags gtk+-2.0 pygtk-2.0 gthread-2.0`  -I. -I..
CXXFLAGS=-DGTK2  
LDFLAGS=`pkg-config --libs gtk+-2.0 pygtk-2.0 pygobject-2.0 gthread-2.0`
LEXEROBJS=$(wildcard ~/workspace/pygtkscintilla/scintilla/gtk/Lex*.o)

all: gtkscintilla-wrap.c gtkscintilla-module.o gtkscintilla.o gtkscintilla.so

gtkscintilla-wrap.c: gtkscintilla.defs gtkscintilla.override
 python /usr/share/pygobject/2.0/codegen/codegen.py \
 --override gtkscintilla.override \
 --prefix gtkscintilla gtkscintilla.defs &gt; $@

# Here's the magic!
gtkscintilla.so: gtkscintilla-wrap.o gtkscintilla.o  gtkscintilla-module.o
 gcc -shared  $(LDFLAGS) -L~/workspace/pygtkscintilla/scintilla/bin -lscintilla  $^ -o $@

gtkscintilla-wrap.o: gtkscintilla-wrap.c
 gcc $(CFLAGS) -fPIC -c $^ -o $@
gtkscintilla.o: gtkscintilla.c
 gcc $(CFLAGS) -fPIC -c $^ -o $@
gtkscintilla-module.o: gtkscintilla-module.c
 gcc  $(CFLAGS) -fPIC -c   $^ -o $@

clean:
 rm -f gtkscintilla.so gtkscintilla-wrap.c gtkscintilla.o gtkscintilla-module.o
</pre>
<p>Ok I&#8217;ve finished telling my story. I hope that my errors can help you!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=83&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/08/01/wrapping-gobject-for-pygtk-a-real-world-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>Wrapping pygtk widgets &#8211; what you should know</title>
		<link>http://pygabriel.wordpress.com/2009/07/31/wrapping-pygtk-widgets-what-you-should-know/</link>
		<comments>http://pygabriel.wordpress.com/2009/07/31/wrapping-pygtk-widgets-what-you-should-know/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 18:45:32 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wrapping]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/?p=74</guid>
		<description><![CDATA[In past days I&#8217;ve encountered a series of problems. In this article I will explain what kind of problem one can found and how to solve this problems. I&#8217;ve some hints: Study the C syntax and the pointers , skip all the algorithmic part: it&#8217;s not useful for wrapping a python module. It&#8217;s useful to  [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=74&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In past days I&#8217;ve encountered a series of problems. In this article I will explain what kind of problem one can found and how to solve this problems.</p>
<p>I&#8217;ve some hints:</p>
<ul>
<li> Study the C syntax and the pointers , skip all the algorithmic part: it&#8217;s not useful for wrapping a python module.</li>
<li>It&#8217;s useful to  study some C++  for design purposes, the C manuals doesn&#8217;t face well the multiple-file programs, compilation,  headers topics&#8230; In C++ this is necessary and well explained in manuals.</li>
<li>The most important thing you should know is how to read (and write ) simple Makefiles,  I&#8217;ve tried to learn autotools but they are very hard to understand.</li>
</ul>
<h2>Libraries and python modules</h2>
<p>A python module (from a C wrapper)  is a <span style="text-decoration:underline;"><strong>shared</strong></span> library. What&#8217;s shared, and what&#8217;s library? Let&#8217;s explain with a simple example.</p>
<p>Suppose you are a mathematician and you&#8217;ve coded in C your ugly formulas.  You want to use this formulas in other programs.</p>
<p>The best solution is to split your program in three files:</p>
<ul>
<li>main.c : Run the program, using the functions you specify in other files.( includes headers files like ugly-functions.h to define the fuctions prototypes)</li>
<li>ugly-functions.h : here are the function prototipes, each function is declared and explained in an human-readable format ( a lot of  comments)</li>
<li>ugly-functions.c : here are the function implementations, you code what each function do.</li>
</ul>
<p>Well, it&#8217;s time to compile your boring program. You can compile with:</p>
<pre>gcc ugly-functions.c main.c -o boring-program</pre>
<p>Another way, more interesting:</p>
<pre>gcc -c ugly-functions.c # The output is a file called ugly-functions.o
gcc -c main.c           # main.o
gcc main.o ugly.functions.o -o boring-program # This phase is called linking</pre>
<p>With the first two commands you create object files.  With the last command you link the so called object-files in an executable form.</p>
<p>The -c option tells gcc to don&#8217;t call the linker. The linker links the function implementations to their name. (otherwise main.c couldn&#8217;t find the function implementations).</p>
<h3>Static libraries</h3>
<p>Now you can found other formulas and code them in another file:  good-formulas.c.</p>
<p>You make your header file(.h), and your source file (.c), now you can compile with the same command.</p>
<pre>gcc -c ugly-functions.c # The output is a file called ugly-functions.o
gcc -c good-formulas.c  # good-formulas.o
gcc -c main.c           # main.o
gcc main.o ugly.functions.o good-formulas.o -o interesting-program</pre>
<p>Ok you have obtained your interesting program with your new good formulas.  Now you may want to transform them in libraries.</p>
<h3>Static libraries</h3>
<p>To make a static library, you can group (archive) your object-files in a single file with this command:</p>
<pre><span><span style="color:#000000;">
<pre>ar rcs libmine.a ugly-functions.o good-formulas.o</pre>
<p></span></span></pre>
<p>now with this archive you can link your functions to the main program in this way:</p>
<pre>gcc main.o libmine.a -o interesting-program</pre>
<p>OK. You&#8217;ve done our static library. You&#8217;ve copied in the final executable all the object-files.  When there are a lot of object-files the executable will growth in dimension. Here comes the shared libraries.</p>
<p>A note before proceeding, static libraries are discouraged in general.</p>
<h3>Shared libraries</h3>
<p>Now there&#8217;s the most important part of the tutorial.  Because python modules are shared libraries.</p>
<p>To make a shared library, you have to recompile your .c files in a special manner, with the -fPIC option:  this makes the library to be loaded and referenced at run time.</p>
<pre>
<pre>gcc -c -fPIC ugly-functions.c
gcc -c -fPIC good-formulas.c</pre>
</pre>
<p>Now we can create the library, libmine.so :</p>
<pre>gcc -shared ugly-functions.o good-formulas.o -o libmine.so</pre>
<p>Now it&#8217;s time to link, you can use the same method:</p>
<pre>gcc main.o libmine.so -o interesting-program</pre>
<p>There&#8217;s another way to link the program, that is mostly used:</p>
<pre>gcc -L/directory/containing/library -lmine main.o -o interesting-program</pre>
<p>The -l option specifies which library to link when you use this you have to omit the lib prefix and the .so suffix  (if there isn&#8217;t the lib prefix you have to omit only the .so suffix).</p>
<p>The -L option specifies the path where to find the library.</p>
<p>Remember this options that are widely used in Makefiles.</p>
<p>Now this library can be used by a lot of programs and it&#8217;s linked at runtime but it has to be reachable. If you run the program you will catch this error:</p>
<pre>./interesting-program: error while loading shared libraries: libmine.so:
 cannot open shared object file: No such file or directory</pre>
<p>You have to tell to the system where to find the library, you can put it in a standard location like /usr/lib or you can use the variable LD_LIBRARY_PATH.</p>
<pre>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/directory/containing/library</pre>
<p>Re-run and it should be ok. There are a lot of other problems you can encounter, mostly related to the file you have linked in the library.</p>
<h3>What you should take at home</h3>
<p>When you compile python module in a shared library you can encounter a lot of problems:</p>
<ul>
<li>Sure you that you have compiled <strong><span style="text-decoration:underline;">ALL</span></strong> the object files with the -fPIC option</li>
<li>You must include all the libraries that contains the functions defined. Otherwise you will encounter &#8220;undefined symbol&#8221; errors.</li>
<li>Others that now I can&#8217;t remember</li>
</ul>
<p><span style="color:#888888;"> </span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/74/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=74&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/07/31/wrapping-pygtk-widgets-what-you-should-know/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
		<item>
		<title>Eureka eureka eureka!!! pygtkscintilla coming soon!!!!</title>
		<link>http://pygabriel.wordpress.com/2009/07/29/eureka-eureka-eureka-pygtkscintilla-coming-soon/</link>
		<comments>http://pygabriel.wordpress.com/2009/07/29/eureka-eureka-eureka-pygtkscintilla-coming-soon/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 22:11:46 +0000</pubDate>
		<dc:creator>gabrielelanaro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pygabriel.wordpress.com/2009/07/29/eureka-eureka-eureka-pygtkscintilla-coming-soon/</guid>
		<description><![CDATA[Well after some days of pain and blood finally I compiled and run a pygtkscintilla module!!! This gives me a great great satisfaction and happiness!!!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=73&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Well after some days of pain and blood finally I compiled and run a pygtkscintilla module!!! This gives me a great great satisfaction and happiness!!!<br />
 <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pygabriel.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pygabriel.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pygabriel.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pygabriel.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pygabriel.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pygabriel.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pygabriel.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pygabriel.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pygabriel.wordpress.com&amp;blog=8682004&amp;post=73&amp;subd=pygabriel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pygabriel.wordpress.com/2009/07/29/eureka-eureka-eureka-pygtkscintilla-coming-soon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5bfe31fdaae579afcfcf22900dab73f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielelanaro</media:title>
		</media:content>
	</item>
	</channel>
</rss>
