Monday, December 31, 2012

Python and RaspberryPi in 2012


This year, just looking at what is directly relevant to this blog, it hasn't been a bad year at all on the Python and Raspberry Pi front, considering I do this in my free (where? when?) time, outside of running an IT department, a company, a household, and helping in my community...

  • mentored a few individuals
  • a lightning talk at PyCarolinas
  • a full length talk at PyCarolinas
  • Got a whole team to embrace Python
  • started PYPTUG, The PYthon Piedmont Triad User Group
  • started PYPTUG PyHack Workshops @ Fablocker
  • organized PYPTUG meetings
  • over 250 posts on Raspberry Pi forum
  • started this blog (over 56,000 visitors in last 4 months)
  • over 120 blog articles in 4 languages
  • published a few repositories on Bitbucket
  • translated and proofread part of The Mag Pi magazine (in French)
That is a lot. And I plan to continue. Plus I contributed to a very very cool project, Brython (a Welsh word for a Breton, someone originating from the region of Brittany in France). Brython is Python scripting in your web browser.

Personally, I think this is a very important project for the Python community, and I put my money where my mouth is by investing my own time on this:
  • english translation
  • spanish translation
  • spanish group (brython-es on google group)
  • writing a few demos
  • writing a few articles
  • testing functionality
  • sending bug reports
  • fixing stuff
  • some public relation and promo
Of course, this pale in comparison to the amount of time that Brython's creator Pierre Quentel has spent on it. I encourage my readers to get involved in that project and make it a success in 2013.


In 2013, I would like to see dtrace (one of the most important technology of the last 15 years) bundled with Python on all platform that support it (the BSDs, Mac OS/X, Solaris and IllumOS based like OpenIndiana). The patch has existed for a long time, so it is not a technical issue. We will see if politics can be set aside and the patch be mainstreamed. I do owe some people from OpenIndiana some work on the regular Python 2.7.x, but quite frankly I am less than enthused to work on this without making dtrace (Jesus Cea's patches) part of it.

How about IllumOS on the Rasberry Pi? The time is right, with the 512MB Pi now being the norm. There is some background noise already on this, so I'm hoping we can get this thing going.

Finally, I'd like to see the disaster of 2012 (Ten's Complement Zevo zfs file system sandbagged) get reversed, and ZFS be brought back to Mac OS/X. That is probably most unlikely, since Apple are not interested in trailblazing anymore. HFS+ in 2013, really? really?


Le magazine Mag Pi (RaspberryPi)

Le Mag Pi 

Vous connaissez?

En Anglais

C'est un magazine en format PDF, qui se specialise sur le Raspberry Pi. Ce qui est bien avec celui-ci c'est qu'il couvre le materiel et le logiciel, et la programmation en differents langages, allant de C a Python.

Mais il est en anglais, me direz-vous. Oui, c'est bien le cas. Mais il existe aussi un travail de traduction en francais et espagnol.

Pour les versions en francais:

Pour le moment, seul le numero 5 est complet:


RaspberryPi: 2 bit H bridge

4 bit H Bridge

two modes, motor turning in different directions
A typical H bridge is what is required to drive a regular DC motor in both directions. The diagram above clearly shows how to accomplish this with 4 switches. But manipulating 4 switches is a pain, so we control this with transistors (in my case, 4 very common 2N2222 NPN transistors). However, although there appear to be only two modes, with 4 switches, or 4 bits, there are a lot more variations:

From the wikipedia article:

S1 S2 S3 S4 Result
1 0 0 1 Motor moves right
0 1 1 0 Motor moves left
0 0 0 0 Motor free runs
0 1 0 1 Motor brakes
1 0 1 0 Motor brakes
1 1 0 0 Shoot-through
0 0 1 1 Shoot-through
1 1 1 1 Shoot-through

The last 3 are to be avoided, since they short the power supply. This would be controlled by 4 GPIO pins. But there is a better solution (even though the name might not be appealing...):

2 bit H Bridge

For the PyHack workshop at the beginning of december, we controlled some gearhead motors (and a bunch other stuff) with the Raspberry Pi:

The main thing with these motors is that they are regular DC motors and can be run from two wires. But to reverse them, we need an H bridge. But why use up 4 GPIO, if all we want is to have the motor turn right, turn left or free run?

All we have to do is connect S1 to S4 and S2 to S3, and use 2 GPIOs to drive S1 and S2. On a breadboard, it looks like this:

closeup of the h bridge, right in the middle

4 different circuits: darlington array, direct, single and H Bridge

We are using pins 4 and 23 to control S1 and S2.

 The code

#!/usr/bin/env python

import RPi.GPIO as gpio
from time import sleep

# set the mapping mode for the GPIO numbering

# DC Motor connected to pin 4

gpio.setup(MOTORA, gpio.OUT)
gpio.setup(MOTORB, gpio.OUT)


# Bring it to 3V3 (HIGH)
gpio.output(MOTORA, gpio.LOW)
gpio.output(MOTORB, gpio.HIGH)

print("it is on")
gpio.output(MOTORB, gpio.LOW)
gpio.output(MOTORA, gpio.HIGH)

print("it is reversed")


I'm working on a way to publish diagrams and breadboard layouts, I should publish it along with a bill of material in a few days.

Update!: see the followup "Fritzing with Brython"

Listas y foros RaspberryPi Python en espanol

Has recibido su Raspberry Pi? Sigues mi blog, obviamente :) pero también hay listas y foros que te ayudaras. Mi preferencia es por listas, porque los foros no permiten una interacción rápidita como el coreo electrónico.

Hay twitter que en teoría debería ser aun mas rápido, pero es imposible tener una conversación técnica allá. A caso, soy @f_dion


Raspberry Pi

Un mes atras, empezó una lista sobre el Raspberry Pi en espanol. Es regional (Argentina), pero todos son bienvenidos:



Varios anos atrás (al minimo desde 2001 a ver los archivos) empezó la lista de python en castellano (disponible también como foro en Google Groups):


Hay una lista regional (Argentina), y todos son bienvenidos:


Voy a mencionar mi lista de Brython en español (Python en navegadores):



Quizas no hay una lista especifica a Raspbian en español, pero hay:



Raspberry Pi

El foro oficial de la fundación Raspberry Pi en español es:

Un otro foro por el Raspberry Pi es:


Como stackoverflow, pero en español:

Hay también la sección Python de solocodigo:

Los siguientes son foros Google Groups, y en ciertos casos se puede recibir por medio de correo electrónico también:

Foro regional de Madrid, España: python-madrid

Foro regional de Sevilla, Espana: python-sevilla

Foro regional de Perú: python-peru

Foro regional de Venezuela: python-venezuela

Foro regional de Uruguay: forum/pyuy

Foro Python scientifico de Argentina: forum/sci-pyar


Sunday, December 30, 2012

Python raspberrypi ICU

Finally completed some stuff I had on my todo list for a few weeks now, so I can get back into the PyHack workshops.


Intensive care unit? Intensive computing unit? nope. I see you. For the next PYPTUG PyHack workshop, we are going to see how we can put to good use some webcams along with our Raspberry Pi.


Along with the Pi and the webcam, we will be using Python and pygame. That's the main portion of the workshop, but we'll also use a phone, a web server and a web framework on top of that. To do what? You'll have to be there...


January 12 2013, 3PM @ Fablocker in Winston Salem

That'll be a busy week since I'm also doing a presentation on the Raspberry Pi on the 9th, also in Winston Salem. More on this later.

Thursday, December 27, 2012

UTF-8, les accents et Python

Python 2

Avec Python 2.x (2.7.x sur Raspberry Pi), on peux utiliser les caractères accentués directement dans nos chaines de caractères. Par exemple:

machaine = u"je suis bien étonné, François!"

Le u devant la chaine indique que c'est en unicode.


En plus de cela, il faut indiquer a l’éditeur l'encodage (car on n'utilise pas des valeurs hexa ou octales, mais bien les caractères eux-mêmes). On peut utiliser un encodage latin-1, ISO-8859 ou un autre qui semble émerger comme le plus courant: UTF-8.

Pour declarer cela dans notre fichier Python, il faudra commencer avec:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#!/usr/bin/env python
# vim: set fileencoding=utf-8

selon que l'on prefere la syntaxe emacs ou vim :)

Python 3

Avec Python 3.x, les chaines sont toutes Unicode, et donc plus besoin de mettre un u devant les chaines. Toutefois, il faut encore et toujours declarer notre encodage, comme ci dessus.


Et avec Python pour les navigateurs web (Brython)? Brython suis la syntaxe de Python 3, et donc on peut declarer une chaine Unicode, sans u:

Dans ce cas ci, l'alphabet russe. Mais pas dans l'ordre naturel. Je l'ai mis ici dans l'ordre de l'alphabet latin, de façon phonétique.

Et l'encodage lui? On le fera a l'exterieur du script Python. On l'indique par l'entremise de HTML et meta:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Un éditeur HTML (genre Bluefish) va savoir quel encodage utiliser, et idem pour le navigateur web qui recevra cela.

Si vous etes curieux, voila le lien (ruskey.html) et le code de mon petit test de clavier phonétique pour le cyrillique (russe):

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="/brython.js"></script>
<body onload="brython()">
<h1>Phonetic cyrillic on QWERTY keyboard</h1>
Here is a little test, mapping latin characters on a keyboard to their phonetically equivalent characters in a cyrillic script, as used in Russian.
This demoes UTF-8 unicode, handling of keyboard events, and adding, modifying and deleting elements from the tree.
<script type="text/python">

Phonetic ordering of cyrillic (фонетических упорядочение кириллицу)
We are matching the latin alphabet, uppercase, then lowercase

CYR =  'АБЦДЕФГЧИЙКЛМНОПЯРСТУВЖХЫЗШЩЭЮЁЬЪабцдефгчийклмнопярстувжхызшщэюёьъ'
position = 0

def printkey(letter):
    global position
        span = doc[str(position)]
        span.value = letter
    except KeyError:
        doc <= SPAN(letter, id = str(position))
    position += 1

def deletekey():
    global position
    position -= 1
    if position < 0:
        position = 0
        del doc[str(position)]

def keydown(e):
    if not e:
        e = win.event
    key = e.keyCode
    offset = 65 if e.shiftKey else 32
    if key == 8:
    elif key == 32:
        printkey(' ')
    elif key in range(48, 58):
        printkey(str(key - 48))
    elif key >= offset:
        printkey(CYR[key - offset])

def keyup(e):
    if not e:
        e = win.event

def drawkeyboard():
    table = TABLE()
    row = TR()
    for letter in CYR:
        row <= TD(BUTTON(letter, onClick= "printkey('%s')" % letter))
        if letter in ('Я','Ъ','я'):
            table <= row
    table <= row
    doc <= table

# Draw keyboard and set key events

doc.onkeydown = keydown
doc.onkeyup = keyup

<br />
Click buttons or type on keyboard:
<br />

print() and win.print()

Python vs Brython vs Javacript

Before Python 3, print was a keyword, and not a function. With Python 3, print() is a built-in function.

Brython follows the syntax of Python 3, so one would expect a print() function. However that since its inception, it has been suggested that print() didn't make sense in the context of a web browser, and to use log() instead. win.print() was the call to the window.print() Javascript equivalent:

Javascript has a print() function too. It is actually a method of window, and brings up a print dialog to print a web page from a web browser.

The lightbulb moment

I didn't see it coming, but as Pierre was working with the Brython demo console (and I'm guessing from feedback from people who got confused by it) and thought that perhaps print() wasn't such a bad idea after all.

And here's what he came up with:
- for standard output there was a Brython-specific builtin function log() : it is now replaced by the usual Python function print(), with the syntax used in Python 3, including the keyword argument "end"
By default, print() sends its arguments to the browser console. This can be changed by setting sys.stdout to an object with a method write(). For instance, in the online console, to send the output to the textarea with the id "console" the code is (remember that classes are not implemented yet...)

import sys
sys.stdout = object()
def write(data):
    doc["console"].value += data
sys.stdout.write = write

Errors can also be redirected using sys.stderr

sys.stderr = object()
sys.stderr.write = write

But what about the javascript functionality of print(), did we loose that at the same time?

Thankfully, Pierre didn't hardwire conversion of keywords without keeping in mind the scope, and that means that the following works:

<!DOCTYPE html>
        <title>Brython test</title>
        <script src="brython.js"></script>
    <body onLoad="brython()">
        <script type="text/python">
        def printandprint():

        doc <= BUTTON('Print and print', onClick='printandprint()')

You'll see in your debug console the word hello printed through print("hello"), and a print dialog will open when win.print() is called.

Try it:

Python e xadrez

Esta é uma peça de xadrez bonito. É um gladiador romano:

Este não é tão bonito, mas o seu objectivo é muito claro, é um peão:

Quando os amigos vêm e querem jogar xadrez, eles tendem a escolher o jogo de xadrez romana. Todos são jogadores casuais. Aqueles que jogar em um nível mais alto escolher o jogo de xadrez com peças de madeira.

Há uma razão que usar esse tipo de peça (de madeira) de xadrez ao jogar. São concebidos para ser óbvio, e não distrair do objetivo, que é jogar xadrez.


Eu tive uma conversa com um amigo sobre isso, e eu percebi que eu gosto de Python, pela mesma razão. Python não fica em seu caminho de seu objetivo principal, que é a de escrever um programa.

{} $ => end

Variáveis ​​não deve ter uma delimitado $, blocos não deve ser por {} ou concluído até end. Essas coisas encontradas em outras linguagens me distrai visualmente.

Conheço Java, Javascript e C++ por muitos mais anos do que Python (e uma boa experiência com Perl, PHP, Ruby, Pascal, Basic, Assembler etc), e eu tenho vivido com estas coisas por um longo tempo. Mas, assim como com peças de xadrez limpos e simples que me permite ver e entender o jogo em um piscar de olhos, agora eu vejo uma sintaxe limpa e simples que me permite ver e entender o código em um piscar de olhos.

Monday, December 24, 2012

Geolocation with Brython

Brython keywords

We used the doc keyword previously, in another article. How about using the win keyword this time? How about something for mobile apps?


To access geolocation services in your web browser, in Javascript you need to use the methods of window.navigator.geolocation. That means win.navigator.geolocation in Brython.

I'm lazy, so i'll assign it once:

geo = win.navigator.geolocation

Next I'll define a callback function for success and error:

def navi(pos):
    log('Position acquired')
    xyz = pos.coords
    display = "Your position: %f,%f" % (xyz.latitude, xyz.longitude)

def nonavi(error):

Alright, now we are ready to actually try to get a position:

if geo:
    geo.getCurrentPosition(navi, nonavi)
    alert('geolocation not supported')

Full code

It is pretty straightforward:

<!DOCTYPE html>
        <title>Brython test</title>
        <script src="brython.js"></script>
    <body onLoad="brython()">
        <script type="text/python">
        geo = win.navigator.geolocation

        def navi(pos):
            log('Position acquired')
            xyz = pos.coords
            display = "Your position: %f,%f" % (xyz.latitude, xyz.longitude)

        def nonavi(error):

        if geo:
            geo.getCurrentPosition(navi, nonavi)
            alert('geolocation not supported')

Friday, December 21, 2012

Python List comprehensions now in Brython

Brython improvements

So by now, you've heard of Brython, the implementation of Python 3 (or at least a subset) for your web browser, in Javascript. After all, I've been talking about it for almost a month now (although not in english).

New this week

Pierre has been busy... He implemented the ternary operator, that is, a way to assign one of two values, based on a condition, for example:

x = 7 if a > 2 else 17
List comprehensions are also in! This was a heavily requested feature that was missing from Brython, for example:

y = [ x ** 2 for x in range(10)]
 I did find a bug in some variations, and am looking into the code to fix this.

Another addition this week is that your python code indentation is now relative to the first line of your script, instead of having to start at the first position. That means you can now format your html code and have your Python properly aligned:

<!DOCTYPE html>
        <title>Brython test</title>
        <script src="brython.js"></script>
    <body onLoad="brython()">
        <script type="text/python">
        def myfunc():
            return True


instead of:
        <script type="text/python">
def myfunc():
    return True


Mode de demarrage du Raspberry Pi

Mode texte

C'est ce qu'il fait automatiquement avec Raspbian, et on a une invite pour se connecter comme usager pi. On peut aussi automatiser la connection avec un login automatique.

Login automatique

On peut aussi se connecter a la console de façon automatique, en éditant le fichier /etc/inittab:

pi@raspberrypi ~ $ sudo vi /etc/inittab

Et en ajoutant la ligne en emphase (et ajoutant un # au debut la ligne précédente pour mettre en commentaire):

1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1
On remplace pi par l'usager que l'on veut (après l'avoir créé)

Mode Python

Plutôt que de démarrer en console bash, on peut aussi démarrer directement dans l’interpréteur  Python, ou encore mieux, ipython. ipython remplace bel et bien bash, et bien plus encore.

Ici, pas besoin d'etre root (pas de sudo), on edite notre propre .profile:

pi@raspberrypi ~ $ cd
pi@raspberrypi ~ $ vi .profile

Comme derniere ligne, on ajoute:


On pourra aussi démarrer un autre programme a la place de ipython, comme dosbox, un menu pour MAME ou autre et ainsi spécialiser notre Raspberry Pi.

Mode graphique

Pour demarrer automatiquement sous LXDE plutot qu'en console texte, il faut faire une configuration avec raspi-config:

pi@raspberrypi ~ $ sudo raspi-config
choisir boot behaviour

choisir yes (oui) pour environnement graphique
Si on veux revenir au mode console, on lance raspi-config, boot behaviour, No (non).

Sunday, December 16, 2012

Python en todo lugar

Ordenadores, móvil, navegadores

Empecé a programar ordenadores con el lenguaje Basic y Turtle (Logo) y poco después con Assembler, Pascal, C, C++ y un montón de otros lenguajes. En los anos 90, seguí con Perl, Java y Javascript (y varios otros a través los años como PHP, C#, Python, Ruby).

La mayoría del código que estoy escribiendo ahora es en Python, pero cuando es una cuestión de web, siempre hay que hacer algo en Javascript. Casi todas las paginas en la red incluyen <script...>.


En el pasado (mas de 10 anos atrás) era común ver <script type="text/vbscript"> (vbscript es una forma de visual basic), pero como solo Internet Explorer ofrece eso, no se ve mucho. Si hacemos algo que opera con todos los navegadores, debemos utilizar <script type="text/javascript">.

Ah, si tan sólo pudiéramos utilizar Python aquí también, del lado del navegador. Un lenguaje en todo lugares y todos los navegadores.

Si era posible...

Debería ser similar a la manera que uno puede usar Javascript. Una pagina html muy sencilla como la siguiente:

<script type="text/python">
def hola(nombre = "todo el mundo"):
    alert( "hola, " + str(nombre))  # numeros o caracteres

<input type=button onclick="hola()" value="mundo!"> 
<input type=button onclick="hola('queridos lectores')" value="click!">

Incluso sin requerir un servidor. Sería bastante bien.

Si, ¡Es posible!

Hay dos cosas mas que debemos hacer, y funcionara:

<head><script src="brython.js"></script></head>
<body onload="brython()">
<script type="text/python">
def hola(nombre = "todo el mundo"):
    alert( "hola, " + str(nombre))  # numeros o caracteres


<input type=button onclick="hola()" value="mundo!">
<input type=button onclick="hola('queridos lectores')" value="click!">

Y, si estas leyendo mi sitio directamente en un ordenador o ipad (o similar), puedes probarlo (voy a añadir brython en mi sitio para móvil en unas semanas):

¡Demasiado! Es cierto.


Lo que hace eso posible es Brython:

Brython es un proyecto que tiene por objeto sustituir Python a Javascript en los navegadores web. Pierre Quentel annuncio el proyecto en el grupo fr.comp.lang.python ( annuncio en francés ) el 25 de noviembre.

De inmediato fue muy obvio para mi de que era lo que estaba buscando. Como he encontrado algunos problemas, los envió a Pierre, y él los corregía rápidamente. Le ayudo también con la traducción del sitio de francés a ingles:

Ahora, estoy trabajando a traducir el sitio (toda la documentación) en español (y buscando ayuda).

No hay documentacion en español, pero hay una lista en español , un grupo google:!forum/brython-es

Hay grupos google en ingles (brython) y frances (brython-fr) también.


A veces una imagen vale mil palabras, o, en este caso, un sitio de demo:

reloj analógico
técnica 'arrastrar y soltar'
almacenamiento local
laberinto 3d

Haga un clic con el botón derecho para ver el código de cada demo. Python. Deja uno sin palabras, ¿verdad?


Thursday, December 13, 2012

Brython: Browser Python

100th post

Wow, already the 100th article on the Raspberry Pi Python Adventure blog. I didn't think I'd get there that quick when I started it back in august. Still, if I could type 10x faster, I'd be talking about my 1000th post... It's a race you can never win, and that's too bad.

Fibonacci again

If you've been following the blog for at least a month, you've seen various mentions of Fibonacci numbers. It is a sort of mathematical Hello World for me. I can demo all kinds of Python related things (modules, techniques etc) with them.


I've shown how to print the Fibonacci numbers, to have the Pi speak them and to draw them (even into something that looked like flowers). But you've not seen me do the following before, python in your browser :

So, what do we have here? A textbox with some code, and if you are reading this on my website, you should be seeing the result in a yellow box, below the grey box.

If you are getting this through email or RSS, you probably wont see the result (and it is not yet on my mobile version of the site, either). I see you are a bit puzzled by what is going on... Is this for real? I see you reaching for the view page source already, but stick with me for a little while longer.

The code

Everything in the main section looks like the first Fibonacci script I had posted, that is, with the exception that print() has been replaced with webprint(). And what is webprint()? It is a function I define, and it has only 1 line:

doc['result'] <= str(x) + BR()

If you are thinking, that is just unusual for Python, then you are right. How can a boolean value print, and what is BR()?

We are looking at Python code, but with certain adaptations, due to how web browsers works:

An HTML page is seen as a tree whose root node is represented by the tag doc. And doc['result] is a node with an id named result (in our case, a <td></td> section for the results).

Subsequent nodes are either built-in Python objects or objects created by the functions corresponding to their HTML tag. In this case BR() corresponds to <BR />.

And the <= is not a lesser or equal comparison, it is a special assignment to add a child node.

I am thus sending a string representation to the browser's document item with an id of 'result', and creating a linefeed with <br />

This browser specific implementation of Python is called Brython.


Back in November, I posted a blog article about Brython (Utopie Python ou realite), but quite a few readers probably missed the significance of this, the reason being that the article was in French.

I didn't post it in English, because Pierre Quentel, the creator of Brython, wanted to first get some feedback from a smaller community before a more widespread distribution.

I saw the potential right away, and started experimenting with it. As I found issues, I sent them to Pierre, and he corrected them. I'm not sure if he sleeps at all...

The other thing that prevented a widespread release was the lack of documentation in English.  So I gave Pierre a hand, and the documentation is now fully translated. I got to learn a lot about the internals of Brython in the process.

So, what is it?

Like I said, Brython is a browser specific implementation of Python (Python 3 syntax). At this time, the main features it lacks are list comprehensions, the ternary operator and classes.

Quoting the author:
"HTML5 brings a new potential to web applications on all platforms : PCs, smartphones, tablets, TV etc
At the moment, only Javascript is supported for local client programming. The objective of Brython is to be able to use Python instead of Javascript"

It supports Ajax, HTML5 canvas, local storage, embedded audio and video. It also has alert(), confirm() and prompt(), which should be familiar to those using Javascript. And there is ton more stuff.

How does it work?

How can this work, how can we put Python code in a web page and it runs? That is because Brython takes the Python code and converts it on the fly to Javascript code, and then runs that. Everything runs in your web browser. There is nothing running on my server.

You can see the code it generates by accessing the online console on the official site.

How do I use it?

That is really the beauty of Brython, how to use it. It is not an online console or tutor helper, it is a mechanism to use:

<script type="text/python">
python code goes here

instead of type="text/javascript".

For this to work (until that is the day where browsers support this natively), we have to include brython itself: brython.js

And then run it when the page loads, through the <body> tag like this:

<body onLoad='brython()'>

Show me more!

On the brython site, you'll find quite a few interesting demos in the gallery, including these HTML5 canvas and local storage demos:

analog clock
drag and drop
local storage

I'll be starting to post some code in interactive mode, using Brython, so keep an eye on the blog!


Brython is brand new, but already it is quite usable. I think it will take off and become a fairly important project in the long term. No doubt, you'll want to keep an eye on it.

The website for Brython is

The English documentation:

The google code page:

The english google group:!forum/brython

Questions? Just leave a comment!


Wednesday, December 12, 2012

Comment Python assigne les "variables"

Dans le deuxième tutoriel, je parle de variables et d'assignations (ou d'affectations pour les lecteurs du vieux continent). Bien que ces termes sont utiles pour décrire une ligne de code Python comme:

a = 4

strictement parlant, a n'est pas une variable comme on l'entends au même titre qu'avec un langage comme C ou C++ et l’opérateur d'assignation (=), lui, et bien, vous allez voir. Je vais couvrir ici de l'information supplémentaire, pour ceux qui aiment comprendre dans le détail. Même si vous débutez a peine, c'est une bonne idée de lire cet article et de s'y referer dans le futur, quand on a une meilleure compréhension du langage.

Le modèle C

En C, on assigne la valeur 4 a un entier a, que l'on définit grâce au mot clé int

int a = 4;
int b = 17;

Regardons ce qui se passe en arrière plan, avec une représentation de la mémoire. Prenons un exemple simple, avec 4 espaces mémoire et ou chaque int prend 1 espace.

espace 1espace 2espace 3espace 4

Après avoir assigné a = 4 et b = 17, on se retrouve avec:

espace 1espace 2espace 3espace 4
4  17   

La variable a est a l'espace 1, qui contient une valeur de 4. Le compilateur sait que, a chaque fois que l'on utilise la variable a, on parle de l'espace mémoire 1. Faire a = 5 nous donne simplement:

espace 1espace 2espace 3espace 4
5  17   

L'espace 2 est utilise par une autre variable (b). De ce fait, il serait impossible de changer notre variable a d'un entier par une chaine de caractères, car l'espace 2, 3, etc n'est pas disponible. De toute façon, C réserve l'espace mémoire pour un int au moment de la compilation et on ne sait jamais l'ordre dans lequel les variables sont en mémoire (chaque compilateur le fait différemment).

Avec Python, pas de problème de ce genre:

Le modèle Python

En Python, quand on déclare a = 4, en fait ce que l'on fait c'est de créer un objet, un entier de valeur 4:

objet: 4

Puis le a = lui donne un nom:

objet: 4

Si on "assigne" 5 en écrivant a = 5, on crée un autre objet, un entier de valeur 5:

objet: 5
objet: 4

Puis le a = lui donne un nom, et comme il ne peut y avoir qu'un seul objet avec le même nom, notre objet:4 perd son nom:

objet: 5
objet: 4

Éventuellement, Python se débarrasse de l'objet sans nom (4) et on se retrouve avec:

objet: 5

Et que se passe t'il si on fait b = a ?

objet: 5
a  b

Les variables a et b nomment toutes deux l'objet int() de valeur 5.

Cette flexibilité entraine néanmoins une perte de performance par rapport au modèle du langage C, car il faut créer un nouvel objet pour chaque "assignation" (création d'un objet et étiquetage du nom, en fait).


Il y a une fonction bien utile avec python, c'est dir(). Cela retourne une liste des noms qui sont disponibles. Donc si on déclare a = 4, on y trouvera 'a' dans cette liste. Et si on fait dir(a), alors on peut voir toutes les méthodes qui peuvent être appliquées a cet objet 'a'.

C'est le temps d'essayer quelques trucs avec python en mode interactif:

pi@fdion-rpi ~ $ python
Python 2.7.3rc2 (default, May  6 2012, 20:02:25)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> a = 4
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a']
>>> b = 17
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'b']
>>> dir(a)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> a
On voit bien que python retourne 4, et que a a des methodes du genre __int__ et real, celles de int(). Continuons:

>>> a = 5
>>> a

Entre la première et deuxième ligne, python a du travailler dur a créer un nouvel objet et lui a donné le nom a. Notre ancien a (4) lui, il est dans les vapes (et python s’apprête a faire le ménage et a le virer). Mais comme c'est pas évident de voir que c'est ce qui ce passe, on va utiliser une chaine de caractère, cette fois:

>>> a = "wow"
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

C'est tres clair que a n'est pas le meme objet, car on ne retrouve plus __int__ ni real, par exemple. On y retrouve les methodes d'un objet str().


La ligne de code Python a = 4 represente donc un objet int() de valeur 4 qui a pour nom a.

On va donc clore cette petite (!) parenthèse la dessus, et on se revoit pour le prochain tutoriel.

Bonjour / zeroconf / Avahi


Zeroconf é um conjunto de técnicas que criam de forma automática uma rede IP (TCP,UDP...) sem necessitar de configuração ou servidores. Bonjour é a mais largamente adotada solução Zeroconf, encontrado em cada Apple Mac.


Avahi é uma implementação livre do Zeroconf que inclui um sistema para multicast DNS/DNS-SD.


pi@rpi ~ $ sudo apt-get install avahi-daemon
pi@rpi ~ $ sudo insserv avahi-daemon

pi@rpi ~ $ sudo vi /etc/avahi/services/multiple.service

salvar este para o arquivo multiple.service:
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<name replace-wildcards="yes">%h</name>

pi@rpi ~ $ sudo /etc/init.d/avahi-daemon restart

Unix / Mac

Podemos agora conectar remotamente de um Mac (o Solaris / OpenIndiana), usando o seguinte comando:

ssh pi@rpi.local


Com o Windows, instalar este programa também:

Bonjour (Apple)

Use Putty em vez de ssh.

Crushed under the load?

Sometimes you take access to some online ressources for granted.


From time to time, trying to access twitter, I get an error message stating that their servers are over capacity. There was an image accompanying that:

I'll say...

And this morning, it is the raspberry pi foundation web site that is telling me:

Error establishing a database connection

And the raspberry pi forum is even more verbose on the error:

General Error
SQL ERROR [ mysqli ]

Too many connections [1040]

An sql error occurred while fetching this page. Please contact an administrator if this problem persists.

On and Offline

That is why I dont like stuff that is only online. I'm in the middle of a demo, and there you go, it is down. Oh, and I'm not picking on the above two, it has happened to *everybody* at some point, and always in the middle of a demo!

So I tend to make sure I have everything on my laptop when I do a demo. And that I have a backup.

PDF and Epub?

So perhaps I should make my blog also available as a PDF or Epub, what do you think?

Tuesday, December 11, 2012

Python sur Raspberry Pi 02

On continue notre série de tutoriels sur le langage de programmation Python sur le Raspberry Pi.

Geany ou autre

Je dois dire que pour le moment on ne fera rien qui soit spécifique au Raspberry Pi, et donc on peut suivre le tutoriel sur n'importe quel ordinateur, après avoir installé Python 2.7 et l’éditeur geany (ou un autre éditeur configuré comme il se doit).

Le premier tutoriel a établi une base sur les modes d’opérations du programme python et comment installer et utiliser geany. Toutefois, nous n'avons pas configuré geany. Il faut tout d'abord s'occuper d'un concept bien important, l'indentation.


Sur un clavier d'ordinateur, il y a une touche [TAB]. C'est un vestige des bonnes vieilles machine a écrire, et ca signifie "tabulation stop". C'est que sur les machines a écrire, on pouvait mettre a certains endroits, des arrêts d'indentations, bien pratique pour avoir la première ligne d'un paragraphe indenté (C'est la norme en typographie française, mais pas en anglais - alors sur le web on ne voit pas cela beaucoup):

        Cher Monsieur Gaston Lagaffe, c'est avec plaisir que nous vous envoyons a Kuujjuaq, comme représentant de la compagnie. Veuillez trouver ci-joint votre billet d'avion. Surtout, ne manquez pas votre vol qui part demain matin a 6:30 de l’aéroport Charles De Gaule. Un taxi va venir vous chercher a 5:00.
Menfin, c'est bien, ce taxi!

L'indentation nous permet de voir clairement ou commence un paragraphe, mais pas ou il finit. Avec python, l'indentation est inversée par rapport aux normes de typographie française (la première ligne n'est pas indentée, toutes les autres le sont), et on ne parle pas d'un paragraphe, mais plutôt d'un bloc de code. Par exemple:

b = 0
while b < 10:
    b += 1

Cela définit un bloc de code pour une boucle while qui inclut 2 lignes, print(b) et b += 1, car on y trouve une indentation vers la droite, par rapport a la ligne précédente. La ligne b = 0 ne fait pas partie de cela.

Combien d'espace?

Alors que les machines a écrire d'antan permettaient de mettre l'indentation a quelque valeur que l'on veut, la clé [Tab] sur un ordinateur est en général assignée a une valeur de 4 ou de 8 caractères, bien que ne prenant qu'un seul caractère (le 9ieme caractère d'une table ASCII par exemple). De plus, on peut choisir que [Tab] produise des espaces blancs ou bien un TAB.

Pour s'assurer que tout fonctionne correctement avec python, il faut s'assurer de toujours utiliser, soit les espaces blancs, soit le caractère TAB. Si on mélange les deux, on va avoir tout plein de problèmes.

Ma suggestion? Configurer son éditeur pour une indentation de 4 espaces blancs. Et voila.

Indentation: 4 espaces blancs aux lignes 3 et 4

Et comment fait-on cela avec geany? Menu Edit -> Preferences, et la, on choisit Editor sur la colonne de gauche, et Indentation sur la rangée en haut:

4 spaces, Tab key indents
Sur Width, on choisit 4, pour Type, Spaces et il faut avoir le Tab key indents coché. Il y a beaucoup d'autres options, mais c'est un minimum pour commencer.

Les nombres

Avec python et les types intégrés, on peut utiliser des nombres entiers, réels, de très grandes valeurs ou bien complexes. On peut les utiliser dans des équations, des conditions ou les assigner a des variables ou des constantes.

Entiers (int)

Si on considère notre Peugeot 406 Taxi ci dessus, on peut dire qu'il comporte 4 jantes. On pourrait écrire cela en python comme:


On met tout en majuscule pour indiquer que c'est une constante. Si on va changer le nombre de jantes sur le taxi, on l'indiquerais comme une variable, en lettres minuscules:

jantes = 4

Réels (float)

Considérons la capacité du réservoir a essence de notre taxi. Elle est de 70.2 litres (notation avec un point décimal). En python on pourrait écrire cela comme:


Cette capacitee est une constante, car elle ne peut changer (a moins d'y faire un trou, et dans ce cas, ce sera une capacitee de 0 litres...)

Il y a une différence entre le type de nombre pour JANTES et RESERVOIR.

En effet, 4 est un nombre entier, et donc JANTES est un nombre entier. C'est ce que python nomme un int (pour integer).

Pour 70.2, c'est un nombre réel, et donc RESERVOIR est aussi un nombre réel. C'est ce que python nomme un float (pour floating point, ou virgule flotante).

Dans ces cas, python sait très bien ce qu'il faut faire, sans qu'on lui dise le type de nombre en question. Mais, que va faire python avec ceci?

Python 2.6.4 (r264:75706, Oct 17 2011, 16:55:05) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> JANTES = 4
>>> COUT = 2731
>>> prixunitaire = COUT / JANTES
>>> prixunitaire

Le prix unitaire pour une jante serait de 2700 euros (le cout total), divisé par le nombre de jantes. Mais, est-ce que 682 est la valeur correcte? Non. Enfin, pour python, il est convaincu que si... Mais si on fait notre vérification:

>>> prixunitaire * JANTES

Il nous manque quelques euros.... Quel est le problème?

Nous avons demandé a python de diviser un nombre entier (2731) par un nombre entier (4), et il va donc assigner un nombre entier (682) au prixunitaire. Python as donc fait ce qu'il devait faire.

Que peut-on faire ici? Une solution simple, c'est de définir le cout comme 2731.0, et en faire un nombre a virgule flottante:

>>> COUT_JANTES = 2731.0
>>> prixunitaire = COUT_JANTES / JANTES
>>> prixunitaire
>>> prixunitaire * JANTES
On peut aussi utiliser la fonction intégrée float():

>>> prixunitaire = float(COUT_JANTES) / JANTES
>>> prixunitaire
Similairement, il existe une fonction intégrée int().

Très grandes valeurs

Depuis Python 2.4, on peut utiliser les entiers sans spécifier un type pour très grandes valeurs (long). Ce que cela veux dire, c'est que si on a un nombre entier, il est représenté comme valeur de 32 bits sur un système d'exploitation de 32 bits (Raspbian sur Raspberry Pi), et 64 bits sur un système d'exploitation de 64 bits avec python en 64 bits, mais que si on y assigne une valeur qui ne peut être représentée dans cet espace, on se retrouve avec un long (avec un L après le nombre):

>>> 2**30
>>> 1073741824 + 1073741824

En pratique, ça devrait être transparent, mais si on veux, on peut forcer l'utilisation d'un long:

salaire = 25L

N’empêche que même si je force python a considérer ce salaire comme un très grand nombre, c'est quand même un petit nombre entier...

On peut aussi utiliser la fonction intégrée long().

Nombres complexes

Ils le sont, complexes. Si ça vous dit, allez lire l'article sur wikipedia: Nombre_complexe

Il suffit d'ajouter un j devant la partie imaginaire (et pas une autre lettre, comme x):

>>> nombrecomplexe = 1 + 2j
>>> nombrecomplexe
>>> nombrecomplexe = 1 + 2x
  File "<stdin>", line 1
    nombrecomplexe = 1 + 2x
SyntaxError: invalid syntax

Ce n'est pas une équation, mais bien un nombre complexe, avec une partie réelle et une partie imaginaire. On peut aussi utiliser la fonction intégrée complex().

Pas très folichon tout ça, alors passons a autre chose.

Assignations multiples

En Python, on peut assigner plusieurs variables en même temps.

Exemple 1:

x = y = z = 0

Exemple 2:

x, y, z = 0, 1, 2


On peut aussi assigner une valeur a une variable, et bien sur, la changer.

>>> x = 0
>>> print(x)
>>> x = 7
>>> print(x)

Mais on peut aussi réassigner le type, pas seulement la valeur:

>>> x = 0
>>> print(x)
>>> x = "Bonjour!"
>>> print(x)
x est tout d'abord un nombre entier, puis une chaine de caractères, sans aucun problème.

Chaines de caractères

Dans notre premier tutoriel, on a imprimé des chaines de caractères, délimitées par les guillemets:


De la même façon, on peut assigner une chaine de caractères a une variable en utilisant les guillemets simples, doubles ou encore en triple (''' ''' ou """ """):

x = "allo!"
x = 'allo!'
x = """allo!"""

Et on peut aussi utiliser la fonction integree str():

a = 123
x = str(a)

Type dynamique

Pas le type dynamique comme Python
N'ayant pas a identifier le type de nos variables, nous permet comme on l'a vu de réassigner une chaine de caractères a une variable qui contenait un nombre entier, bien sur, mais en plus, cela nous permet de créer des fonctions qui peuvent accepter une variété de types.

On va créer une fonction qui va accepter un paramètre, et va retourner 2 fois ce paramètre:

def mafonction( parametre):
    return parametre * 2

Dans un langage de programmation ou l'on doit identifier clairement par type nos variables, il nous faudrait définir une fonction pour les entiers, pour les réels, pour les chaines de caractères, etc. Mais avec python, c'est tout ce que l'on a a faire:

>>> def mafonction( parametre):
...     return parametre * 2
>>> print(mafonction( 123))
>>> print(mafonction( "123"))
>>> print(mafonction((1, 2, 3)))
(1, 2, 3, 1, 2, 3)

Ceci conclu donc notre deuxième tutoriel. Le prochain, on va créer un squelette de code que l'on va utiliser pour apprendre différends concepts.