Atelier Python : introduction de base


INTRODUCTION

  • Présentations
    • Montréal-Python
      • Présentateur
      • Événements : conférence mensuelle (MP), soirées projets, sprints, ateliers, PyCon
      • Ateliers
      • Sponsors
    • Et vous?
      • Étudiants?
      • Programmeurs?
      • Professeurs?
  • Python

    • interprété
    • orienté-objet
    • dynamique
    • fortement typé
    • ... utilisé (presque) partout
  • Objectifs

    • explorer Python par l'expérimentation et l'introspection dans l'interpréteur
    • maîtriser les notions de base : types, fonctions, conditionnels, itérations...
    • écrire un script qu'on exécutera dans l'interpréteur
    • importer la puissance de Python
  • Documentation

  • Environnement

    • éditeur texte
    • interpréteur python : python, ipython

NOTIONS DE BASE

Interpréteur

  • python : interpréteur de base
$ python
  • ipython : interactivité / introspection
$ ipython

Syntaxe

Variables

  • nom, valeur, référence : les noms de variables référencent des valeurs
In [1]:
a = 12
b = a
In [2]:
id(a)
Out[2]:
142708844
In [3]:
id(b)
Out[3]:
142708844

Types

  • typage dynamique (pas besoin déclarer)
In [4]:
n = None        # NoneType : type spécial voulant dire... rien
b = True        # bool : booléen... True ou False n'oubliez pas les majuscules

i = 15          # int : entier
f = 15.5        # float : décimal

s = "chaine"    # str : chaine de caractère, instancié avec "" ou ''
u = u"chaîne"   # unicode : chaîne de caractère unicode, instancié avec u"" ou u''

l = []          # list : liste d'objets (ordonné)
t = ()          # tuple : liste immuable d'objets
d = {}          # dict : dictionnaire de données (unique, non-ordonné), clés-valeurs

ens = {}        # set : ensemble (unique, non-ordonné), set([])
  • unpacking
In [5]:
coord = (45.30, 73.34)
x, y = coord
  • fortement typé (pas de transtypage implicite)
  • transtypage

    str(), int(), float(), bool(), list(), tuple(), dict(), set()

In [6]:
float(a)
Out[6]:
12.0

Conteneurs

  • imbrication
In [8]:
l = [[1,2,3],[4,'salut',6],[7,8,9]]
d = {1611: {'nom':'Baragiotta', 'prenom':'Davin'}, 123: {'nom':'Leduc-Hamel', 'prenom':'Mathieu'}}
  • index
In [9]:
l[2]
l[-1]
d[1611]
l[1][1]
Out[9]:
'salut'
  • slicing
In [10]:
l[1:2]
Out[10]:
[[4, 'salut', 6]]

Fonctions

Appel de fonction

  • nom de fonction : open
  • appel de fonction : open()

Built-in : fonctions built-in et structure du langage

type() # retourne le type de l'objet
dir() # retourne les noms derrière l'objet
help() # retourne l'aide
callable() # dit si un objet est appelable, exécutable...

bool(), int(), str()... # initialisation ou transtypage
getattr()

isinstance(objet, Type) # teste le classe (ou type) d'un objet
issubclass()
super()

len()
min()
max()

open()
range()
raw_input()

enumerate()
zip()
sorted()
reversed()

print
del

Déclarer une fonction

  • convention de nommage
  • output : None par défaut, une ou plusieurs valeurs
  • input : paramètres positionnels ou nommés
  • portée des variables
  • *args, **kwargs
In [ ]:
def age(annee_naissance):
    return 2012 - annee_naissance

def ma_fonction(param1, param2, param3=None, param4=0, *args, **kwargs):
    """Ceci est ma fonction."""
    output = True
    return output

Objets et namespaces

  • objet : tout est un objet
  • attribut = variable sur un objet
  • méthode = fonction sur un objet

  • objet.attribut

  • objet.methode()
  • objet.attribut.methode()

Introspection

  • variable. [+ tab]
  • variable?

  • type()

  • dir()
  • help()

  • exploration des types

  • concaténation : s1 + s2

In [7]:
nom = "Davin Baragiotta"
prenom, nom = nom.split()
nom.upper()
nom.lower()
nom.ljust(30)
nom = [prenom.lower(), nom.lower()]
username = ".".join(nom)

nom = "Davin Baragiotta"
username = ".".join(nom.split()).lower()

users = []
users.append(username)

davin = {'prenom':'Davin', 'nom':'Baragiotta'}
mathieu = {'prenom':'Mathieu', 'nom':'Leduc-Hamel'}
jp = {'prenom':'Jean-Philippe', 'nom':'Caissy'}

personnes = []
personnes.append(davin)
personnes.append(mathieu)
personnes.append(jp)

statuts = [
    (1, u'Nouveau'),
    (2, u'En cours'),
    (3, u'Rejeté'),
    (4, u'Retenu'),
]

Comparaisons et opérateurs

  • + - * / // **
  • < > <= >= == !=
  • x < y <= z
  • faux = False, 0, "", (), [], {}, None
  • and, or, not
  • & | ^
  • in, not in
  • is, is not

Conditionnel

  • if, elif, else
In [1]:
liste = range(6)
if 5 in liste:
    print 'hourra 5'
elif 4 in liste:
    print 'hourra 4'
else:
    print 'pas hourra'
hourra 5

  • one-liner
In [2]:
'hourra 5' if 5 in liste else 'pas hourra'
Out[2]:
'hourra 5'

Itération

  • while
In [11]:
annee = 2012
while annee <= 2015:
    print annee
    annee = annee + 1   # annee += 1
2012
2013
2014
2015

  • for
In [12]:
for i in range(2012, 2016):
    print i
2012
2013
2014
2015

Classes

Déclarer une classe

In [3]:
class Personne(object):
    
    def __init__(self, nom, prenom, date_naissance=None):
        self.nom = nom
        self.prenom = prenom
        self.date_naissance = date_naissance
        
    def age(self):
        # TODO : calculer a partir de la date naissance et aujourd'hui
        return self.date_naissance

Créer des objets (instances) à partir d'une classe

In [4]:
mathieu = Personne("Leduc-Hamel", "Mathieu")
davin = Personne(prenom="Davin", nom="Baragiotta")

Scripts

  • créer script.py
In [17]:
#! /usr/bin/env python
# -*- encoding: utf-8 -*-

def coucou(nom):
    return u"Coucou %s!" % (nom,)
        
if __name__ == '__main__':
    print u"--------------------------------------------------"
    print u"DÉBUT du script"
    print u"--------------------------------------------------"
    nom = raw_input("Quel est votre nom? ")
    print coucou(nom)
    print u"-----------------------------------------------"
    print u"FIN du script"
    print u"-------------------------------------------------"
--------------------------------------------------
DÉBUT du script
--------------------------------------------------
Quel est votre nom? Davin
Coucou Davin!
-----------------------------------------------
FIN du script
-------------------------------------------------

  • shebang : #! /usr/bin/env python
  • encoding : # -*- encoding: utf-8 -*-
  • if __name__ == '__main__':
  • raw_input()

  • créer un répertoire projet/contacts

  • créer dans ce répertoire un script Python nommé form.py qui :

    • demande à l'utilisateur son nom, prénom et année de naissance
    • salue l'utilisateur en affichant son prénom et son nom en majuscule
  • exécution ipython :

In [18]:
run script
--------------------------------------------------
DÉBUT du script
--------------------------------------------------
Quel est votre nom? Davin
Coucou Davin!
-----------------------------------------------
FIN du script
-------------------------------------------------

  • exécution python :
$ python script.py

Import

  • import module
  • from module import nom
  • from module import nom as mon_nom

  • built-in : pas besoin d'import

  • standard library (shipped with) : import sans installation
  • pypi : plein de modules à installer qui n'attendent qu'à être importés
In [20]:
from datetime import datetime

date = datetime.now()
print date
#annee = ??
2013-09-19 15:53:30.559746

  • packages : importable si installé dans le path
In [21]:
import sys
sys.path
Out[21]:
['',
 '/home/giotta/machina/venv/mtlpy/local/lib/python2.7/site-packages/distribute-0.6.24-py2.7.egg',
 '/home/giotta/machina/venv/mtlpy/local/lib/python2.7/site-packages/pip-1.1-py2.7.egg',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/site-packages/distribute-0.6.24-py2.7.egg',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/site-packages/pip-1.1-py2.7.egg',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/plat-linux2',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/lib-tk',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/lib-old',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/lib-dynload',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-linux2',
 '/usr/lib/python2.7/lib-tk',
 '/home/giotta/machina/venv/mtlpy/local/lib/python2.7/site-packages',
 '/home/giotta/machina/venv/mtlpy/lib/python2.7/site-packages',
 '/home/giotta/machina/venv/mtlpy/local/lib/python2.7/site-packages/IPython/extensions']
  • dans le répertoire projet/contacts, créer un script Python nommé lib.py
  • déclarer la fonction age dans ce script
  • dans ipython, s'assurer d'être dans projet/contacts puis tester l'import de la fonction
In [22]:
import lib
mon_annee_naissance = 1975
lib.age(mon_annee_naissance)
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-22-15d8a38ba137> in <module>()
----> 1 import lib
      2 mon_annee_naissance = 1975
      3 lib.age(mon_annee_naissance)

ImportError: No module named lib
  • améliorer form.py en saluant le user qui a rempli le form et en lui donnant son âge

Modules

__init__.py __name__ __main__
  • __name__ : nom du module, c'est le nom de fichier si importé, affecté aussi à __main__ si exécuté (utile pour tests)
  • ajouter un fichier __init__.py dans le répertoire projet/contacts pour le convertir en module
  • créer un fichier tests.py à la racine du répertoire projet/ (pour créer une suite de tests)
  • importer la fonction age dans tests.py pour la tester

Modules tiers

https://pypi.python.org/

  • pypi = python packaging index
  • les modules qu'on importe vivent dans des paquets à installer sur notre système
  • identifier le paquet pertinent (sur pypi ou en parlant avec des Pythoneux)

Bases de données

  • DB : sqlite3, mysqldb, psycopg2
  • ORM : sqlalchemy

Developpement web

  • django (+south)
  • pyramid
  • flask

Science

  • numpy
  • matplotlib
  • pandas
  • scipy
Psychologie
  • psychopy

Administration système

  • fabric
  • celery
  • ...

Traitement des langues naturelles

  • nltk
  • pattern

  • installer avec pip

  • pip = pip installe python

Installation avec pip

  • pip installe les paquets sur votre machine
  • pour une meilleure gestion des paquets, utiliser virtualenv (couvert dans un autre atelier)
$ pip install nompaquet

Raccourcis syntaxiques

Formattage de chaînes de caractères

  • substitution : %
In [15]:
for n in range(10):
    print "La puissance 2 de %d est : %d" % (n, n**2)

for p in personnes:
    print "Bonjour %s %s" % (p['prenom'], p['nom'].upper())
La puissance 2 de 0 est : 0
La puissance 2 de 1 est : 1
La puissance 2 de 2 est : 4
La puissance 2 de 3 est : 9
La puissance 2 de 4 est : 16
La puissance 2 de 5 est : 25
La puissance 2 de 6 est : 36
La puissance 2 de 7 est : 49
La puissance 2 de 8 est : 64
La puissance 2 de 9 est : 81
Bonjour Davin BARAGIOTTA
Bonjour Mathieu LEDUC-HAMEL
Bonjour Jean-Philippe CAISSY

Compréhensions de liste, de dictionnaire, de set

  • créer une liste, un dictionnaire ou un set à partir d'un itérable avec un "one-liner"
new_list = [v for v in old_list if v < 2]
new_dict = {k, v for k, v in old_dict.items() if k < 2}
new_set = {v for v in old_list if v < 2}

Exceptions

  • try, except
In [ ]:
try:
    15/0
except (ZeroDivisionError,), e:
    print "Diviser par zéro c'est mal, vous voyez?"
    print e

Fichiers

  • ouvrir, manipuler, fermer
    • exemple de fichier : texte.txt
    • introspecter la fonction open pour voir comment ouvrir en écriture, lecture, ajout en fin de fichier... : r, w, a...
In [14]:
f = open('texte.txt')
for line in f.readlines():
    print line,
f.close()
Python est un langage que j'aime
et, paraît-il, son nom serait dérivé
du groupe d'humoristes britanniques Monty Python
et non de l'espèce de serpent ayant pour nom "python"


In [1]:
f = open("texte.txt")
lignes = f.readlines()
f.close()

cible = 'python'
contexte = [ligne for ligne in lignes if cible in ligne]
commentaires = [ligne for ligne in lignes if ligne.startswith('#')]

Permanence de l'information

  • fichiers
  • sérialisation : import pickle
In [23]:
import pickle

f = open('pickles', 'w')
pickle.dump(statuts, f)
pickle.dump(personnes, f)
f.close()

exit()

import pickle

f = open('pickles')
pickle.load(f)
#objets = []
#for obj in pickle.load(f):
#    objets.append(obj)
f.close()
  • en base de données?

CONCLUSION

  • import antigravity

  • documentation + interactivité + introspection

  • scripts + modules + import

  • communauté pour aider

  • Montréal-Python :

    • entrer dans la communauté
    • événements à venir
  • enjoy!

EXERCICE

Objectif

Créer un script flux.py dans le répertoire projet/actualites qui retournera les 5 dernières actualités affichées sur le site de Montréal-Python : http://montrealpython.org/fr/feed/

Approche

  1. utiliser feedparser
    • pip install feedparser
  2. lancer interpréteur et suivre exemple de la doc :
  3. introspecter (et imprimer dictionnaire pour voir ses clés) au besoin
  4. coder le script qui fera le traitement voulu
  5. lancer le script dans l'interpréteur pour confirmer son exécution correcte
  6. servir froid

Algorithme

  • capter le flux RSS de http://montrealpython.org
  • retenir le nombre d'items voulus
  • traiter les items retenus :
    • créer une chaîne de caractères unique : avec les infos des derniers items modifiés (titre, URL... et éventuellement la date de dernière modification)

Solution

Prenez le temps de coder vous-même une solution... ... ensuite vous pouvez comparer avec : le solutionnaire

Pour info, la solution ne fait que 8 lignes Python.