Post archive
virtualenv + virtualenvwrapper
What's a virtualenv and how to manage them easily with virtualenvwrapper.
If you are a python programmer you should know what a virtualenv is. If not, then this is the right place to learn.
What's a virtualenv?
As the name suggests, it is a virtual environment for your python project. In this environment you can install different versions of python packages for different projects without taking risks of messing up with your system's site-packages or other projects!
How to create a virtualenv?
Creating a virtualenv without virtualenvwrapper is possible but no that fun. So for the first step we will be installing virtualenv *and* virtualenvwrapper.
Installing things up
- On Arch GNU/Linux: yaourt -S virtualenv python-virtualenvwrapper
- On other distros or operating systems:
- You'll need to install virtualenv (su -c 'apt-get install python-virtualenv' on Debian based distros or easy_install)
- You'll need to install virtualenvwrapper (you can grab it with easy_install virtualenvwrapper)
After you have virtualenvwrapper installed you'll need to source /usr/bin/virtualenvwrapper.sh in your .bashrc so all bash functions get installed. You can achieve this with the following bash command: echo ". /usr/bin/virtualenvwrapper.sh" >> ~/.bashrc
You will also need to create the .virtualenvs folder where all your environments will live. You can change this folder location by setting the WORKON_HOME environment variable to whatever path you want.
After all that, you have two options: close the terminal and open a new one or execute source ~/.bashrc
Creating and using our first virtualenv with virtualenvwrapper
To create a new virtualenv using our default python version but without its site-packages we execute mkvirtualenv with the --no-site-packages argument. If we wanted to set an specific python version for the environment the -p switch would do the trick (ie: mkvirtualenv -p python2.5).
[fgallina@cuca ~]$ mkvirtualenv myproject --no-site-packages
New python executable in myproject/bin/python
Installing setuptools............done.
Our environment has been created, so now we want to activate it:
[fgallina@cuca ~]$ workon myproject
(myproject)[fgallina@cuca ~]$
Notice how the prompts now starts with (myproject), this indicates the environment has been activated successfully. So there it is, we have our virtual environment. Now let's test it installing some packages on it.
(myproject)[fgallina@cuca ~]$ easy_install PIL simplejson MySQL-Python django
...Lots of logs...
Finished processing dependencies for django
(myproject)[fgallina@cuca ~]$ python
Python 2.6.5 (r265:79063, Apr 1 2010, 05:28:39)
[GCC 4.4.3 20100316 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django; django.VERSION
(1, 2, 0, 'final', 0)
Ok, so we have our packages installed, but what's the status of our main python installation packages? Well they will remain the same as the were before you installed anything on the virtualenv. To check this, let's deactivate the environment we are working on and start a python shell to check the django version our main python installation has.
(myproject)[fgallina@cuca ~]$ deactivate
[fgallina@cuca ~]$ python
Python 2.6.5 (r265:79063, Apr 1 2010, 05:28:39)
[GCC 4.4.3 20100316 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django; django.VERSION
(1, 1, 1, 'final', 0)
Bingo! nothing got broken.
So what's next?
This powerful combination of virtualenv + virtualenvwrapper can be even more cool if you start using pip and requirement files. pip is a drop-in replacement for easy_install and it has some great features, for instance it *can* uninstall packages and read a text file with python package names and versions and install them automatically. I will talk about pip on detail on the next article.
Useful links:
- virtualenvwrapper: http://www.doughellmann.com/projects/virtualenvwrapper/
- pip: http://pip.openplans.org/
closures
A little introduction to shortcuts.
I will take some minutes to post about closures before starting to work :)
What are closures?
Closures are a pretty neat feature you can find in languages like Scheme, Lisp, Ruby, JavaScript and Python (among others).
Closures can many times increase your code readability and cleverness. You'll find examples of use the codes samples below.
To understand what a closure is you need to understand the following concepts:
- first-class objects: objects that can be stored in a variable, passed as argument and/or returned by a function.
- first-class functions: if all the characteristics of the first-class objects apply to a function then it's called first-class function. This is a particularity of the programming language itself and is not up to the programmer to set this. If you come from Java, C, PHP you'll probably find some enlightment regarding closures in this article since in those languages functions are not first-class objects (c'mon don't come up with crazy pointer stuff).
- free variable: is a variable that can be accessed from a function but this variable is not an argument or a local variable of that function.
- lexical binding: all variables are contained in their respective environment (code block) instead of being available globally (dynamic binding).
With the definitions above, then we can define a closure as:
A lexical binded first class function which can access free variables.
I know that line probably didn't helped that much. So let's go to the...
Code examples
The most common example for a closure seems to be a counter, so lets do it with Python:
def counter(start):
# we are setting the variable start as a counter function property
# because if we don't do that `start` will be placed in the local
# scope of incr after incrementing its value.
counter.start = start
def incr():
counter.start += 1
return counter.start
return incr
# this binds the closure function incr to the c variable so we can
# call it later. Of course, before that, this will also set the
# counter.start variable to 10 but nothing else will happen as desired
c = counter(10)
print c() # will print 11
print c() # will print 12
print c() # will print 13
Here is a better real life example in JavaScript.
Let's say we want to print out the order of the links contained in a list when they are clicked (yes, I'm using jQuery in the example ;).
The first thing you'd probably try is:
var links = $('li a'); // gets all <a> elements contained in a <li>
for(var index=0; index < links.length; index++) {
// $() extends the element so the click function is available.
// $().click() allows us to bind the onClick event.
$(links[index]).click(function(event) {
alert(index);
return false
});
}
This will fail! After you click an element it will print the value of index, but its value will be the latest it got in the for loop. In this case, we have a closure (the index variable is accessed via lexical binding) but is not working as expected.
The solution for this would be rebinding each value of index in an inner lexical scope and then add the closure inside that scope. This way, the closure will be looking to that inner value of index instead of the latest state of the for loop.
var links = $('li a');
var closure = function(i) {
return function(event) {
alert(i);
}
}
for(var i=0; i < links.length; i++) {
event_handler = closure(i);
$(links[i]).click(event_handler);
}
And there we go! Now it's working as we wished. However that was just for the sake of a detailed example. The best way of doing it with jQuery will be using each like this:
var links = $('li a');
links.each(function(index) {
$(this).click(function(event) {
alert(index);
return false
});
})
Which remains on-topic because the index is accessed by the click event handler thanks to lexical binding.
Conclusions
Closures are a great language feature, they can be used for many purposes (even for a kind of poor man's object oriented programming). I'd recommend you to play with them a little to understand them better.
Optimizing your mootools application using Sizzle!
How to put Sizzle in place of mootools' selectors so you have an instant javascript application speed up!
A little introduction
Some weeks ago I had to improve performance of a really neat mootools based javascript application at work. I'll probably will post later about some common javascript optimizations, however the really *huge* speed boost was to replace mootools' selector machinery with Sizzle.
Sizzle is a CSS selector engine you can use standalone in any application, and you've probably used it before without noticing it: it's the corner stone of jQuery's selectors.
You've probably heard also about the posiblity of replacing mootools selectors before and that improvements are not that relevant. Well, let me disagree with that, I'm not a blind fan, I recognize I like jQuery the most over mootools but I also see things with non-partial eyes. In this case I tried it not because I like jQuery but because I just wanted to get the job done
Sizzlefying mootools
Integrating Sizzle into mootools turned out to be pretty simple, this snippet will do the trick:
Native.implement([Document, Element], {
getElements: function(expression, nocash) {
return new Elements(
new Sizzle(expression, this),
{ddup: (expression.length > 1), cash: !nocash}
);
}
})
Code explanation
The explanation of the code is pretty straightforward, what we are doing here is to replace the getElements method of Document and Element with our Sizzlefied version of it.
The first thing to take care about is to leave the API intact so everything will continue to work (if it was working ;), that means we will respect all arguments, that's why the nocash argument is there:
...
getElements: function(expression, nocash) {
...
Now for the fun part, let me say that the first argument for Sizzle is the selector expression (ie: "input.save") and the second is the context, we are using the javascript keyword this to pass the Document or Element that's calling the function.
...
new Sizzle(expression, this),
...
Sizzle will then return all DOM elements matching the selector, but there's a detail, none of these elements will contain the mootools extensions. That leads us to the problem: if someone tries element.setStyle('display', 'none') will not work, and as we said before, we want to leave the API working as it was, so old code continues doing its magic without new problems :). The solution for this is to use the Elements class. It takes an array of DOM elements and extends them with mootools' magic.
The ddup option indicates if Elements should remove duplicates, and we are setting it to "yes, if we have more than one element in the array".
The cash option is set to !nocash. nocash is normally is undefined and !undefined is true. If the cash option is true, then elements will be extended with mootools' magic (which is what we want)
...
return new Elements(
new Sizzle(expression, this),
{ddup: (expression.length > 1), cash: !nocash}
);
...
And that's it.
Benchmarks (Firefox 3.6)!
Here are some numbers, consider each Transaction as a table row, where each row have a click event handler that turns it into editable (of course, everything is very much complex than that).
# Click after load on a test account with 13 Transactions
Standard Mootools: Time: 1819.709ms, function calls: 348897
Sizzledfied mootools: Time: 208.859ms, function calls: 12832
# Click after checkregister load on a test account with 163 Transactions
Standard Mootools: Time: 7184.338ms, function calls: 1179935
Sizzledfied mootools: Time: 780.623ms, function calls: 18156
# Fresh load on a test account with 335 Transactions
Standard Mootools: Time: 13178.882ms, function calls: 2243445
Sizzledfy mootools: Time: 1261.888ms, function calls: 50086
Final note
This shouldn't start a Javascript Framework War, I'm not saying mootools sucks. This is just what worked for me and I hope it will work for you too :)
A volverlaaa
Vuelve, vuelve como Perón...
Finalmente después de largo rato de inactividad me tomé el tiempo para arreglar los detalles que no me conformaban del sitio y me dieron ganas de escribir de nuevo. Esto básicamente quiere decir que re-inauguro este blog.
Volveré dentro de poco con alguna de las tantas cosas que fui acumulando desde Octubre del año pasado :)
Charla introductoria a python en el Instituto Politécnico
Miércoles 14 de Octubre a partir de las 21
Organizado por el LUGRo (Grupo de Usuarios de GNU/Linux Rosario) el día Miércoles 14 de Octubre a partir de las 21 horas se llevará a cabo la charla INTRODUCCIÓN A PYTHON a cargo de Fabian Gallina en el aula 1-14 del Instituto Politécnico Superior de calle Pellegrini 250.

Entrada libre y gratuita
Conexión clandestina del terror @ Montevideo
Sí, nos deschavetamos un poco, pero no se puede estar tantas horas sin wifi
Ya estamos en Montevideo con Seba, tenemos que esperar hasta las 19 para abordar el avión que finalmente nos llevará a Santiado de Chile.
Mientras tanto nos hemos armado una conexión clandestina para poder conectar nuestras notebooks y apacigar el nerdismo desaforado que genera el encierro prolongado.

A saber: los alargues nunca están de más.

El cable está ordenadamente escondido debajo de la silla de Seba.

Seba con cara de "hemos trinfado" y cuca (derecha) agradeciendo su nueva fuente de energía.

Mac Guiver, morite de envidia.
Going to Chile
On my way to las Jornadas Regionales de Software Libre in Chile
Because of the Regional Free Software Conference I'm travelling to Chile with Seba who will give a presentation about the LUGRo-Mesh Project.
I did my homework and watched Turbulence 1 and 2, and other airplane crash movies, I promess to bring pisco for everyone if we survive the four travels we need to make, yes they are four becase the airplane makes a stop in... Montevideo (as good Nerds we decided to increment our posibilities of being in an Airplane Crash than paying more :P)
See you all.
pa' Chile me voy
Por motivos de las Jornadas Regionales de Software Libre 2009, voy a estar viajando este martes a Chile junto con Seba (quien va a estar dando una presentación sobre el LUGRo-Mesh).
Ya hice las tareas y me vi Viven y Turbulencia 1 y 2, entre otras películas de catástrofes de aviones, prometo traer pisco si es que sobrevivimos a los 4 viajes, son 4 porque el avión hace escala en... Montevideo. Como buenos nerds de bajos recursos económicos consideramos preferible incrementar las posibilidades de morir que pagar más :).
Nos vemos a la vuelta.
1,5 minutes of fame
A little interview about the Software Freedom Day event in Rosario organized by LUGRo
Because of the Software Freedom Day Rosario 2009, I did a TV interview on a local channel. Now I'm shaved so take that into account when looking at me for an autograph :P
1.5 minutos de fama
Por motivo del SFD Rosario 2009, me hicieron una nota en la televisión local. Ahora estoy afeitado, tenganlo en cuenta al momento de buscarme para pedirme un autógrafo :P