Showing posts with label francais. Show all posts
Showing posts with label francais. Show all posts

Friday, February 6, 2015

Friday, January 2, 2015

L'étonnant Python: à grande échelle

Perception

De temps a autres, j'entends dire des choses complètement ridicules:

"Ah oui vous utilisez Python. Je connais, c'est un langage de programmation pour écrire des petits scripts, ce n'est pas utilisable à grande échelle.

(En fait il y avait 2 autres points encore plus ridicule dans cette conversation, j'y reviendrai plus tard)

Réalité

Une connaissance travaille chez Bank Of America sur le programme Quartz. Ils sont passes de 0 a 5000 développeurs Python et des millions (plus de 10) de lignes de code en quelques années seulement. On parle de la même échelle pour YouTube. Les projets de 10 millions+ de lignes de code Python sont rares bien sur, mais ce n'est pas du a une raison technique, mais plutôt parce que l'on accomplis beaucoup en peu de lignes de code.

François
@f_dion

Monday, August 19, 2013

Nouvelle version de Brython: 20130817-141536

Téléchargement de Brython


Une nouvelle version de Brython, Brython-20130817-141536, est maintenant disponible sur la page des téléchargement
 

Changements

Depuis la version précédente :

- import amélioré , on peux utiliser les packages : "import X.Y", "from X.Y import Z [as A]", "from . import X" (corrige le bogue 123)
- le protocole des itérateurs utilise maintenant les méthodes __iter__() et __next__() pour tous les types
- "for" les utilisent aussi
- implémentation des compréhensions améliorée : utilise les dictionnaires global et local (corrige le bogue 129)
- améliorations a la console interactive : http://brython.info/tests/interactive_mode.html
- ajout du type "bytes" (incomplet)
- ajout de balises HTML5 et événements DOM manquants
- ajouts a la documentation en français, ajout d'une section pour les modules spécifiques a Brython ; autres parties traduites
- Bouton sur la page de tests pour exécuter tout les tests et retourner les erreurs
- amélioration du module markdown : les _ et * génèrent du HTML différent, tout comme __ et **
- le mot clé del : utilise la méthode __del__() si elle existe


Bogues

  • - Corrections :
. #78 : map() and filter() return iterator objects, not lists
. #124 : support of CSS attribute "float"
. #125 : add methods copy() and clear() to lists
. #126 : escaped quotes inside strings
. #127 : DOMNode instances comparison methods (__eq__ and __ne__)
. #128 : class inheritance
. conversion des JS objects dans json.js et $JS2Py
. problème avec les itérations sur instances DOMNode



Autres


  • réorganisation : déplacement de JSObject du fichier py_dom.js au fichier py_utils.js
  • galerie : ajout d'un jeu de solitaire qui utilise SVG et le glisser - déposer


Vos retours


L’équipe Brython espère vos retours sur cette version, autant pour nous laisser savoir si vous trouvez  des bogues mais aussi au niveau de votre expérience avec Brython, en joignant et participant aux forums Brython.

De plus nous aimerions entendre parler de vos projets (actuels ou futurs) avec Brython sur appareils mobiles (tablettes, etc) et informatique embarquée (Raspberry Pi, Beaglebone black, Cubieboard, etc), surtout au niveau des écrans tactiles, car nous y travaillons en ce moment. Alors, n’hésitez pas a joindre le forum ou a me contacter directement sur mon blog ou sur twitter.

François
@f_dion

Friday, June 7, 2013

Wednesday, February 13, 2013

Audio numerique sur RaspberryPi

Audiophile

Pour que le Raspberry Pi coute le moins possible, certaines décisions on du être prise. Par exemple, il n'y a pas de CODEC analogique - numérique. De sorte que l'audio se joue par soit:

1) le port HDMI - audio numérique passée directement au téléviseur ou a l'ampli intégré avec décodeur DTS, dolby digital, master audio etc... Si on utilise le Raspberry Pi comme serveur de media, c'est parfait. Mais si on ne peut utiliser le port HDMI?

2) le port 3.5mm analogique - l'audio est générée par PWM (Pulse Width Modulation). Avec une fréquence suffisamment élevée, on peut arriver a 16 bit de résolution, comme les convertisseurs plus conventionnels. Dans le cas du Raspberry Pi toutefois, la résolution est un peu moindre. En plus, il y a un problème avec le pilote ALSA, de sorte que le son n'est pas vraiment... a la hauteur.

USB

Tout n'est pas perdu. En effet, on peut se procurer une carte son sur USB:
Mini PCM2704 USB sur ebay (A noter que le prix est a la hausse, de $4.00 par rapport a ce que j'ai payé ...).

C'est géré par le Raspberry Pi: 

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 08bb:2704 Texas Instruments Japan

Et ça donne une sortie analogique 3.5mm de qualité (super sur casque d’écoute), une sortie SPDIF rca numérique et une TOSLink optique numérique.
de USB a SPDIF, TOSLink et 3.5mm analogique

Illusion d'optique

Dans mon cas, je saute le DAC. J'utilise la carte son comme interface numérique optique, qui se relie a un processeur de son numérique Technics SH-AC500D (qui lui se branche a un ampli):

Le processeur de son est sur le dessus

La lumiere au bout ... de la fibre
On branche la fibre sur un des ports TOSlinks

Le soft


mpg123, aplay et d'autres lecteurs audio qui utilisent ALSA vont fonctionner avec la carte, mais il faut effectuer un changement a un fichier de configuration:

$ sudo vi /etc/modprobe.d/alsa-base.conf

et sur la derniere ligne, on change le -2 par un 1:

options snd-usb-audio index=-2
devient
options snd-usb-audio index=0 nrpacks=1
et on reboot.

François
@f_dion

Thursday, February 7, 2013

L'autoréplication


de RaspberryPi a SD


Il y a un certain challenge a faire une carte SD pour le Raspberry Pi.

Ceci est du en partie a la grande variété de systèmes d’opération et d'ordinateurs (et leur matériel). D'autre part, beaucoup de personnes n'ont que le Raspberry Pi comme ordinateur, les autres étant hors de portée du au prix.

Il y a certains groupes d'usagers ici et la qui se débrouillent pour aider les usagers a faire leur propre carte SD, alors que d'autres doivent acheter des cartes SD avec le système d’opération déjà installé. Mais comment faire pour faire une copie de cette carte SD, n'est on pas de retour a la case départ?

Le lecteur


En fait, une fois que l'on a un système d’opération  sur la carte SD, on peut alors faire de l'autoréplication. Quésaco? me direz vous... Et bien, c'est quand un système d’opération peut se répliquer lui même (faire une copie de carte SD seulement avec le Raspberry Pi).

Pour ce faire, il faut un lecteur de carte SD, car le Pi n'a qu'une seule fente SD. Un lecteur comme celui ci, par exemple (ici, avec une carte 16GB, mais on peut faire 4GB ou 8GB ou plus, de la même façon):




Et on le branche (avec un câble ou en direct) au port USB.



dd


La version la plus recente de Raspbian Wheezy est de Decembre 2012:
http://files.velocix.com/c1410/images/raspbian/2012-12-16-wheezy-raspbian/2012-12-16-wheezy-raspbian.zip

Ici, les instructions se basent sur une version plus vieille, mais c'est le meme principe. Il suffit de remplacer l'url http://www.gtlib.gatech.edu/pub/raspberrypi/images/raspbian/2012-09-18-wheezy-raspbian/2012-09-18-wheezy-raspbian.zip par une de cette liste ici (choisir un serveur plus pres de soi): http://downloads.raspberrypi.org/download.php?file=/images/raspbian/2012-12-16-wheezy-raspbian/2012-12-16-wheezy-raspbian.zip


Avant de commencer, il faut s'assurer d'avoir au moins 2.5GB de libre (df -h me donne 2.9G ici). On insere la carte SD vide dans le lecteur et on verra apparaitre /dev/sda ou sdb.



fdion@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs           15G   11G  2.9G  80% /
/dev/root        15G   11G  2.9G  80% /
devtmpfs        109M     0  109M   0% /dev
tmpfs            22M  248K   22M   2% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            44M     0   44M   0% /run/shm
/dev/mmcblk0p1   56M   35M   22M  62% /boot
fdion@raspberrypi ~ $ wget http://www.gtlib.gatech.edu/pub/raspberrypi/images/raspbian/2012-09-18-wheezy-raspbian/2012-09-18-wheezy-raspbian.zip
fdion@raspberrypi ~ $ unzip 2012-09-18-wheezy-raspbian.zip
fdion@raspberrypi ~ $ ls /dev/sd*
ls: cannot access /dev/sd*: No such file or directory
fdion@raspberrypi ~ $ ls /dev/sd*
ls: cannot access /dev/sd*: No such file or directory
fdion@raspberrypi ~ $ ls /dev/sd*
/dev/sda  /dev/sda1
fdion@raspberrypi ~ $ ls *.img
2012-09-18-wheezy-raspbian.img


Ici, le lecteur de carte avec SD est /dev/sda (si c'est sdb, il faut ajuster la commande ci dessous avec of=/dev/sdb). On est pret a faire la copie de l'image de la carte SD (le fichier .img), a partir du Pi (on peut aussi utiliser bs=4M qui va beaucoup plus vite avec certaines cartes):


fdion@raspberrypi ~ $ sudo dd bs=1M if=2012-09-18-wheezy-raspbian.img of=/dev/sda
1850+0 records in
1850+0 records out
1939865600 bytes (1.9 GB) copied, 428.218 s, 4.5 MB/s
fdion@raspberrypi ~ $ sudo sync


Le sudo sync est très important. Si on ne le fait pas, ça ne fonctionnera pas.

Et c'est tout! On peut maintenant donner cette copie a une autre personne. Tres pratique pour les clubs.

Il existe aussi une méthode pour faire une copie, sans utiliser de fichier .img, mais cela sera pour une autre fois...


François
@f_dion

Friday, February 1, 2013

Nouvelle publication DIY

faitmain

Un nouveau magazine vient de paraitre, il s'agit de Fait Main, un magazine collaboratif en ligne et en PDF:

http://www.faitmain.org

On y retrouve divers sujets autour du DIY("Do It Yourself"), et dans ce premier numéro, on y parle bien sur de Raspberry Pi.

J'ai écris l'article "câble d'interface pour Raspberry Pi" Lire l'article 

Mais ce n'est pas tout: 

Contenu du volume 1

La tribune de ce numéro est un parallèle entre web hébergé et OGM. Lire la tribune 

Le premier article présente une application de reconnaissance de feuille écrite pendant un Hackathon. C'est l'application qui a été écrite en 24 heures par Olivier, Ronan & Tarek lors du dernier AngelHack à Paris. On y parle de machine-learning au service des plantes, des hackathons de programmation & de responsive design . Lire l'article

Le deuxième article parle de domotique et vous explique comment piloter des dispositifs sans fils - portails, détecteurs de mouvements etc. On y parle d' Arduino , de Raspberry-PI et de signal en 433 mhz . Lire l'article 
 
Le troisième article présente le travail de Marcin Ignac: des méduses animées en 3D. Des captures d'écran de ces méduses ont ensuite été utilisées pour faire partie d'un projet de livre génératif. On y parle d' animation procédurale , de processing.js & d'hachurage. Lire l'article

Le quatrième article vous donne 5 conseils de photos culinaires pour que vous puissiez prendre en photos vos soupes, gigots et autres desserts comme un(e) pro. Lire l'article 

Suit une interview de Hugues Aubin au LabFab de Rennes. Lire l'article .

Un cinquième article sur la conception d'un Juke box avec un Raspberry-PI, sans aucune soudure requise :) Lire l'article 

Le sixième article vous explique comment recycler une vieille nappe de disque dur pour connecter le GPIO de votre Raspberry. Lire l'article 

Le septième article est une rapide présentation du jeu The Midst , conçu avec Processing et WebPD. Lire l'article 

Enfin, le huitième article aborde les bases du fonctionnement d'une CNC. Lire l'article 
Bonne Lecture!
— Tarek

Equipe

Le projet FaitMain est monté par Tarek Ziadé mais est surtout possible grâce aux créateurs d'articles et aux relecteurs.

Ont participé à ce numéro :

Tuesday, January 29, 2013

Applications pour téléphones mobiles avec Python

C'est une traduction de iPhone app with Python. J'ai eu une forte demande pour la version française.

Grâce a Brython


L’icône Brython GPS

 

Une vraie app pour iPhone?


Le programme lancé, on y voit un écran de démarrage, comme il se doit:

Splash (ancienne carte de Caroline du Nord)

Mais c'est un programme web, et pas une application faite avec xcode.

Le premier écran, mode manuel


Mode mise a jour automatique

J'essaie?


Il suffit d'aller sur le lien de la galerie de Brython, ici:

gallery/geo.html et sur un iPhone, on l'ajoute a l'ecran d'accueil. On peut maintenant lancer le programme comme une vraie application iOS.


J'ai déjà vu cela, non?


C'est bel et bien une application web, donc basée sur HTML et CSS, mais le code lui même, c'est écrit en Python. En plus, on utilise ici une toute nouvelle fonctionnalité de Brython, en faisant appel a un script Python externe a la page HTML (c'est une nouveauté qui date de cette fin de semaine), plutôt que d'avoir le code a même la page HTML. Cela nous permet une séparation de la présentation, de la logique et du "bling" (le CSS):

Notre HTML


<!DOCTYPE html>
<html>
    <head>
        <title>Brython test</title>
        <meta charset="iso-8859-1">
        <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1,maximum-scale=1">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <script src="../brython.js"></script>
        <script type="text/python" src="navi.py"></script>
        <link rel="stylesheet" type="text/css" href="navi.css" />
        <link rel="apple-touch-icon" href="icon.png"/>
        <link rel="apple-touch-startup-image" href="splash.png">
    </head>
    <body onLoad="brython()">
        <div id="header">
            <H1>Votre position</H1>
            <div id="switch">
                  <span class="thumb"></span>
                    <input id="refr" type="checkbox" />
                </div>
            </div>
        </div>
        <div id="navarea"></div>
        <div id="maparea"></div>
    </body>
</html>

Application web pour iPhone typique, mais sans jQuery mobile ou autre module du genre. Et pas de onclick dans la page html. L'unique javascript c'est brython.js qui est l’interpréteur Brython même et l'appel a brython() par l'entremise de onload.

Le code Python n'est pas sur la page, mais on voit qu'on y fait reference par src="navi.py"

Allons donc voir ce qu'il y a dans ce fichier navi.py:

Notre Python


# globals #########################
refr = False
geo = win.navigator.geolocation
watchid = 0


# les fonctions ###########################
def navi(pos):
    xyz = pos.coords

    ul = UL(id="nav")
    ul <= LI('lat: %s' % xyz.latitude)
    ul <= LI('lon: %s' % xyz.longitude)

    mapurl = "http://maps.googleapis.com/maps/api/staticmap?markers=%f,%f&zoom=15&size=320x298&sensor=true" % (xyz.latitude, xyz.longitude)
    img = IMG(src = mapurl, id = "map")
    try:
        doc["nav"].html = ul.html  # on met a jour la liste
    except KeyError:
        doc["navarea"] <= ul  # on cree la liste
    try:
        doc["map"].src = mapurl  # on met a jour l'url de l'image
    except KeyError:
        doc["maparea"] <= img  # on cree la balise img

def nonavi(error):
    log(error)

def navirefresh(ev):
    global refr, watchid
    refr = False if refr else True
    if refr == True:
        doc["switch"].className = "switch on"
        watchid = geo.watchPosition(navi, nonavi)
    else:
        doc["switch"].className = "switch"
        geo.clearWatch(watchid)

# au demarrage ###########
if geo:
    geo.getCurrentPosition(navi, nonavi)
    doc["switch"].className = "switch"
    doc["switch"].onclick = navirefresh  # on associe un evenement onclick
else:
    alert('geolocation not supported')

On établis 2 fonctions de rappel (callback). Une si on a notre géolocalisation (navi), et une s'il y a une erreur (nonavi), et finalement, une autre fonction (navirefresh) pour s'occuper de l’événement onclick du contrôle auto refresh dans la barre de menu de l'application. Le démarrage initial se fait par un appel a geo.getCurrentPosition avec nos fonctions de rappel. Ça fonctionne assez bien comme GPS.

Notre CSS

Le CSS étant un peu long, je ne le mettrai pas sur mon blog, mais vous pouvez trouver le code sur le site brython.info ou sur googlecode: SVN repository. Le CSS pour l'interrupteur genre ios 5 a ete emprunté ici: ios-5-style-switch-control

Ce n'est que le début

Alors voila, c'est un point de depart pour faire toute sortes de choses. Un tracker pour le jogging, le velo (avec local storage et synchro par appel ajax) et bien d'autres choses. Vous pouvez désormais faire tout cela avec votre langage favori (Python, bien sur) que ce soit pour votre téléphone mobile ou tablette. Cet exemple est quelque peu spécifique au iPhone (surtout a cause du CSS), mais fonctionne sur Android aussi et peut être adapté facilement aux tablettes. Et cela ne m'a pas pris beaucoup de temps.

Et si vous avez besoin d'aide, n'oubliez pas qu'il existe une liste en francais:
forum/brython-fr

@f_dion

Friday, January 25, 2013

Brython trouve son code...

Sur le serveur


Jusqu’à maintenant, en parlant de Brython, j'ai mis l'emphase sur le fait que tout roule du cote du client, dans la page web.

Sur ce blog, par exemple, j'inclus même brython.js a même le gabarit de blogger, pour figer la version. Tout est ici.

Et bien sur, le code Python lui meme se retrouve a l'interieur de la balise script:

<script type="text/python">
#le code python va ici
print("Et pourtant elle tourne")
</script>

Mais pourquoi le titre?


C'est pour introduire une nouvelle fonctionnalité de Brython, tout juste sortie du four! On peut maintenant utiliser la syntaxe:

<script type="text/python" src="script.py"></script>

Et le Brython va aller chercher script.py (ou tout autre script python que l'on spécifie) avec un appel ajax, sur le serveur (avec certains navigateurs comme Firefox, en fait meme pas besoin de serveur, on peut faire un file open de la page web et tout fonctionne localement). Sur un serveur, comme c'est avec ajax, bien sur le script se doit d’être sur le même domaine que la page web.

On pourra ainsi séparer notre structure (.html), nos embellissements (.css) et notre logique (.py).

@f_dion

Saturday, January 19, 2013

RPi.GPIO, l'imposteur

Un module python pour ateliers raspberrypi

L'atelier PyHack qui est présenté par PYPTUG porte sur comment faire interagir le monde virtuel de la programmation avec le monde physique, avec Python, et souvent avec l'ordinateur Raspberry Pi. Mais pas tout le monde a un Raspberry Pi.

Les ateliers, et aussi les tutoriels de ce blog, sont faits pour apprendre l’électronique et le langage de programmation Python. Les techniques Python enseignées ici, peuvent être appliquées a une grande variété de problèmes.

Et donc, ca serait drolement bien si on pouvait rouler le meme code qui est fait pour le raspberry pi, sur un portable? J'ai donc décidé de m'attaquer au probleme.

L'imposteur

J'ai donc ecris un module RPi.GPIO de remplacement pour essayer le code pour Raspberry Pi qui inclus des access aux GPIO sur des plateformes autres que le Raspberry Pi. C'est-a-dire, votre portable.


Votre portable aura une personnalité multiple

Comment?

C'est un module Python (en fait, un package RPi qui inclus un module GPIO) avec une implémentation des fonctions setmode(), setup(), cleanup(), input(), output(), prends en charge les 54 GPIO (états et directions), modes broadcom et board, fonctions vides pour les 4 set_*_event() - peut etre dans le futur j'y ajouterai la logique, et un peu de vitriol. Non, pas ca! Et un peu de logique pour les erreurs (genre, essayer d'acceder a un GPIO avant de l'assigner). Il y a meme un mode de débogage (gpio.debug = True).

Tout cela devrait etre suffisant pour rouler sur un portable du code Python fait pour le Raspberry Pi. Seul hic, pas moyen dans l’immédiat de simuler le changement d’état d'une entrée (simuler un bouton, par exemple).

On se le procure

Chez Mr. Bitbucket (bitbucket.org/fdion)

Pour cela il faut d'abord avoir l'outil Mercurial:

Sous un Linux de type debian
$ sudo apt-get install mercurial

Sous fedora
$ sudo yum install mercurial

Sous solaris / openindiana, c'est disponible par packagemanager.

Pour windows ou mac c'est ici: http://mercurial.selenic.com/

A noter que sous windows on peut aussi se procurer TortoiseHg qui ajoute un menu Mercurial (hg) quand on clique le bouton droit sur un repertoire, dans file manager: tortoisehg.bitbucket.org

Une fois que l'on a installé mercurial:

$ hg clone https://bitbucket.org/fdion/fablocker

On se retrouve avec les ateliers PyHack. RPi.GPIO l'imposteur fait partie du deuxième atelier.

C'est sous le répertoire fablocker/PyHack/workshop02

Il y a un fichier test.py qui importe RPi.GPIO. Comme il y a un répertoire du nom de RPi et a l’intérieur, un fichier python GPIO.py, test.py va importer ce GPIO plutôt que le module système. Pour en faire l'essai, on fait:

python test.py

(RPi.GPIO l'imposteur n'a pas besoin de sudo, ce qui n'est pas le cas du module système). Sur un vrai Raspberry Pi, dans tout autre répertoire l'imposteur ne sera pas trouvé. Mais dans workshop02, si on veux rouler test.py sur les GPIO du Pi, il suffit de renommer le répertoire RPi, et ainsi Python ne le trouvera pas.

Mise a jour


Si vous avez déjà un clone du projet Fablocker, pour faire la mise a jour, il suffit de faire (sous Windows utiliser le hg workshop ou bien la ligne de commande):


pi@raspberrypi ~/bitbucket $cd fablocker
pi@raspberrypi ~/bitbucket/fablocker $ hg pull http://bitbucket.org/fdion/fablocker
real URL is https://bitbucket.org/fdion/fablocker
pulling from http://bitbucket.org/fdion/fablocker
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 5 changes to 5 files
(run 'hg update' to get a working copy)
pi@raspberrypi ~/bitbucket/fablocker $ hg update
5 files updated, 0 files merged, 0 files removed, 0 files unresolved
pi@raspberrypi ~/bitbucket/fablocker $ 

Thursday, January 10, 2013

Adafruit T-cobbler

Le Raspberry Pi Cobbler

Peut-être avez vous acheté le Cobbler de chez Adafruit. C'est facile avec cela de se connecter a une plaque de prototypage.

Mais, une chose qui m'a toujours irrité, c'est que le cable viens et camoufle tout (enfin, au moins un coté):
Cobbler: le cable cache beaucoup

De sorte qu'il faut alors commencer par:
  • mettre le cobbler sur la plaque
  • mettre les composants
  • faire les connections
  • au final, mettre le câble plat
  • on exécute notre code Python
  • on espère que ça fonctionne
Et si ça ne fonctionne pas, on enlève le câble, et on tente de trouver l'erreur.

Ou peut-être c'est simplement une erreur de code, on a choisi le mauvais GPIO...

Peut importe, si le GPIO est en haut, impossible de voir! La seule façon de vérifier, c'est de déconnecter le câble. Ça m'est arrivé plus d'une fois dans les workshops ou je fais des démos avec plusieurs circuits différents.

Le T-cobbler

Vers la fin de 2012, Adafruit ont introduit un nouveau type de cobbler, le T-cobbler, en forme de T.

C'est beaucoup mieux ainsi, car on a pleine vue de notre plaque:

T-Cobbler: le cable n'occulte rien

Et c'est plus facile a lire la légende. Le seul hic, c'est qu'il faut avoir un cable assez long pour le plier et qu'il soit vraiment hors "d'etat de nuire" ...

Ca va bien aussi avec les plaques plus grandes, il suffit de voir cela dans Raspberry Pi 2 bit H bridge (en anglais).

@f_dion

Monday, December 31, 2012

Le magazine Mag Pi (RaspberryPi)

Le Mag Pi 

Vous connaissez?

En Anglais
www.themagpi.com

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:
frenchmagpi.site-mpe.fr/index.php?title=Accueil

Pour le moment, seul le numero 5 est complet:

The_MagPi_issue_5_Francais.pdf

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.

Encodage

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 -*-

ou
#!/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.


Brython

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:

CYR =  'АБЦДЕФГЧИЙКЛМНОПЯРСТУВЖХЫЗШЩЭЮЁЬЪ'
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):


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="/brython.js"></script>
</head>
<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.
<p>
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
    try:
        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
    else:
        del doc[str(position)]


def keydown(e):
    if not e:
        e = win.event
    key = e.keyCode
    offset = 65 if e.shiftKey else 32
    e.preventDefault()
    e.stopPropagation()
    log(key)
    if key == 8:
        deletekey()
    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
    e.preventDefault()
    e.stopPropagation()


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


# Draw keyboard and set key events

drawkeyboard()
doc.onkeydown = keydown
doc.onkeyup = keyup

</script>
<br />
Click buttons or type on keyboard:
<br />
</body>
</html>

Friday, December 21, 2012

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:

ipython

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).


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
a

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

objet: 5
objet: 4
a

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
a
objet: 4

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

objet: 5
a

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).

dir()


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
4
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
5

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().

Conclusion


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.

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.

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:
    print(b)
    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:

JANTES = 4

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:

RESERVOIR = 70.2

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
682

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
2728

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
682.75
>>> prixunitaire * JANTES
2731.0
On peut aussi utiliser la fonction intégrée float():

>>> prixunitaire = float(COUT_JANTES) / JANTES
>>> prixunitaire
682.75
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 + 1073741824
2147483648L

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: fr.wikipedia.org Nombre_complexe

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

>>> nombrecomplexe = 1 + 2j
>>> nombrecomplexe
(1+2j)
>>> 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

Réassignation


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

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

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

>>> x = 0
>>> print(x)
0
>>> x = "Bonjour!"
>>> print(x)
Bonjour!
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:

print("allo!")
print('allo!')
print("""allo!""")

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))
246
>>> print(mafonction( "123"))
123123
>>> 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.