<?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/"
	>

<channel>
	<title>Eurion · RainCT&#039;s Blog &#187; python</title>
	<atom:link href="http://bloc.eurion.net/archives/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://bloc.eurion.net</link>
	<description>I would love to change the world, but they won&#039;t give me the source code...</description>
	<lastBuildDate>Sun, 29 Jan 2012 13:23:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Sudoku solving with Python and SAT</title>
		<link>http://bloc.eurion.net/archives/2010/sudoku-solving-with-python-and-sat/</link>
		<comments>http://bloc.eurion.net/archives/2010/sudoku-solving-with-python-and-sat/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 21:53:20 +0000</pubDate>
		<dc:creator>RainCT</dc:creator>
				<category><![CDATA[Planet Ubuntu]]></category>
		<category><![CDATA[logics]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://bloc.eurion.net/?p=541</guid>
		<description><![CDATA[At Logic class last week we saw how to solve a Sudoku using SAT and for fun I decided to actually try this out using Python. It turned out to be pretty trivial to implement and I thought I&#8217;d share the experience. First of all let&#8217;s see how the Sudoku problem was described at class: [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://www.fib.upc.edu/en/estudiar-enginyeria-informatica/enginyeries-pla-2003/assignatures/IL.html">Logic</a> class last week we saw how to solve a <a href="http://en.wikipedia.org/wiki/Sudoku">Sudoku</a> using <a href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT</a> and for fun I decided to actually try this out using Python. It turned out to be pretty trivial to implement and I thought I&#8217;d share the experience.</p>
<p>First of all let&#8217;s see how the Sudoku problem was described at class: we have a table with 9 rows and 9 columns;</p>
<ul>
<li><strong>1.</strong> Each field [i, j] (where i=1..9 and j=1..9) has at least one value (between 1 and 9).</li>
<li><strong>2.</strong> Each field [i, j] (where i=1..9 and j=1..9) doesn&#8217;t have more than one value.</li>
<li><strong>3.</strong> There isn&#8217;t any repeated value in any row, column or 3&#215;3 group.</li>
<li><strong>4.</strong> Some of the fields have a predefined value.</li>
</ul>
<p>Now to implement this in code, first of all I needed a Python module implementing SAT solving. A quick search in Debian&#8217;s repositories gave me <a href="http://www.logilab.org/card/eid/3441">python-logilab-constraint</a>, which I&#8217;ve found to be quite nice to use, even though it could definitely take some speed improvements.</p>
<p>Conditions <strong>1</strong> and <strong>2</strong> aren&#8217;t a problem at all, as <em>logilab.constraint</em> can be used quite naturally <small>[0]</small>. We just define a variable for each field (eg., x11 to x99, where the first number is the row and the second number is the column) and the domain in which they operate (integer value from 1 to 9):</p>
<pre>values = range(1, 10) # [1..9]
variables = ["x%d%d" % (i, j) for j in values for i in values]
domains = {}

for variable in variables:
	domains[variable] = fd.FiniteDomain(values)
</pre>
<p>The <strong>4</strong>th rule is also straightforward, we just need to hardcode the values. If we have a bidimensional list <em>sudoku</em> containing the initial numbers and <em>None</em> in all empty fields, we add each of them as a constraint:</p>
<pre>constraints = []
for i, row in enumerate(sudoku):
	for j, field in enumerate(row):
		if field is None:
			continue
		variable = "x%d%d" % (i+1, j+1)
		constraints.append(fd.make_expression((variable,),
			"%s == %d" % (variable, field)))
</pre>
<p>Now only rule <strong>3</strong> remains; here we basically have to set up three more groups of constraints: one for rows, one for columns and one for the 3&#215;3 groups. My initial implementation checked each row/column/group at once; for example, for the first row «<em>x11 != x12 != x13 != &#8230; != x19</em>», for the first column «<em>x11 != x21 != &#8230; != x91</em>», etc. However, this proved to be extremely slow, and after checking the «<em>Performance considerations</em>» section of <a href="http://www.logilab.org/card/eid/3441">Logilab Constraint&#8217;s documentation</a> I split up the row and column conditions <small>[1]</small> to lots of smaller conditions, as in: «<em>x11 != x12</em>», «<em>x11 != x13</em>», «x11 != x14», etc. I also moved the constraints for the initial numbers to the top (I had them at the end of the <em>constraints</em> list before), as they are the simplest ones. With those changes resolution time changed from several minutes to some tenths of a second.</p>
<p>And this is it. After all constraints have been added, we just need to run the solver:</p>
<pre>repository = Repository(variables, domains, constraints)
solutions = Solver().solve(repository)
</pre>
<p>The complete code is available via Bazaar at <a href="http://bazaar.launchpad.net/~rainct/%2Bjunk/sudoku-sat/annotate/head%3A/sudoku.py">lp:~rainct/+junk/sudoku-sat</a>. Being completely new to the <em>logilab.constraints</em> module, or implementing any such stuff at all, it took me around half an hour to write this, which shows how SAT makes such sort of problems really straightforward.</p>
<p><small><br />
[0] Using <em>logilab.constraint</em> it&#8217;s possible to assign arbitrary Python data to variables (here we just give each an integer, but variables could also take tuples or whatever else). When this problem was presented at class using pure propositional logic it was a bit more cumbersome, as we couldn&#8217;t just say &#8220;there&#8217;s a variable x11 with domain [1..9]&#8220;. For instance, rule <strong>1</strong> was «<em>(p111 | p112 | p113 | &#8230; | p119) and (p121 | &#8230; | p129) &#8230;</em>», where &#8220;p111&#8243; would be True if field [1,1] is supposed to contain a one, &#8220;p112&#8243; is True if it&#8217;s supposed to contain a two, etc.<br />
[1] I didn&#8217;t bother also splitting up he 3&#215;3 group constraints since the other two changes already gave me enough of a speedup; changing that may squeeze a few msecs more out of it.<br />
P.S.: If you&#8217;d like a more formal explanation of this, a search on Google found this paper: <a href="http://www.cl.cam.ac.uk/~tw333/publications/weber05satbased.pdf">A SAT-based Sudoku Solver</a>.<br />
</small></p>
<p>Related posts:<ol>
<li><a href='http://bloc.eurion.net/archives/2010/python-snippets-web-directory/' rel='bookmark' title='You no longer have an excuse not to look at Python Snippets!'>You no longer have an excuse not to look at Python Snippets!</a> <small>You&#8217;ve probably already heard of Jono Bacon&#8217;s effort to create...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://bloc.eurion.net/archives/2010/sudoku-solving-with-python-and-sat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>You no longer have an excuse not to look at Python Snippets!</title>
		<link>http://bloc.eurion.net/archives/2010/python-snippets-web-directory/</link>
		<comments>http://bloc.eurion.net/archives/2010/python-snippets-web-directory/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 23:12:15 +0000</pubDate>
		<dc:creator>RainCT</dc:creator>
				<category><![CDATA[Planet Ubuntu]]></category>
		<category><![CDATA[Planet Ubuntu.cat]]></category>
		<category><![CDATA[opportunistic development]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[website]]></category>

		<guid isPermaLink="false">http://bloc.eurion.net/?p=525</guid>
		<description><![CDATA[You&#8217;ve probably already heard of Jono Bacon&#8217;s effort to create a collection of Python snippets and of Acire, the application to browse through them. If you&#8217;re interested in developing something with Python you should really take a look at those 115 (and couting!) awesome snippets, ranging from the most basic stuff to more advanced examples [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve probably already heard of Jono Bacon&#8217;s effort to <a href="https://wiki.ubuntu.com/PythonSnippets">create a collection of Python snippets</a> and of <a href="http://www.jonobacon.org/2010/02/26/acire-0-3-released/">Acire</a>, the application to browse through them. If you&#8217;re interested in developing something with Python you should really take a look at those 115 (and couting!) awesome <a href="https://launchpad.net/python-snippets">snippets</a>, ranging from the most basic stuff to more advanced examples on a wide range of topics.</p>
<p>Last Thursday there was a talk on Acire and a snippet creation party (as part of the <a href="https://wiki.ubuntu.com/UbuntuOpportunisticDeveloperWeek">Ubuntu Opportunistic Developer Week</a>) and someone mentioned it would be nice to have a web interface. So, yesterday I took a couple hours and hacked together a quick script to convert the snippets to HTML, resulting in <a href="http://eurion.net/python-snippets/">this snippets directory</a> which you can use to look up stuff when you haven&#8217;t Acire at hand or to give links to snippets to other people!</p>
<div id="attachment_538" class="wp-caption aligncenter" style="width: 310px"><a href="http://bloc.eurion.net/wp-content/uploads/2010/03/python-snippets-web.png"><img class="size-medium wp-image-538" title="python-snippets-web" src="http://bloc.eurion.net/wp-content/uploads/2010/03/python-snippets-web-300x156.png" alt="" width="300" height="156" /></a><p class="wp-caption-text">The new web interface to python-snippets!</p></div>
<p>And now that you&#8217;ve read this post, maybe you would like to <a href="http://eurion.net/python-snippets/snippet/Load%20an%20Image%20and%20detect%20click%20events.html">delve into Clutter</a>, <a href="http://eurion.net/python-snippets/snippet/Create%20an%20Application%20Indicator.html">update your application to work with Application Indicator</a>, <a href="http://eurion.net/python-snippets/snippet/Recently%20used%20items%20%28async%29.html">see how easy it is to get data from Zeitgeist</a> or <a href="http://eurion.net/python-snippets/snippet/Lists%20101.html">refresh the knowledge on lists</a> you gained at <a href="https://wiki.ubuntu.com/MeetingLogs/OpWeek1002/Python4Programmers">Rick Spencer&#8217;s Python talk</a>?</p>
<p><em>The code for the snippets generator is available <a href="https://code.launchpad.net/~rainct/+junk/python-snippets-webui">here</a>. Thanks go to <a href="http://www.makotemplates.org/">Mako Templates</a>, <a title="Pygments - Python syntax highlighter" href="http://pygments.org/">Pygments</a> and <a title="Universal Encoding Detector: character encoding auto-detection in Python" href="http://chardet.feedparser.org/">Chardet</a> for having made it dead easy to create this page! And, of course, patches are welcome.<br />
</em></p>
<p>Related posts:<ol>
<li><a href='http://bloc.eurion.net/archives/2010/sudoku-solving-with-python-and-sat/' rel='bookmark' title='Sudoku solving with Python and SAT'>Sudoku solving with Python and SAT</a> <small>At Logic class last week we saw how to solve...</small></li>
<li><a href='http://bloc.eurion.net/archives/2010/introducing-espeak-gui/' rel='bookmark' title='Introducing espeak-gui'>Introducing espeak-gui</a> <small>I&#8217;m joining the hype of presenting little new projects there...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://bloc.eurion.net/archives/2010/python-snippets-web-directory/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>espeak-gui 0.2</title>
		<link>http://bloc.eurion.net/archives/2010/espeak-gui-0-2/</link>
		<comments>http://bloc.eurion.net/archives/2010/espeak-gui-0-2/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 20:10:26 +0000</pubDate>
		<dc:creator>RainCT</dc:creator>
				<category><![CDATA[Planet GNOME]]></category>
		<category><![CDATA[Planet Ubuntu]]></category>
		<category><![CDATA[Planet Ubuntu.cat]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[Programari lliure]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[speech-synthesis]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://bloc.eurion.net/?p=470</guid>
		<description><![CDATA[Yesterday I did a first release of espeak-gui, so while I&#8217;m still in practice I&#8217;ve decided to get out a second one! The main changes are fixing a crash bug and&#8230; internationalization support. So, if you like this project but you&#8217;re not a coder, now you&#8217;ve got a way to contribute: translating it into your [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I did a first release of <a href="http://bloc.eurion.net/archives/2010/introducing-espeak-gui/">espeak-gui</a>, so while I&#8217;m still in practice I&#8217;ve decided to get out a second one!</p>
<p>The main changes are fixing a crash bug and&#8230; internationalization support. So, if you like this project but you&#8217;re not a coder, now you&#8217;ve got a way to contribute: <a href="https://translations.launchpad.net/espeak-gui">translating it into your language</a> (come on, it only has a few strings! :)).</p>
<p>The new version is already in <a href="https://launchpad.net/~rainct/+archive/voice/">my PPA</a>: <a href="https://launchpad.net/~rainct/+archive/voice/+files/espeak-gui_0.2-0ubuntu1~ppa1_all.deb">espeak-gui_0.2-0ubuntu1~ppa1_all.deb</a>. A tarball is also available, and the installation instructions are the following:</p>
<pre>$ wget -c <a href="http://launchpad.net/espeak-gui/trunk/0.2/+download/espeak-gui-0.2.tar.gz">http://launchpad.net/espeak-gui/trunk/0.2/+download/espeak-gui-0.2.tar.gz</a>
$ tar -xzvf espeak-gui-0.2.tar.gz; cd espeak-gui-0.2
$ python setup.py build
$ sudo python setup.py install</pre>
<p>In case you didn&#8217;t already have the previous version, you&#8217;ll also need to install the <a href="https://launchpad.net/python-espeak">python-espeak</a> module, for which there are also .deb&#8217;s (<a href="https://launchpad.net/~rainct/+archive/voice/+files/python-espeak_0.0ubuntu1~ppa1_i386.deb">i386</a>, <a href="https://launchpad.net/~rainct/+archive/voice/+files/python-espeak_0.0ubuntu1~ppa1_amd64.deb">amd64</a>) or the manual installation option like explained in my <a href="http://bloc.eurion.net/archives/2010/introducing-espeak-gui/">previous post</a>:</p>
<pre>$ bzr get lp:python-espeak
$ cd python-espeak
$ python setup.py build
$ sudo python setup.py install</pre>
<p>Here are the contents of the NEWS file:</p>
<pre>2010-01-02: Version 0.2
-----------------------

 - Fixed a crash happening when there was no voice language set in
   gconf (LP: 502253). [Reported by Rugby471]
 - Added a "Plain text" filter to the Open/Save dialogues.
 - Added internationalization support.
 - Added a manpage and a gconf schemas file.
 - A couple little user interface improvements.

Translations: Catalan.</pre>
<p>Related posts:<ol>
<li><a href='http://bloc.eurion.net/archives/2010/introducing-espeak-gui/' rel='bookmark' title='Introducing espeak-gui'>Introducing espeak-gui</a> <small>I&#8217;m joining the hype of presenting little new projects there...</small></li>
<li><a href='http://bloc.eurion.net/archives/2010/gnome-activity-journal-and-installing-it-on-ubuntu/' rel='bookmark' title='GNOME Activity Journal, and installing it on Ubuntu'>GNOME Activity Journal, and installing it on Ubuntu</a> <small>As already announced by Seif, the first development release of...</small></li>
<li><a href='http://bloc.eurion.net/archives/2009/zeitgeist-api-02/' rel='bookmark' title='Introduction to Zeitgeist 0.2&#8242;s API'>Introduction to Zeitgeist 0.2&#8242;s API</a> <small>So now that Zeitgeist 0.2.0 is out I&#8217;ve thought I&#8217;d...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://bloc.eurion.net/archives/2010/espeak-gui-0-2/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Introducing espeak-gui</title>
		<link>http://bloc.eurion.net/archives/2010/introducing-espeak-gui/</link>
		<comments>http://bloc.eurion.net/archives/2010/introducing-espeak-gui/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 21:33:36 +0000</pubDate>
		<dc:creator>RainCT</dc:creator>
				<category><![CDATA[Planet GNOME]]></category>
		<category><![CDATA[Planet Ubuntu]]></category>
		<category><![CDATA[Planet Ubuntu.cat]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[Programari lliure]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[speech-synthesis]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://bloc.eurion.net/?p=463</guid>
		<description><![CDATA[I&#8217;m joining the hype of presenting little new projects there seems to be those days, unleashing the first version of espeak-gui, a graphical interface to let the computer read out text. Why, when, who? The project started almost a year ago when, out of curiosity on what writing Python bindings for C/C++ libraries is like, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://bloc.eurion.net/wp-content/uploads/2010/01/espeak-gui-0.1.png"><img class="size-medium wp-image-464 alignright" title="Screenshot of espeak-gui (version 0.1)" src="http://bloc.eurion.net/wp-content/uploads/2010/01/espeak-gui-0.1-300x180.png" alt="" width="300" height="180" /></a>I&#8217;m joining the hype of presenting little new projects there seems to be those days, unleashing the first version of <a href="https://launchpad.net/espeak-gui">espeak-gui</a>, a graphical interface to let the computer read out text.</p>
<p><strong>Why, when, who?</strong></p>
<p>The project started almost a year ago when, out of curiosity on what writing Python bindings for C/C++ libraries is like, I started <a href="https://launchpad.net/python-espeak">python-espeak</a>, bindings for the espeak speech synthesizer (which, by the way, comes installed by default on Ubuntu and many other distributions).</p>
<p>It turned out that writing bindings isn&#8217;t as funny as I thought so they haven&#8217;t advanced much since then, but the basic functionality was there and I felt the need for some application using those bindings, so that&#8217;s how I started <a href="https://launchpad.net/python-espeak">espeak-gui</a>.</p>
<p>Some months later, in true Free Software spirit, someone else -interested in an application like this for personal usage- found my code on Launchpad and got in touch with me, providing me with quite some nice patches. Thank you, <a href="https://launchpad.net/~joe-a-burmeister">Joe Burmeister</a>! However, I didn&#8217;t do any more work on it, as I&#8217;ve been busy with other projects (eg. <a href="http://zeitgeist-project.com/">Zeitgeist</a>), and development stalled there.</p>
<p>Now, another half a year later, I&#8217;ve finally got back to this and decided it&#8217;s time I push it out into the wild. So, after cleaning it up a bit more and implementing some new feature, here you have <a href="https://launchpad.net/espeak-gui">espeak-gui</a>!</p>
<p>(The bindings aren&#8217;t really encouraged for widespread usage at this point and I&#8217;ll probably end up rewriting them using <a href="http://www.swig.org/">SWIG</a> or something else; however, if you&#8217;re interested in using them please get in touch with me).</p>
<p><strong>Where do I get it?</strong></p>
<p>If you&#8217;re using Ubuntu or Debian, you can find a <a href="https://launchpad.net/~rainct/+archive/voice/+packages">packages for python-espeak and espeak-gui</a> in <a href="https://launchpad.net/~rainct/+archive/voice">my PPA</a>.</p>
<p>For users of other distributions, you can install them manually after installing the needed dependencies (most importantly, libespeak-dev).</p>
<p>For the Python bindings for espeak:</p>
<pre>$ bzr get lp:python-espeak
$ cd python-espeak
$ python setup.py build
# python setup.py install
</pre>
<p>And for the GUI:</p>
<pre>$ wget -c <a href="http://launchpad.net/espeak-gui/trunk/0.1/+download/espeak-gui-0.1.tar.gz">http://launchpad.net/espeak-gui/trunk/0.1/+download/espeak-gui-0.1.tar.gz</a>
$ tar -xzvf espeak-gui-0.1.tar.gz
$ cd espeak-gui-0.1
# python setup.py install
</pre>
<p>[<strong>Update:</strong> A new version is out, see <a href="http://bloc.eurion.net/archives/2010/espeak-gui-0-2/">espeak-gui 0.2</a> for details.]</p>
<p>I have several ideas on how to continue improving it and I think I&#8217;ll slowly continue doing so (or maybe not so slowly if I get positive feedback on this :)). Also, patches are always welcome!</p>
<p><strong>Using it</strong></p>
<p>Once installed, you&#8217;ll find <a href="https://launchpad.net/espeak-gui">espeak-gui</a> under <em>Applications</em> -&gt; <em>Sound and Video</em> (maybe Accessibility would be a better place?), or you can run it from the command line like this:</p>
<pre>espeak [ &lt;file 1&gt; &lt;file 2&gt; ... ]</pre>
<p>Related posts:<ol>
<li><a href='http://bloc.eurion.net/archives/2010/espeak-gui-0-2/' rel='bookmark' title='espeak-gui 0.2'>espeak-gui 0.2</a> <small>Yesterday I did a first release of espeak-gui, so while...</small></li>
<li><a href='http://bloc.eurion.net/archives/2009/zeitgeist-api-02/' rel='bookmark' title='Introduction to Zeitgeist 0.2&#8242;s API'>Introduction to Zeitgeist 0.2&#8242;s API</a> <small>So now that Zeitgeist 0.2.0 is out I&#8217;ve thought I&#8217;d...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://bloc.eurion.net/archives/2010/introducing-espeak-gui/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Freevial, a trivia game for community events</title>
		<link>http://bloc.eurion.net/archives/2009/freevial-a-trivia-game-for-community-events/</link>
		<comments>http://bloc.eurion.net/archives/2009/freevial-a-trivia-game-for-community-events/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 22:08:41 +0000</pubDate>
		<dc:creator>RainCT</dc:creator>
				<category><![CDATA[Planet Ubuntu]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[freevial]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[Jocs]]></category>
		<category><![CDATA[loco]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://bloc.eurion.net/?p=213</guid>
		<description><![CDATA[Freevial is a trivia-like questions and answers game which has been created by the Catalan LoCo Team. We play at least one match at all our events and its great fun, so we have decided that we want to go international and share it with any other group who wants to use it. You can [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://launchpad.net/freevial">Freevial</a> is a trivia-like questions and answers game which has been created by the <a href="https://wiki.ubuntu.com/CatalanTeam">Catalan LoCo Team</a>. We play at least one match at all our events and its great fun, so we have decided that we want to go international and share it with any other group who wants to use it. You can see how it looks in this <a title="Video demonstrating the features of Freevial" href="http://www.youtube.com/watch?v=K6rxUk_kDf4">video</a>:</p>
<p><object width="425" height="344" data="http://www.youtube.com/v/K6rxUk_kDf4&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/K6rxUk_kDf4&amp;hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
<p>Now that you&#8217;ve seen how cool it is, go grab it <a href="http://packages.ubuntu.com/jaunty/freevial">here</a> (yes, the Jaunty version will work fine on Intrepid; in case you&#8217;re not comfortable with this, expect a <a href="https://bugs.edge.launchpad.net/intrepid-backports/+bug/332693">backport</a> within the next days.</p>
<p>Currently it only includes Catalan questions, but with the help of you all we hope to get categories in lots of different languages! If you have a bit of spare team, join #freevial on irc.freenode.net and we&#8217;ll help you to start working on some category in your language (there&#8217;s a <a href="http://db.freevial.org/">web editor</a> to write questions, thanks to <a href="http://arnau.alcalleop.cat/">Arnau Alcázar</a>). We&#8217;d love to see other LoCo Teams (or even groups completely unrelated to Ubuntu) using it!</p>
<p>Related posts:<ol>
<li><a href='http://bloc.eurion.net/archives/2007/the-freevial/' rel='bookmark' title='The Freevial'>The Freevial</a> <small>Avui ha tingut lloc la primera partida de Freevial al...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://bloc.eurion.net/archives/2009/freevial-a-trivia-game-for-community-events/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Standalone desktop widgets with PyGTK+</title>
		<link>http://bloc.eurion.net/archives/2009/standalone-pygtk-desktop-widgets/</link>
		<comments>http://bloc.eurion.net/archives/2009/standalone-pygtk-desktop-widgets/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 22:23:55 +0000</pubDate>
		<dc:creator>RainCT</dc:creator>
				<category><![CDATA[Planet Ubuntu]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://bloc.eurion.net/?p=122</guid>
		<description><![CDATA[Now that I&#8217;ve got a new computer I decided to give gdesklets a try and I have to say, I am not excited. Most of them don&#8217;t even work, and I don&#8217;t really like those which do work, so I ended up with only one single desklet enabled, &#8220;Quote of the Day&#8221;, and for a [...]]]></description>
			<content:encoded><![CDATA[<p>Now that I&#8217;ve got a new computer I decided to give <a href="http://www.gdesklets.de/">gdesklets</a> a try and I have to say, I am not excited. Most of them don&#8217;t even work, and I don&#8217;t really like those which do work, so I ended up with only one single <em>desklet</em> enabled, &#8220;Quote of the Day&#8221;, and for a single widget I don&#8217;t want to have gdesklets running. So, considering that I&#8217;ve got some spare hours and that I haven&#8217;t coded much lately, I decided to try to create a standalone version of it.</p>
<p>So, after deciding that I&#8217;d use Python and try to get this done with GTK+, I needed a window with two properties: a) being &#8220;on the desktop&#8221;, and b) having a transparent background. I could achieve both things without too much hassle, keep reading to know how!</p>
<p><strong>Widget on the desktop</strong></p>
<p>After a quick search I found<a href="http://unpythonic.blogspot.com/2007/11/desktop-widgets-with-pygtk-launchpad.html"> this post</a>, which claims that this can be achieved by giving our window the type hint &#8220;gtk.gdk.WINDOW_TYPE_HINT_DESKTOP&#8221;. I tried it out and, yes!, there we have our widget on the desktop&#8230; But wait, I just clicked next to it and it disappeared! Weird&#8230; So it seems like clicking somewhere on the real desktop places the widget behind it (or does something else with it) and then it&#8217; s no longer visible. I looked up the hint in the documentation and there it says that it actually is to implement <em>a desktop</em>, so I stopped messing with this and looked for something else.</p>
<p>The solution I found was a quite ovious one:  just give our window all the properties we expect a widget to have. This is done with the following code (assuming that we have a gtk.Widget instance called, well, widget):</p>
<pre>widget.set_skip_taskbar_hint(True)
widget.set_skip_pager_hint(True)
widget.set_keep_below(True)
widget.set_decorated(False)
widget.stick()</pre>
<p>I am not going to stop and explain each of them as their name already explains it all; if you want to know a bit more about some of them you&#8217;ll find more details in GTK+&#8217;s docs. This code achieves the purpose, but it has a little flaw: although our window behaves pretty much like a widget, it still is a window, so clicking on &#8220;Show desktop&#8221; will hide it. Gdesklets has the same problem, though, so I guess we can live with it. <em>[Update: See below for an improved variant of this code.]</em>.</p>
<p><strong>Window with a transparent background</strong></p>
<p>A widget isn&#8217;t a true widget if it hasn&#8217;t some fancy transparency, so this is an important point, and I had absolutely no clue on how to solve it.  Fortunately, the PyGTK+ docs came to the rescue, with &#8220;A <a href="http://www.pygtk.org/docs/pygtk/class-gdkwindow.html">gtk.gdk.Window</a> Composited Windows example&#8221;. The example shows how to place a semi-transparent button upon a colored window, but simplyfing it a bit I could get it to do what I want: make the background of the window itself transparent. Here is the result:</p>
<pre>import gtk
import cairo

def transparent_expose(widget, event):
	cr = widget.window.cairo_create()
	cr.set_operator(cairo.OPERATOR_CLEAR)
	region = gtk.gdk.region_rectangle(event.area)
	cr.region(region)
	cr.fill()
	return False

# And in the GUI part, after defining a gtk.Window called "window":
		screen = window.get_screen()
		rgba = screen.get_rgba_colormap()
		window.set_colormap(rgba)
		window.set_app_paintable(True)
		window.connect("expose-event", transparent_expose)</pre>
<div id="attachment_130" class="wp-caption aligncenter" style="width: 358px"><img class="size-full wp-image-130" title="Screenshot of a transparent GTK+ window" src="http://bloc.eurion.net/wp-content/uploads/2009/01/transparent_window.png" alt="Who doesn't like transparency? :)" width="348" height="120" /><p class="wp-caption-text">Who doesn&#39;t like transparency? :)</p></div>
<p><strong>Putting it all together</strong></p>
<p>Now that we know how to implement both characteristics, we just have to put them together. To make it easier to reuse the code if I later decide to create more widgets, I wrote thi as a gtk.Window subclass:</p>
<pre>import gtk
import cairo

def transparent_expose(widget, event):
	cr = widget.window.cairo_create()
	cr.set_operator(cairo.OPERATOR_CLEAR)
	region = gtk.gdk.region_rectangle(event.area)
	cr.region(region)
	cr.fill()
	return False

class DesktopWindow(gtk.Window):

	# Based upon the composited window example from:
	# http://www.pygtk.org/docs/pygtk/class-gdkwindow.html

	def __init__(self, *args):

		gtk.Window.__init__(self, *args)

		self.set_skip_taskbar_hint(True)
		self.set_skip_pager_hint(True)
		self.set_keep_below(True)
		self.set_decorated(False)
		self.stick()

		screen = self.get_screen()
		rgba = screen.get_rgba_colormap()
		self.set_colormap(rgba)
		self.set_app_paintable(True)
		self.connect("expose-event", transparent_expose)</pre>
<p>I saved this as common.py, and now I can just import it into the file for my widget and use common.DesktopWindow() instead of Gtk.Window() to automatically get both, the transparent background and the widget behavior.</p>
<p>That&#8217;s it. Another day I&#8217;ll finish writing the actual widget (still have some other work to do now) and eventually publish it for whoever may want to use it. I may also make a module out of the above code (with some additional stuff, like possibly drag-and-drop support, position saving, right-click menu, etc). I hope this post will be useful to someone!</p>
<p>Ah, and if you know of a better way to achieve this (beside using some alternative to gdesklets, which would take out the fun of this project :P), please tell me!</p>
<p><strong>Update: Improved version</strong></p>
<p>Hans Rödtang pointed out that using the type hint &#8220;gtk.gdk.WINDOW_TYPE_HINT_DOCK&#8221; may solve the problem with our widget being hidden when the &#8220;Show desktop&#8221; button is pressed. Effectively, it does, and it also makes it unnecessary to set some of the properties we need manually, so here is an improved version of the DesktopWindow class:</p>
<pre>class DesktopWindow(gtk.Window):

	def __init__(self, *args):

		gtk.Window.__init__(self, *args)

		self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
		self.set_keep_below(True)
		self.set_decorated(False)
		self.stick()

		screen = self.get_screen()
		rgba = screen.get_rgba_colormap()
		self.set_colormap(rgba)
		self.set_app_paintable(True)
		self.connect("expose-event", transparent_expose)</pre>
<hr />
<p><small>
<a href="http://bloc.eurion.net/archives/2009/standalone-pygtk-desktop-widgets/#comments">15 comments</a><br />
© Siegfried-Angel Gevatter Pujals, 2009. |
<a href="http://bloc.eurion.net/archives/2009/standalone-pygtk-desktop-widgets/">Permalink</a> |
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">License</a> |
Post tags: <a href="http://bloc.eurion.net/archives/tag/gtk/" rel="tag">gtk</a>, <a href="http://bloc.eurion.net/archives/tag/python/" rel="tag">python</a><br/>
</small></p><p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://bloc.eurion.net/archives/2009/standalone-pygtk-desktop-widgets/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

