<?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>Tales of a GeekTrotter</title>
	<atom:link href="http://www.dallagnese.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dallagnese.fr</link>
	<description>Binary Logbook</description>
	<lastBuildDate>Tue, 15 May 2012 12:24:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Mobile Applications in HTML5/CSS3 with Sencha Touch</title>
		<link>http://www.dallagnese.fr/computers-it/mobile-applications-in-html5-css3-with-sencha-touch/</link>
		<comments>http://www.dallagnese.fr/computers-it/mobile-applications-in-html5-css3-with-sencha-touch/#comments</comments>
		<pubDate>Tue, 15 May 2012 12:09:36 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=899</guid>
		<description><![CDATA[Quickly build smartphone applications in HTML5/CSS3 with Sencha Touch and PhoneGap]]></description>
			<content:encoded><![CDATA[<p>A few years ago, I was writing about <a title="Build smartphone applications with Rhomobile Rhodes" href="http://www.dallagnese.fr/computers-it/programming/developpez-rapidement-des-applications-pour-les-mobiles-iphone-android-wp7-bb-symbian-avec-rhomobile-rhodes/" target="_blank">building smartphone applications with Rhomobile Rhodes</a>.</p>
<p>Since then, I also tried several frameworks, such as<strong> Appcelerator Titanium Mobile</strong> but was especially satisfied by a relatively recent one, using only web technologies: <a title="Sencha Touch" href="http://www.sencha.com/products/touch/" target="_blank">Sencha Touch 2.0</a>.<br />
My main concern about Titanium Mobile is that the generated application was not behaving the same on Android and iOS (and was not working on iOS).<br />
After writing code and testing on Android, I was very frustrated that it didn't work out-of-the-box on iPhone.<br />
I didn't really have time to investigate the problem, but it gave me a bad image of the product.<br />
That's how I ended up trying Sencha Touch 2.</p>
<p>A quick summary of the strengths and weakness of Sencha Touch 2.</p>
<p><span style="text-decoration: underline;"><strong>Strengths:</strong></span></p>
<ul>
<li>Rapid testing (inside the browser)</li>
<li>Good User Interface API</li>
<li>MVC Design Pattern</li>
<li>Provides a GUI for quick mockup (Sencha Architect)</li>
<li>Pure HTML5/CSS3</li>
</ul>
<p><span style="text-decoration: underline;"><strong>Weaknesses:</strong></span></p>
<ul>
<li>New, working fine on Mac (from what I heard/read), but unstable on Windows/Linux*</li>
<li>Is limited by the cross-domain security that prevents from fetching data from other domains that do not?explicitly?allow it if ran in the browser (not packaged as an application)</li>
<li>Needs to be integrated into another framework such as PhoneGap (Cordova) to be packaged as a <em>real</em>?application*</li>
<li>Tiny visual difference between the desktop browser rendering and the smartphone browser rendering (text is not coloured in one of the pages)</li>
</ul>
<p>*The Sencha command-line is supposed to provide packaging, but doesn't work well on Linux so I had to integrate the app inside a PhoneGap project to deploy as a <em>real</em>?application.</p>
<p>It took me about 8 working hours (a geek weekend) to build a simple application from scratch.<br />
For testing, I created a small application that allows you to add transactions to the easy online money management service <a title="Buxfer" href="http://www.buxfer.com" target="_blank">Buxfer</a>, which provides a JSON API (Sencha Touch 2 can easily handle data coming from JSON/JSONP objects).</p>
<p>The application is very basic: 3 tabs (Home, Add and Logout).<br />
On the Home tab, I list the accounts and the last transactions.<br />
On the Add tab I allow to add a transaction (an expense or an income).<br />
And the Logout tab will log the user out.</p>
<p>The application works very well on the desktop browser, and it's really fast to test our program:<br />
<object id="scPlayer" width="377" height="550" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="quality" value="high" /><param name="flashVars" value="thumb=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/FirstFrame.jpg&amp;containerwidth=377&amp;containerheight=550&amp;content=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/2012-05-15_2038.swf&amp;blurover=false" /><param name="allowFullScreen" value="true" /><param name="scale" value="showall" /><param name="allowScriptAccess" value="always" /><param name="base" value="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/" /><param name="src" value="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/jingswfplayer.swf" /><param name="flashvars" value="thumb=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/FirstFrame.jpg&amp;containerwidth=377&amp;containerheight=550&amp;content=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/2012-05-15_2038.swf&amp;blurover=false" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><embed id="scPlayer" width="377" height="550" type="application/x-shockwave-flash" src="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/jingswfplayer.swf" quality="high" flashVars="thumb=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/FirstFrame.jpg&amp;containerwidth=377&amp;containerheight=550&amp;content=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/2012-05-15_2038.swf&amp;blurover=false" allowFullScreen="true" scale="showall" allowScriptAccess="always" base="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/" flashvars="thumb=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/FirstFrame.jpg&amp;containerwidth=377&amp;containerheight=550&amp;content=http://content.screencast.com/users/Sp00ky31/folders/Jing/media/9efcc4f6-047c-41ff-baef-a60d222bd2fb/2012-05-15_2038.swf&amp;blurover=false" allowfullscreen="true" allowscriptaccess="always" /></object></p>
<p>However, there are a few differences on the <em>real</em>?application on the smartphone:<br />
 - There are no colours on the accounts balance listing (should be green if positive, red if negative)<br />
 - It's hard to make the checkboxes on the Add tab activate (touch)</p>
<p>I recorded a video of the <em>real</em>?app running on my phone, not really good quality but gives an idea of the rendering:<br />
<iframe src="http://www.youtube-nocookie.com/embed/M1DgIbxQn0M?rel=0" frameborder="0" width="640" height="360"></iframe></p>
<p>As we can see, it's still very nice, and I'm sure the little problems will be fixed soon.</p>
<p>You can find the source code of that application on BitBucket: <a title="Buxfer Mobile on BitBucket" href="https://bitbucket.org/ThomasDalla/buxfer-mobile/src" target="_blank">Buxfer Mobile</a></p>
<p>Next time, I'll try another promising mobile framework: <a title="jQuery Mobile" href="http://jquerymobile.com/" target="_blank">jQuery Mobile</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/mobile-applications-in-html5-css3-with-sencha-touch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some Parallel Computing (Multithreading) and Http Requests in C#</title>
		<link>http://www.dallagnese.fr/computers-it/some-parallel-computing-multithreading-and-http-requests-in-c/</link>
		<comments>http://www.dallagnese.fr/computers-it/some-parallel-computing-multithreading-and-http-requests-in-c/#comments</comments>
		<pubDate>Sun, 13 May 2012 13:18:39 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[multithread]]></category>
		<category><![CDATA[parallel]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[sharp]]></category>
		<category><![CDATA[studio]]></category>
		<category><![CDATA[thread]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[wpf]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=882</guid>
		<description><![CDATA[My experience with my first C# program: WPF, multithread, HTTP requests and packaging.]]></description>
			<content:encoded><![CDATA[<p>After programming in Python, Ruby, Java, C/C++ for a while, I decided to give a chance to C#.<br />
For a fair comparison, I decided to write a small program that I have already written (or parts of it) in Java, C++ and Python.</p>
<p>The requirements of the program are the following:<br />
- login to an external website I am not the owner through POST requests and store the session<br />
- fetch several pages on that website (logged in, multithreaded)<br />
- provide a login window, a window with a table (grid) to display the data fetched<br />
- provide the possibility to open the webpage we have logged in, being logged in</p>
<p>Additionally, it would be great if we could have:<br />
- easy packaging and distribution<br />
- multi-platform (Win/Linux/Mac)<br />
- rapid development</p>
<p>I tried Visual Studio 2010 C# edition and created a WPF Application.<br />
Unfortunately, I found out afterwards that WPF is not supported by Mono, the free implementation of .NET for Linux/Mac.<br />
So unfortunately, the "multi-plateform" point was not achieved.<br />
However, all the other points have been reached, and in less than a day, from scratch, my first C# application was up and running:</p>
<p><iframe width="640" height="480" src="http://www.youtube-nocookie.com/embed/n3JJFdTTFyo?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p>What it does:<br />
- Login to <a href="http://www.kingsofchaos.com" title="Kings of Chaos" target="_blank">http://www.kingsofchaos.com</a> (an old online MMORPG game not really popular anymore).<br />
- Gives choice to scan a given number of <a href="http://www.kingsofchaos.com/battlefield.php" title="KoC Battlefield" target="_blank">battlefield pages</a> from a given page.<br />
- Show the results and allow to sort by columns.<br />
- Open the stat page of a given player by double clicking on the row.</p>
<p>Download: <a href="http://www.koc-fr.com/koc_toolbox/KoC_Toolbox.zip" title="KoC=Toolbox.zip">KoC_Toolbox.zip</a></p>
<p>Let see in this post how we achieved that, and what are my first-thoughts about C# programming.</p>
<div class="warning">Usage of third-party tools that automate the game is forbidden by the Kings of Chaos rules.<br />
Doing so can have your account banned so use at your own risk.</div>
<p><span id="more-882"></span></p>
<p>Behind the scenes, we first have a simple HTTP POST request.<br />
We also want to save the user login/password so he/she doesn't have to enter it every time he/she starts the application.</p>
<p>C# provides a very simple Settings.Default feature to hold application configuration:<br />
<img src="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/2f141ef9-4692-48b2-b3be-f08aa7b05a4b/2012-05-13_2140.png" alt="Visual Studio Settings" /></p>
<p>That we can use like below:</p>
<pre class="brush:csharp">
        public LoginWindow()
        {
            InitializeComponent();
            if (Settings.Default.KoCUsername.Length>0)
            {
                usernameTextBox.Text = Settings.Default.KoCUsername;
            }
            if (Settings.Default.KoCPassword.Length > 0)
            {
                passwordBox.Password = Settings.Default.KoCPassword;
            }
        }
</pre>
<p>For easy HTTP requests (POST/GET), I found a very good base snippet by Kersny that I re-use in my application:<br />
<a href="https://gist.github.com/865296" title="Kersny BasicReq" target="_blank">https://gist.github.com/865296</a></p>
<p>I added the XMLHttpRequest feature to the class for my own needs, by took that base.<br />
Now we can easily handle the web requests.</p>
<p>Example to login:</p>
<pre class="brush:csharp">        public bool Login(string username, string password)
        {
            var postData = String.Format("usrname={0}&#038;peeword={1}", username, password);
            var result = _req.HttpPost(GetUrl("login.php"), postData, true, GetUrl());
            return IsLoggedIn(result);
        }
</pre>
<p>Visual Studio, as we can expect from Microsoft, integrates very well C# and WPF.<br />
It's very easy to find and attach UI events to actions:<br />
We can graphically draw our window, and also edit its XAML code:<br />
<img src="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/baa394f3-682c-4e0b-9755-2664ff70b765/2012-05-13_2201.png" alt="" /></p>
<p>And add methods to events, such as a Click event on the Scan button:<br />
<img src="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/5ad0251e-02ed-405d-819c-167f7c8c3d19/2012-05-13_2201.png" alt="" /></p>
<p>The next step is to fetch many pages (from 1 to 100) asynchronously and quickly (so using multi-threads).<br />
There are many ways to do that in C#.<br />
First, I tried the <strong>Thread </strong>class, but it has some issues with WPF windows that are not in the same thread.<br />
So I moved to the WPF <strong>Dispatcher</strong>, which is nice for quick UI modifications, so I use the Dispatcher to update the labels and other UI elements.<br />
For heavy tasks, such as loading and parsing hundred of pages, a combination of Threads/Dispatcher can be used, or a so-called <strong>Parallel </strong>class that handles parallel programming.</p>
<p>More information about Parallel: <a href="http://msdn.microsoft.com/en-us/library/dd460703.aspx" title="C# Parallel" target="_blank">http://msdn.microsoft.com/en-us/library/dd460703.aspx</a></p>
<p>However, I was not satisfied by the performance of Parallel, which is muuuuch slower than my C/C++ multithread version of the tool (the main one).<br />
So I searched online for an alternative and found the <strong>Task</strong> class, which seems a good option.<br />
Indeed, the performance is better (I don't have figures to support my words though....) but still much slower than its C/C++ equivalent I wrote a few years ago.</p>
<p>But it's really easy to write (contrary to my C++ version....), for example:</p>
<pre class="brush:csharp">
            for (var p = startPage; p < startPage + numberOfPages; p += 1)
            {
                var page = p;
                var t = Task.Factory.StartNew(() =>
                {
                    List<KoCUser> enemies = _koc.GetBattleFieldPageEnemies(page);
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        ((KoCUserDataContext)DataContext).AddEnemies(enemies);
                        progressBar1.Value += 1;
                    }));
                });
                tasks.Add(t);
            }
</pre>
<p>Finally, we want to open a web browser window when we double click on the row.<br />
We need to pass the cookies to the web browser, and I had to find a workaround using a DLL to do that.<br />
It's not ideal, but it's working:</p>
<pre class="brush:csharp">
        public void Navigate(string url, CookieContainer cookies)
        {
            var uri = new Uri(url);
            foreach(Cookie cookie in cookies.GetCookies(uri))
            {
                InternetSetCookie(url, cookie.Name, cookie.Value);
            }
            FieldInfo fieldInfo = webBrowser1.GetType().GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);

            if (fieldInfo!=null)
            {
                dynamic activexObject = fieldInfo.GetValue(webBrowser1);
                activexObject.Silent = true;
            }

            webBrowser1.Navigate(url);
        }
</pre>
<p>And... that's it!<br />
Our application was done in a few hours, from zero C# knowledge (but programming skills of course).</p>
<p>Besides, packaging and distributing the application is really easy.<br />
There is a "Publish Wizard" in Visual Studio that allows to deploy the application to a FTP server.<br />
I just had to provide my FTP access, and Visual Studio automatically depoyed the application!</p>
<p>The deploy URL is: <a href="www.koc-fr.com/koc_toolbox/install.html" target="_blank">www.koc-fr.com/koc_toolbox/install.html</a><br />
Unfortunately, the EXE is not signed with a valid certificate so Google consider it as malicious and warn the user:<br />
<img src="http://content.screencast.com/users/Sp00ky31/folders/Jing/media/aa458534-bb4b-4725-bfaf-bc2c29fe4652/2012-05-13_2209.png" alt="" /></p>
<p>Besides, it seems not to work with Internet Explorer... I need a special web server to handle it (with Front Page Server if I understood well).<br />
Anyway, the setup.exe file is working, and if you ignore the warning and install it, it just works!<br />
It will download the required libraries automatically if you don't have them already.</p>
<p>Moreover, it has a built-in update manager so I can publish new versions in one click and it will be automatically be detected when the client launch the application so they will be asked if they want to update the application.</p>
<p>That's a real delight, but available only on Windows (because I chose WPF as the UI framework).<br />
Java also has very easy packaging, but that's even easier than that.<br />
And compared to Python/Ruby, that's way easier.</p>
<p>I created an archive of the setup.exe file if you want to install the tool (you need a Kings of Chaos account though): <a href="http://www.koc-fr.com/koc_toolbox/KoC_Toolbox.zip" title="KoC=Toolbox.zip">KoC_Toolbox.zip</a></p>
<p>Finally, the complete source code of the program is available publicly, because open-source rocks:<br />
<a href="https://bitbucket.org/ThomasDalla/koc_toolbox/src" target="_blank">https://bitbucket.org/ThomasDalla/koc_toolbox/src</a></p>
<p>Feel free to contribute to the code, but please note that I do not plan to maintain the tool, it was just for programming purpose.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/some-parallel-computing-multithreading-and-http-requests-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Save your screenshots to a file in Python</title>
		<link>http://www.dallagnese.fr/computers-it/save-your-screenshots-to-a-file-in-python/</link>
		<comments>http://www.dallagnese.fr/computers-it/save-your-screenshots-to-a-file-in-python/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 13:58:17 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bmp]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[pil]]></category>
		<category><![CDATA[pillow]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[screenshots]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=862</guid>
		<description><![CDATA[Save your screenshots to a file in Python]]></description>
			<content:encoded><![CDATA[<p>Python allows you to quickly build useful applications.<br />
Let say you're running the old Windows XP and need to take screenshots of your screen, directly saving the picture.<br />
You might usually open Paint, paste, save (choosing the format you want to save as).<br />
Well, fast enough, but could be improved isn't it?</p>
<p>The following piece of code grabs the image from the clipboard and directly prompts you where to save the file.<br />
Depending on the filename you choose, it will automatically apply the correct compression (bmp/png/jpeg...) thanks to the Python Image Library (PIL).</p>
<p>In addition to the libraries bundled with Python you only need to install PIL, either from PIL or from PILLOW.</p>
<p>I personally chose <b>pillow</b>:</p>
<pre class="brush:bash">$ pypm install pillow
The following packages will be installed into "%APPDATA%\Python" (2.7):
 pillow-1.7.6
Hit: [pypm-free.activestate.com] pillow 1.7.6
Installing pillow-1.7.6
Fixing script %APPDATA%\Python\Scripts\pilconvert.py
Fixing script %APPDATA%\Python\Scripts\pildriver.py
Fixing script %APPDATA%\Python\Scripts\pilfile.py
Fixing script %APPDATA%\Python\Scripts\pilprint.py</pre>
<p>You are now ready to run the script:</p>
<pre class="brush:python">
import os
from PIL import ImageGrab # from PIL or PILLOW
from Tkinter import Tk
from tkFileDialog import asksaveasfile
import tkMessageBox
import subprocess

if __name__=='__main__':

    # hide the Tk window
    root = Tk()
    root.withdraw()

    # grab the image from the clipboard
    myimage = ImageGrab.grabclipboard()

    # quit if it's not an image
    if myimage is None:
        msg = "The clipboard does not contain an image."
        tkMessageBox.showwarning("Error", msg)
        exit()

    # choose where to save the file
    fout = asksaveasfile(mode='w', defaultextension=".png")

    # quit if the user canceled saving the file
    if fout is None:
        exit()

    # finally, save the file (extension will dictate the compression)
    try:
        output = fout.name
        myimage.save(output)
    except Exception, e:
        msg = "Error: %s" % e
        tkMessageBox.showerror("Error", msg)
    else:
        filePath = os.path.abspath(output)
        #tkMessageBox.showinfo("Saved", filePath)
        subprocess.Popen(r'explorer /select,"'+filePath+'"')
</pre>
<p>To use it, simply hit the "Print Scrn" key and run the script.<br />
Running the script is not that faster than starting Paint so you could create a shortcut to the desktop and create a <i>Shortcut Key</i> to the shortcut.</p>
<p>For example to set a shortcut to "Ctrl + Alt + P":<br />
<img src="http://www.dallagnese.fr/wp-content/uploads/2012/02/clip2img.png" alt="" title="clip2img" width="367" height="502" class="aligncenter size-full wp-image-863" /></p>
<p>Now simply hit "Print Scrn", "Ctrl + Alt + P" and choose where to save the screenshot, that's it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/save-your-screenshots-to-a-file-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Run Django from a VM and access it from the host</title>
		<link>http://www.dallagnese.fr/computers-it/run-django-from-a-vm-and-access-it-from-the-host/</link>
		<comments>http://www.dallagnese.fr/computers-it/run-django-from-a-vm-and-access-it-from-the-host/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 03:16:53 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[machine.server.host]]></category>
		<category><![CDATA[virtual]]></category>
		<category><![CDATA[virtual machine]]></category>
		<category><![CDATA[vm]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=846</guid>
		<description><![CDATA[Quick tutorial about how to run a Django server from a Virtual Machine and access it from the host machine.]]></description>
			<content:encoded><![CDATA[<p>If you try to run Django development mode from a Virtual Machine and access the website from the host, you need to specify the global IP address in the "runserver" command.</p>
<p>For example if your VM IP address is 192.168.31.128 (in NAT mode):<br />
<a  target="_blank" href="http://www.dallagnese.fr/wp-content/uploads/2012/02/IP_address_of_the_VM2.png"><img src="http://www.dallagnese.fr/wp-content/uploads/2012/02/IP_address_of_the_VM2.png" width="300" alt="IP_address_of_the_VM" title="IP_address_of_the_VM" class="aligncenter size-full wp-image-856" /></a></p>
<p>You should run the server by calling (you can change the port):</p>
<pre class="brush:bash">python manage.py runserver 192.168.31.128:8000</pre>
<p><a target="_blank" href="http://www.dallagnese.fr/wp-content/uploads/2012/02/Run_server_from_VM.png"><img src="http://www.dallagnese.fr/wp-content/uploads/2012/02/Run_server_from_VM-300x73.png" alt="Run_server_from_VM" title="Run_server_from_VM" width="300" height="73" class="aligncenter size-medium wp-image-854" /></a></p>
<p>Now you need to connect to the website specifying the IP address like that: http://192.168.31.128:8000.</p>
<p>Both from the VM:<br />
<a target="_blank" href="http://www.dallagnese.fr/wp-content/uploads/2012/02/Access_server_in_VM.png"><img src="http://www.dallagnese.fr/wp-content/uploads/2012/02/Access_server_in_VM-300x122.png" alt="Access_server_in_VM" title="Access_server_in_VM" width="300" height="122" class="aligncenter size-medium wp-image-852" /></a></p>
<p>And the Host:<br />
<a target="_blank" href="http://www.dallagnese.fr/wp-content/uploads/2012/02/Access_server_from_host.png"><img src="http://www.dallagnese.fr/wp-content/uploads/2012/02/Access_server_from_host-300x123.png" alt="Access_server_from_host" title="Access_server_from_host" width="300" height="123" class="aligncenter size-medium wp-image-851" /></a></p>
<div class="info">The server running on Linux is much faster than the one running on Windows <img src='http://www.dallagnese.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </div>
				<div id="gallery-6e70e04d" class="flickr-gallery photoset">
													<div class="flickr-thumb">
									<a href="http://flickr.com/photo.gne?id=6814869407"><img class="photo" title="IP_address_of_the_VM" src="http://farm8.static.flickr.com/7011/6814869407_1a50dae350_s.jpg" alt="IP_address_of_the_VM" /></a>
								</div>
															<div class="flickr-thumb">
									<a href="http://flickr.com/photo.gne?id=6814869515"><img class="photo" title="Run_server_from_VM" src="http://farm8.static.flickr.com/7142/6814869515_f4bc5fe8be_s.jpg" alt="Run_server_from_VM" /></a>
								</div>
															<div class="flickr-thumb">
									<a href="http://flickr.com/photo.gne?id=6814869467"><img class="photo" title="Access_server_in_VM" src="http://farm8.static.flickr.com/7161/6814869467_8a593f1749_s.jpg" alt="Access_server_in_VM" /></a>
								</div>
															<div class="flickr-thumb">
									<a href="http://flickr.com/photo.gne?id=6814869289"><img class="photo" title="Access_server_from_host" src="http://farm8.static.flickr.com/7030/6814869289_20b9b50dd5_s.jpg" alt="Access_server_from_host" /></a>
								</div>
												<div class="fg-clear"></div>
				</div>
												<div class="fg-clear"></div>
							<script type="text/javascript">
											jQuery(document).ready(function(){
							jQuery("#gallery-6e70e04d .flickr-thumb img").flightbox({size_callback: get_sizes});
						});
										
										//-->
				</script>
			
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/run-django-from-a-vm-and-access-it-from-the-host/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Package a Python Qt (PySide) application for Windows (.exe)</title>
		<link>http://www.dallagnese.fr/computers-it/empaqueter-un-programme-python-qt-pyside-sous-windows-exe/</link>
		<comments>http://www.dallagnese.fr/computers-it/empaqueter-un-programme-python-qt-pyside-sous-windows-exe/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 13:43:57 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[package]]></category>
		<category><![CDATA[py2exe]]></category>
		<category><![CDATA[PyInstaller]]></category>
		<category><![CDATA[pyside]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=824</guid>
		<description><![CDATA[Setup sample to package a python application using the Qt framework to create a GUI (PySide) using PyInstaller and py2exe.]]></description>
			<content:encoded><![CDATA[<p>That's fairly easy to package a Python Qt (PySide) application for Windows (and even easier on Linux with cxfreeze).</p>
<p>Let see two different ways of doing so.</p>
<p><span id="more-824"></span></p>
<div id="toc_container" class="no_bullets"><p class="toc_title">Contents</p><ul class="toc_list"><li><a href="#1_py2exe">1 1. py2exe</a><ul><li><a href="#Pros">1.1 Pros</a></li><li><a href="#Cons">1.2 Cons</a></li><li><a href="#Download">1.3 Download</a></li><li><a href="#Basic_setup">1.4 Basic setup</a></li><li><a href="#Compile">1.5 Compile</a></li></ul></li><li><a href="#2_PyInstaller">2 2. PyInstaller</a><ul><li><a href="#Pros-2">2.1 Pros</a></li><li><a href="#Cons-2">2.2 Cons</a></li><li><a href="#Download-2">2.3 Download</a></li><li><a href="#PySide_setup">2.4 PySide setup</a></li><li><a href="#Compile-2">2.5 Compile</a></li></ul></li><li><a href="#Postface">3 Postface</a></li></ul></div>
<h2><span id="1_py2exe">1. py2exe</span></h2>
<h3><span id="Pros">Pros</span></h3>
<ul>
<li>Easy</li>
</ul>
<ul>
<li>Support multiple binaries</li>
</ul>
<h3><span id="Cons">Cons</span></h3>
<ul>
<li>Might miss some dependencies</li>
</ul>
<h3><span id="Download">Download</span></h3>
<p style="padding-left: 30px;"><a href="http://www.py2exe.org/" target="_blank">Py2Exe Website</a><br />
There are binaries for both win32 and win64.</p>
<h3><span id="Basic_setup">Basic setup</span></h3>
<p>basic_setup.py</p>
<pre class="brush:python">from distutils.core import setup
import py2exe

setup(
    windows = ['pysideApp1.py','pysideApp2.py'],
    options = {
        "py2exe" : {
            "includes" : ['sys', 'tempfile', 'zipfile', 'mmap', 'encodings',
                          'json', 'hashlib', 'datetime', 'struct',
                          'os', 'time', 'random', 'math', 'xmlrpclib', 'Crypto']
        }
    }
)</pre>
<h3><span id="Compile">Compile</span></h3>
<p><strong>$ python basic_setup.py py2exe</strong></p>
<p>That's it!<br />
Look in your "dist" folder and you should have your application <img src='http://www.dallagnese.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2><span id="2_PyInstaller">2. PyInstaller</span></h2>
<h3><span id="Pros-2">Pros</span></h3>
<ul>
<li>Seems to detect the required libraries much better</li>
</ul>
<h3><span id="Cons-2">Cons</span></h3>
<ul>
<li>Last stable version (1.5.1 as today) does not support multiple binaries</li>
<li>Need a little more config</li>
</ul>
<h3><span id="Download-2">Download</span></h3>
<p style="padding-left: 30px;"><a href="http://www.pyinstaller.org/" target="_blank">PyInstaller Website</a><br />
No need to install, just extract somewhere.</p>
<h3><span id="PySide_setup">PySide setup</span></h3>
<p>pyside.spec</p>
<pre class="brush:python">import os

a = Analysis(
    [os.path.join(HOMEPATH,'support\\_mountzlib.py')
        , os.path.join(HOMEPATH,'support\\useUnicode.py')
        , os.path.normpath(os.path.join(currentDir, 'main.py'))
        , os.path.normpath(os.path.join(currentDir, 'importantLib.py'))
        # add the files you want PyInstaller to analyse the "import" statements
        # to detect the libraries to include
    ],
     pathex=['C:\\Python27\\pyinstaller-1.5.1']
)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=1,
          name=os.path.join('build\\pyi.win32\\build_output', 'your_application.exe'),
          debug=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT( exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name=os.path.join('dist', 'dist_output'))</pre>
<h3><span id="Compile-2">Compile</span></h3>
<p>Move to your pyinstaller.py location and run:<br />
<strong>$ python pyinstaller.py "C:\path\to\pyside.spec"</strong></p>
<p>That's it!<br />
Look in your "dist_output" folder and you should have your application <img src='http://www.dallagnese.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2><span id="Postface">Postface</span></h2>
<p>Both methods work fine.<br />
The output folder with PyInstaller is a little bigger (~10MB, whereas the one with py2exe is ~8MB).<br />
However, it seems to include more libraries, even though I didn't manually specified any specific library, I just gave the 2 main py files of my program, so maybe more reliable.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/empaqueter-un-programme-python-qt-pyside-sous-windows-exe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Install Google Chrome Web Browser in Ubuntu 11.10 Oneiric Ocelot</title>
		<link>http://www.dallagnese.fr/computers-it/english-install-google-chrome-web-browser-in-ubuntu-11-10-oneiric-ocelot/</link>
		<comments>http://www.dallagnese.fr/computers-it/english-install-google-chrome-web-browser-in-ubuntu-11-10-oneiric-ocelot/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 12:29:43 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=816</guid>
		<description><![CDATA[Ubuntu 11.10 final is here! But some of you might be having troubles to install the nonfree google chrome web browser. To install it, just follow the following steps: 1. Download the deb package on http://www.google.com/chrome 2. Open a command prompt and try to install it: sudo dpkg -i google-chrome-stable_current_amd64.deb You will have the following [...]]]></description>
			<content:encoded><![CDATA[<p>Ubuntu 11.10 final is here!</p>
<p>But some of you might be having troubles to install the nonfree google chrome web browser.<br />
To install it, just follow the following steps:</p>
<p><strong>1. Download the deb package on http://www.google.com/chrome<br />
2. Open a command prompt and try to install it: sudo dpkg -i google-chrome-stable_current_amd64.deb</strong></p>
<p>You will have the following <i>normal</i> errors:<br />
<code>Selecting previously deselected package google-chrome-stable.<br />
(Reading database ... 127754 files and directories currently installed.)<br />
Unpacking google-chrome-stable (from .../google-chrome-stable_current_amd64.deb) ...<br />
dpkg: dependency problems prevent configuration of google-chrome-stable:<br />
google-chrome-stable depends on libnspr4-0d (&gt;= 4.7.3-0ubuntu1~); however:<br />
Package libnspr4-0d is not installed.<br />
google-chrome-stable depends on libxss1; however:<br />
Package libxss1 is not installed.<br />
google-chrome-stable depends on libcurl3; however:<br />
Package libcurl3 is not installed.<br />
dpkg: error processing google-chrome-stable (--install):<br />
dependency problems - leaving unconfigured<br />
Processing triggers for gnome-menus ...<br />
Processing triggers for desktop-file-utils ...<br />
Processing triggers for bamfdaemon ...<br />
Rebuilding /usr/share/applications/bamf.index...<br />
Processing triggers for man-db ...<br />
Errors were encountered while processing:<br />
google-chrome-stable</code></p>
<p><strong>3. Now just type the following command: sudo apt-get install -f</strong></p>
<p>And Google Chrome will install!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/english-install-google-chrome-web-browser-in-ubuntu-11-10-oneiric-ocelot/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python Qt4 recipe: QSingleApplication (PySide)</title>
		<link>http://www.dallagnese.fr/computers-it/recette-python-qt4-qsingleapplication-pyside/</link>
		<comments>http://www.dallagnese.fr/computers-it/recette-python-qt4-qsingleapplication-pyside/#comments</comments>
		<pubDate>Tue, 10 May 2011 02:02:35 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[pyside recipe qt]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=792</guid>
		<description><![CDATA[(Français) Simple QSingleApplication class for PySide that allows you to be sure your program will be started only once.
In addition to start the application only once, we can send the arguments of the later calls of your program to the first (and only remaining) instance.]]></description>
			<content:encoded><![CDATA[<p>Thanks to Renato Filho who helped me in <a href="http://developer.qt.nokia.com/forums/viewthread/5733/" target="_blank">this thread on the Qt Forums</a>, I made a simple QSingleApplication class for PySide that allows you to be sure your program will be started only once.</p>
<p>In addition to start the application only once, we can send the arguments of the later calls of your program to the first (and only remaining) instance.</p>
<p>The following video summarizes the features:<br />
<iframe width="425" height="349" src="http://www.youtube.com/embed/pSFEAbNU_hw?rel=0" frameborder="0" allowfullscreen></iframe><br />
<span id="more-792"></span></p>
<p>The idea is to use the QLocalServer / QLocalSocket classes to perform the check and communication between the instances.</p>
<p>First, we create a socket and try to connect to the server, registered with the application name.</p>
<pre class="brush:python">
        self.m_socket = QLocalSocket()
        self.m_socket.connected.connect(self.connectToExistingApp)
        self.m_socket.error.connect(self.startApplication)
        self.m_socket.connectToServer(self.applicationName(), QIODevice.WriteOnly)</pre>
<p>If the connection works, it means a server has already been registered, so the application has already been started and we try to connect to that existing application.<br />
If we the new call has been made with arguments, we send them to the already running application (the first one only in this example, adapt to your needs for all).<br />
If the new call has been made without any arguments, we notice the user that the program is already running and we quit.</p>
<pre class="brush:python">
    def connectToExistingApp(self):
        if len(sys.argv)>1 and sys.argv[1] is not None:
            self.m_socket.write(sys.argv[1])
            self.m_socket.bytesWritten.connect(self.quit)
        else:
            QMessageBox.warning(None, self.tr("Already running"), self.tr("The program is already running."))
            # Quit application in 250 ms
            QTimer.singleShot(250, self.quit)</pre>
<p>If the connection fails, then it means this is the first instance of the application so we start the application and register a server listening to future applications.</p>
<pre class="brush:python">
    def startApplication(self):
        self.m_server = QLocalServer()
        if self.m_server.listen(self.applicationName()):
            self.m_server.newConnection.connect(self.getNewConnection)
            self.mainWindow.show()
        else:
            QMessageBox.critical(None, self.tr("Error"), self.tr("Error listening the socket."))
</pre>
<p>You can retrieve the complete source code at Gitorious: <a target="_blank" href="https://gitorious.org/qsingleapplication/qsingleapplication/blobs/master/qSingleApplication.py">qSingleApplication.py</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/recette-python-qt4-qsingleapplication-pyside/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>20 years of Linux</title>
		<link>http://www.dallagnese.fr/computers-it/les-20-ans-de-linux/</link>
		<comments>http://www.dallagnese.fr/computers-it/les-20-ans-de-linux/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 02:37:38 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[anniversary]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=781</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.linuxfoundation.org/"><img alt="Let celebrate the 20 years of Linux!" src="http://www.linuxfoundation.org/20th/images/lf_linux20_webbadge.png" title="Linux 20 years" class="alignnone" width="300" height="250" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/les-20-ans-de-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python VS Ruby through a concrete GUI example (Qt)</title>
		<link>http://www.dallagnese.fr/computers-it/python-vs-ruby-through-a-concrete-example/</link>
		<comments>http://www.dallagnese.fr/computers-it/python-vs-ruby-through-a-concrete-example/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 00:17:00 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[comparaison]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[pyqt]]></category>
		<category><![CDATA[pyside]]></category>
		<category><![CDATA[rubyqt]]></category>
		<category><![CDATA[vs]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=765</guid>
		<description><![CDATA[Python VS Ruby through a concrete GUI example (Qt)]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.dallagnese.fr/computers-it/programming/python-pyqt4-ou-ruby-rubyqt/">previous post</a>, I was justifying my choice to start learning Ruby instead of Python, and in <a href="http://www.dallagnese.fr/en/computers-it/programming/qtruby-creez-rapidement-des-applications-graphiques-puissantes/">another previous post</a> I was praising QtRuby.</p>
<p>Now it's time to challenge QtRuby (and Ruby in general) with PyQt/PySide (and Python in general).</p>
<p>Due to some reasons, I had to write the same program in both languages.    <br />Thanks to that, I better understood myself the pros and cons of both languages and will try to share my thoughts with you.</p>
<p>A very brief summary would be: Ruby is the winner for programming pleasure and private applications while Python is the winner when it gets serious.    <br />For more information, read the whole post!</p>
</p>
<p><span id="more-765"></span><br />
<div id="toc_container" class="no_bullets"><p class="toc_title">Contents</p><ul class="toc_list"><li><a href="#Background">1 Background</a></li><li><a href="#Switching_to_Python">2 Switching to Python</a></li><li><a href="#Similarities_between_Python_and_Ruby">3 Similarities between Python and Ruby</a><ul><li><a href="#Indentation">3.1 Indentation</a></li><li><a href="#Object_Programming">3.2 Object Programming</a></li><li><a href="#Libraries">3.3 Libraries</a></li></ul></li><li><a href="#Differences_between_Python_and_Ruby">4 Differences between Python and Ruby</a><ul><li><a href="#Pleasure_of_programming">4.1 Pleasure of programming</a></li><li><a href="#The_Blocks_Power_of_Ruby">4.2 The Blocks Power of Ruby</a></li><li><a href="#Definition_of_the_slotssignals">4.3 Definition of the slots/signals</a></li><li><a href="#Easiness_of_distribution">4.4 Easiness of distribution</a></li><li><a href="#Performance">4.5 Performance</a></li></ul></li><li><a href="#Conclusion">5 Conclusion</a></li></ul></div>
<h2><span id="Background">Background</span></h2>
<p>I wanted to write a new GUI program, basically uploading pictures to Twitpic (the real goal is beyond that but let's make it easy).    <br />Being a Ruby fan, I started to write my code in Ruby 1.9 with the &quot;qtbindings&quot; gems.     <br />For my application, I also needed other gems like the &quot;zip/zipfilesystem&quot;, &quot;digest/md5&quot; or &quot;json&quot;.     <br />As always with Ruby, everything went fine and after about 16 hours I had my application working.</p>
</p>
<p><a href="http://www.dallagnese.fr/wp-content/uploads/2011/04/ddl-ruby-settings1.png" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="ddl-ruby-settings" border="0" alt="ddl-ruby-settings" src="http://www.dallagnese.fr/wp-content/uploads/2011/04/ddl-ruby-settings_thumb.png" width="192" height="244" /></a></p>
<p>Came the moment to send the program to beta testers.    <br />To make it simple for them, as not all of them are familiar with programming, I <strong>wanted to bundle the program in an executable</strong> with all the required DLLs, as I used to do in C++ with Qt.</p>
<p>Lucky me, there is something called “<strong>RubyScript2Exe</strong>” (or “AllInOneRuby”) that can do it for you!     <br />Unlucky me, it’s not working at all! It always raises a fatal error, even with the simplest QtRuby script…     <br />A “<em>can’t modify frozen string (RunTimeError)</em>” that many people seem to have and no fix available yet…</p>
<p>Well, there is another one called <strong>OCRA</strong> (One-Click Ruby Application Builder) that looks more serious.     <br />It works with basic QtRuby scripts, but unfortunately not when we require some dependencies, like “zip/zipfilesystem”. It <a href="https://groups.google.com/d/topic/ruby-ocra/q2tGVQYCgU8/discussion" target="_blank">posted</a> on their Google Groups and hopefully a solution will be found, but so far… nothing!</p>
<div class="info"><u>Update:</u> <a href="http://groups.google.com/group/ruby-ocra/browse_thread/thread/ab6b46550602814f" target="_blank">Thanks to Lars</a>, a simple --no-autoload made OCRA work perfectly!<br />
So now I can easily bundle my QtRuby applications too!</div>
<p>That’s good to be able to quickly write programs that do their job, but it’s <strong>very frustrating when you cannot distribute them to others</strong>!     <br />For beta testers, I could tell them to install Ruby 1.9, the required gems, Qt 4.7, and send them directly the source code, but it’s not convenient at all for them, especially if they don’t really have time to waste…</p>
<p>Another solution was to switch to Ruby 1.8 instead of Ruby 1.9 that I was using and hope that it works.    <br />However, I am simply unable to run my code under Ruby 1.8 as the qtbindings are not recognized by Ruby 1.8 (even if of course I install the gem… :s).     <br />I <a href="http://stackoverflow.com/questions/5533233/qtbindings-for-ruby-1-8" target="_blank">posted the problem on stack overflow</a>, and, hopefully I will be able to edit this post and write that I managed to make it work on Ruby 1.8, and, with even a lot of luck, to bundle the QtRuby package with Ruby 1.8!     <br />But for now, trying to bundle my QtRuby application just fails enormously…</p>
<p>So I decided to <strong>re-write the program in Python</strong>, as Python and Ruby are often compared; Python being more accepted among professionals.</p>
<h2><span id="Switching_to_Python">Switching to Python</span></h2>
<p>In Python, there are two different Qt4 bindings: PyQt4 and PySide.    <br />They are very similar, except the licence.     <br />PySide being supported by Nokia (which now owns Qt), I chose <strong>PySide</strong>.</p>
<p>Before anything else, I first tried to compile a very basic PySide program into a binary (an .exe for Windows).    <br />There is a tool called <strong>py2exe</strong> so I tried that one and… it works very well! (Unlike RubyScript2Exe…)     <br />I added some “import” and made some basic calls and… py2exe just worked well.</p>
<p>Accepted! I was ready to write my program again, but in Python!    <br />The good thing is that I already had the “brain” of my program and new how to do it.     <br />I just had to change the syntax from Ruby to Python, which was done quite smoothly.</p>
<p>It took me again about 16 hours to re-write it and add some extra features and error control.</p>
<p>The result is looking just exactly the same:</p>
<p><a href="http://www.dallagnese.fr/wp-content/uploads/2011/04/ddl-python-settings1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="ddl-python-settings" border="0" alt="ddl-python-settings" src="http://www.dallagnese.fr/wp-content/uploads/2011/04/ddl-python-settings_thumb.png" width="186" height="244" /></a></p>
<p>The only differences are because I did not copy <em>exactly</em> the position and size of all the elements…</p>
<p>But the code is very different so let see the differences between Ruby and Python!</p>
<h2><span id="Similarities_between_Python_and_Ruby">Similarities between Python and Ruby</span></h2>
<p>First let’s talk about the similarities.</p>
<h3><span id="Indentation">Indentation</span></h3>
<p>A lot of people talk about the “whitespaces” in Python, that force you to indent your code otherwise Python does not understand it… Honestly, it is so transparent that you just forget it after a while!    <br />I mean, when you write code in C++ or Java or whatever, you indent your code (or your IDE does it for you). It is just so natural that there is just nothing to say about it.     <br />My Ruby code had an indentation of 4 whitespaces, and my Python code too.     <br />I didn’t feel any difference between the two languages as for the indentation…</p>
<h3><span id="Object_Programming">Object Programming</span></h3>
<p>Ruby is 100% object programming, Python… is?    <br />It seems that recent Python is also fully object oriented and I did not feel any problem with “int” or “str” that are well handled in both languages.</p>
<h3><span id="Libraries">Libraries</span></h3>
<p>For the needs of my project, both languages had the required libraries, built-in or through easy to install libraries or gems.    <br />It is said that Python has more libraries, and I am sure it is true, but Ruby is very likely to have enough libraries to meet your needs.</p>
<h2><span id="Differences_between_Python_and_Ruby">Differences between Python and Ruby</span></h2>
<h3><span id="Pleasure_of_programming">Pleasure of programming</span></h3>
<p>The first difference is very subjective.    <br />I enjoy much more writing some Ruby code than Python code.     <br />First of all, I hate the<strong> &quot;:&quot; in Python</strong>… I just find it too ugly (ok, very subjective…).</p>
<p>I also don’t like the fact that you always <strong>need to add the parentheses to the method calls</strong> to really call the method. This is also very subjective again and many people won’t agree and say it’s better to differentiate the <strong>method call and reference</strong>, but I prefer a clean code without parentheses like in Ruby (you still can add the parentheses in Ruby if you want though…).</p>
<p>Then, the keyword <strong>self</strong> in Python: you just have it everywhere!     <br />All the method calls first argument are always “self”, and you always repeat “self” when you call a local class instance variable… Among 391 lines of code, I have <strong>286 times the word “self”</strong> (more than one “self” in some lines of course), that’s too many!     <br />I definitely prefer the <strong>@var</strong> in Ruby that some Pythonists laugh at.</p>
<p>Finally, the Python <strong>__init__, __str__</strong> and other underscored methods/functions…     <br />What the…! No, seriously, someone has to to something for that!     <br />OK, the __str__ function that can change any object (anything?) into a string is very useful.     <br />But please find another name…     <br />For example <em>__init__</em> and <em>__del__</em> are respectively called <em>initialize</em> and <em>define_finalizer</em> in Ruby.     <br />It’s less ugly, isn’t it?</p>
<p>To conclude, it’s just nicer to read and write some Ruby code than Python code (for me!).</p>
<h3><span id="The_Blocks_Power_of_Ruby">The Blocks Power of Ruby</span></h3>
<p>Here we are. The Ruby Blocks ( { } ).    <br />They are just so convenient that once you code with it, you’re addicted!     <br />It is possible to achieve such features in Python too, but it’s definitely better implemented in Ruby where it’s very very easy to use.</p>
<p>Let’s take a concrete example of a Qt signal connection.    <br />In Python you have to pass a function as parameter of the call, even if you only have one action to do when the signal is received.</p>
<p>In Python, you need to define the receiving slot separately (note the “…”):    </p>
<pre class="brush:python">        saveSettingsButton = QtGui.QPushButton('Save Settings')
        saveSettingsButton.clicked.connect(self.saveSettings)
        ...
    @QtCore.Slot()
    def saveSettings(self):
        self.settings.setValue('author',self.author())
        QtGui.QMessageBox.information(self, 'Settings', 'Settings saved!') </pre>
<p>In Ruby, you can just use the blocks to write the action on-click right after: </p>
<p></p>
<pre class="brush:ruby">    # Save settings
    saveSettingsButton = Qt::PushButton.new(tr('Save settings'))
    saveSettingsButton.connect(SIGNAL :clicked) {
        @settings.setValue(&quot;author&quot;, Qt::Variant.new(@author))
        Qt::MessageBox.new(Qt::MessageBox::Information, 'Settings', 'Settings saved!').exec
    }</pre>
<p>When you will perform the action only once, or for very short actions, it is definitely better to write it directly after the connection inside the blocks, like in Ruby.<br />
  <br />It is easier to read and maintain. </p>
<p>For actions to perform that can be use somewhere else in the code by another object, of course it is better to separate it, and Ruby can also do that. But for very short call, this Ruby shortcut using blocks is very convenient! </p>
<h3><span id="Definition_of_the_slotssignals">Definition of the slots/signals</span></h3>
<p>In Python, you need to add a <strong>@QtCore.Slot(type1, type2,…)</strong> before the functions that you want to declare as a slot, like the previous &quot;saveSettings(self)&quot; method. </p>
<p>In Ruby, you can just add one line at the top of your class listing all the slots, like you would do in Qt/C++: slots :saveSettings, :mySlot2, :mySlot3 </p>
<p>Same for the signals with the keyword &quot;signals&quot;, whereas in Python you need to declare the signals at the top of your class, outside __init__</p>
<p>Python:<br />
  </p>
<pre class="brush:python">class myClass(QtCore.QObject):
    errorSignal         = QtCore.Signal(str)
    infoSignal          = QtCore.Signal(str)
    def __init__(self):
        ...
    @QtCore.Slot()
    def saveSettings(self):
        ...
    </pre>
<p>Ruby:<br />
  </p>
<pre class="brush:ruby">class myClass &lt; Qt::Object
  slots :saveSettings
  signals :errorSignal, :infoSignal</pre>
<p>And finally, you can just have no slot at all in Ruby if you add your code when a signal is received inside blocks, like shown in the previous code example!</p>
<h3><span id="Easiness_of_distribution">Easiness of distribution</span></h3>
<p>Yes, both of them are multi-platform, and it is possible to run the same code on Windows, Linux and Mac.<br />
  <br />However, not all the clients want to install Ruby or Python and the required libraries to run the program.</p>
<p>So you need to bundle the application for them, and Python is far better on this point!</p>
<p>I have talked about it in more details in the background introduction as it was the reason why I wrote the same program in both languages.<br />
  <br />Refer to the first part for more details.</p>
<h3><span id="Performance">Performance</span></h3>
<p>I was surprised reading on Internet that Ruby was performing better than Python.<br />
  <br />I don’t know if it’s my computer or not, but for me PySide is performing far better than QtRuby…</p>
<p>The PySide GUI is almost immediately displayed when the program is started whereas the QtRuby GUI takes about 10 seconds to display!</p>
<p>The difference is even bigger when I run the debugger… Python debugger runs very smoothly whereas Ruby debugger is very slow, so slow I can’t use it… (and I used the ruby “fastdebug” :s)</p>
<p>My computer is not recent (an almost 3 years old AMD X2 laptop that rediscovered life when it met an SSD) so I tried on a Quad Core running Windows XP and of course the difference was smaller…<br />
  <br />But on old machines, I beleive the PySide GUI is starting faster than the QtRuby one (and the performance of the program once launched is similar).</p>
<h2><span id="Conclusion">Conclusion</span></h2>
<p>In this article, I have shown the pros and cons of Ruby and Python on my concrete example, with my subjective point of view.<br />
  <br />Yes, I prefer Ruby as a language itself and as I already said, I enjoy much more programming in Ruby than Python.</p>
<p>However, in the real world, for real projects and real clients that want a bundled application that just runs smoothly, I’m afraid Python is better.</p>
<p>It is even far better that after justifying Ruby during all this post, I will continue further development of this program in Python… Because yes, the easiness of distribution is a crucial point in the real world and the differences between Ruby and Python are more about self-pleasure than language features.</p>
<p>I hope Ruby will soon become easier to bundle so I can switch back to my lovely functional blocks!</p>
<div class="notice"><u>Update:</u> <a href="http://groups.google.com/group/ruby-ocra/browse_thread/thread/ab6b46550602814f" target="_blank">Thanks to Lars</a>, a simple --no-autoload made OCRA work perfectly!<br />
So now I can easily bundle my QtRuby applications too!</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/computers-it/python-vs-ruby-through-a-concrete-example/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Reasonable people</title>
		<link>http://www.dallagnese.fr/japan/les-gens-raisonnables/</link>
		<comments>http://www.dallagnese.fr/japan/les-gens-raisonnables/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 15:07:56 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[Japan]]></category>
		<category><![CDATA[chanson]]></category>
		<category><![CDATA[gens]]></category>
		<category><![CDATA[mickey 3d]]></category>
		<category><![CDATA[people]]></category>
		<category><![CDATA[raisonnables]]></category>
		<category><![CDATA[reasonable]]></category>

		<guid isPermaLink="false">http://www.dallagnese.fr/?p=745</guid>
		<description><![CDATA[Japanese people aren't they "reasonable people"?]]></description>
			<content:encoded><![CDATA[<p>"Reasonable people<br />
Never do as they see fit<br />
They don't call anybody wretched<br />
Never get on their nerve in their car<br />
And if ever someone blame them<br />
Even if they know they are right<br />
To avoid the misdemeanour<br />
They apologize or leave"</p>
<p><object width="250" height="150"><param name="movie" value="http://listen.grooveshark.com/widget.swf" /><param name="wmode" value="window" /><param name="allowScriptAccess" value="always" /><param name="flashvars" value="hostname=cowbell.grooveshark.com&#038;songIDs=24339554&#038;style=metal&#038;p=0" /><embed src="http://listen.grooveshark.com/widget.swf" type="application/x-shockwave-flash" width="250" height="150" flashvars="hostname=cowbell.grooveshark.com&#038;songIDs=24339554&#038;style=metal&#038;p=0" allowScriptAccess="always" wmode="window" /><br />
</object></p>
<p>Mickey 3D was in Japan when he wrote this song...?</p>
<p>Listen entirely to appreciate <img src='http://www.dallagnese.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
(in French though...)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dallagnese.fr/japan/les-gens-raisonnables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

