Cette présentation est soumise à licence
Les exemples de code sont aussi soumis à licence
En gros, vous faites ce que vous voulez mais citez au moins l'auteur de l'original... Merci!
Attention, je vais pas mal bâcher le language C (et C++). J'en ai fait pendant des années et j'en produis encore donc... #SansRancune
#Python4Ever
vs
Développeurs "débutants" en Python, ayant - malheureusement - éventuellement quelques connaissances en C
#C/C++Bashing
#JeVousAvaisPrévenus
Python est multi-palteforme mais pour le dev, préférez un Linux ou un Mac car Windows... c'est le mal!
void quiCompliqueTout(bool faitCi, bool faitCa) {
if (faitCi) {
if (faitCa) {
printf("euh....");
}
else {
print("ah...");
}
}
}
Qu'est-il affiché lorsqu'on appelle:
quiCompliqueTout(0, 1); // faitCi = false et faitCa = true
def quiCompliqueTout(bool faitCi, bool faitca):
if faitCi:
if faitca:
print("euh....")
else:
print("ah...")
Plus lisible non ? on aurait répondu sans se casser la tête à la même question:
quiCompliqueTout(0, 1) # faitCi = false et faitCa = true
Attention donc à bien configurer votre éditeur. Conseil: spaces only!
Si perf très critique, possibilité de mixer avec du code compilé
...assez discuté, les mains dans le cambouis, y'a que ça de vrai !
par pitié... utilisez tout de suite un gestionnaire de source...
Allez hop ! subversion ou (carrément) mieux: git init
J'ai dit:
#OuiJeVaisBacherSVNAussi
En C, il y a autant de styles de codage (décrits dans des documents interminables) que de développeurs/équipes. En python, on est libre aussi mais il existe un standard: PEP8 à suivre car une écrasante majorité de la communauté l'utilise
Ah ... au fait... TOUT ou RIEN en anglais, pas un "franglais" pourri
Il y en a plein... dont de bien lourds (Eclipse/PyDev) mais je conseille absolument Sublime Text
avec cette config
En plus, vous savez quoi ? Sublime est écrit en.... Python ;)
Cette présentation n'est qu'une petite introduction à Python.
Il existe de nombreux tutos et MOOC mais la doc officielle est une petite tuerie à conserver dans un onglet de votre navigateur
#!/usr/bin/python
print("Hello world!")
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello world!")
Hello world!
>>>
dans un interpréteur:
ou en exécutant le fichier:
[code]
python hello_world.py
Pas de déclaration de type comme en C, l'interpréteur se débrouille... très bien !
#DeroutantAuDebut
#PasDePanique
const char* ma_chaine = "une jolie chaine !";
ma_chaine = "une jolie chaine !"
first = "Pierre" # double quote
last = 'Roth' # single quote
cv = """
Mon CV
sur
plusieurs lignes
"""
contact = '''
pierreroth4@gmail.com
@pierreroth64
'''
Ecrire un script qui affiche:
Pierre Roth
Parcours
--
Mon CV
sur
plusieurs lignes
Contact
--
pierreroth4@gmail.com
@pierreroth64
[code]
user_nb = 5
same_user_nb = int("5")
pi = 3.14159265359
bon... on va pas épiloguer là-dessus, hein ? ;-)
Lorsqu'une valeur n'est pas définie, sa valeur est None.
En C/C++, on utilise NULL (valeur 0) pour ça... mais justement parce que 0 == NULL, c'est pas toujours évident.
Les listes sont des conteneurs d'éléments qui peuvent être hétérogènes
>>> user_list = ["Pierre"]
>>> user_list.append("Cedric")
>>> print user_list
['Pierre', 'Cedric']
>>> others = ["Manu", 12, 3.14]
>>> user_list += others
>>> print user_list
['Pierre', 'Cedric', 'Manu', 12, 3.14]
>>> print user_list[1]
Cedric
>>> user_list.pop()
3.14
>>> print user_list
['Pierre', 'Cedric', 'Manu', 12]
[code]
De mon point de vue, le conteneur de données le plus intéressant / puissant. Permet de stocker les infos sous forme de clé/valeur.
company_info = {
'name': 'My super company',
'address': '45, beautiful avenue, blabla, France',
'number of employees': 3,
'employees': [
"Pierre",
"Cedric",
"Manu"
],
'contact': {
'email': 'contact@my-super-company.com',
'phone': '+33 567874332'
}
}
[code]
Allez, on joue avec ?
#NePasOublierDeCommiter
# ET logique
a and b
# OU logique
a or b
# Negation
not a
# On complique un peu, mais lisible non ?
# ...langage naturel :)
a and not (b or c)
if, else, while, for, ... tous les mots clés que vous connaissez déjà mais à la mode Python, c'est à dire lisible donc maintenable
AGE_LIMIT = 70
age = 23
is_a_boy = True
is_young = (age <= AGE_LIMIT)
if is_a_boy and not is_young:
print 'Your are an "old" man... (above %d years old)' % AGE_LIMIT
[code]
index = 0
while index < 5:
print index
index += 1
[code]
Bon, on code ? parce que les slides... c'est bien mais...
numbers = [2, 3, 7, 8, 90, 8, 8, 8]
odds = [number for number in numbers if number % 2]
print "odds:", odds
[code]
...ou comment créer une liste à partir d'une autre et de critères de façon concise
Ca semble obscur au début mais après un peu de pratique, vous en abuserez!
identiques à ce que vous connaissez en C mais avec des améliorations considérables comme:
On peut passer les arguments comme en C... mais aussi en nommant les paramètres!
#VousVousDemandezPourquoi :)
def my_funny_routine(greet, name):
'''This routine prints a greeting to the console'''
print("%s %s!" % (greet, name))
# traditional (C-like)
my_funny_routine('Hello', 'Cedric')
# Named args
my_funny_routine(greet='Hello', name='Cedric')
# ... identical to:
my_funny_routine(name='Cedric', greet='Hello')
Et si on ne passe pas tel ou tel argument ? Chouette, Python propose des valeurs par défaut :)
def my_funny_routine(name, greet='Hello'):
'''This routine prints a greeting to the console'''
print("%s %s!" % (greet, name))
# same output for these two calls:
my_funny_routine(name='Cedric', greet='Hello')
my_funny_routine(name='Cedric')
[code]
#OnCodeEtOnTeste ?
ou carrément mieux...
#OnEcritUnTestPuisOnCode
Permet de définir des fonctions qui n'ont pas de nombre d'arguments prédéfini.
def my_varargs_routine(*args, **kwargs):
# args is a list of unamed args
# kwargs is a dictionary of named args
pass
Dangereux et à réserver pour des cas bien précis (par exemple: shell)
def display_greeting(msg, name):
'''
Display a greeting to the console
msg is the greeting message
name is the username to greet
'''
print("%s %s!" % (msg, name))
Un fichier c'est bien mais généralement, vous codez plusieurs fonctionnalités que vous organisez dans plusieurs modules, packages
├── __init__.py
├── conf
│ ├── donothingreader.py
│ ├── factory.py
│ ├── __init__.py
│ └── jsonreader.py
├── core
│ ├── exceptions.py
│ ├── __init__.py
│ └── log.py
├── drivers
│ ├── basedriver.py
│ ├── dummydriver.py
│ ├── __init__.py
│ └── serialdriver.py
├── ...
Pour faire court :
def display_msg(msg="default message"):
'''Display message to the console'''
print('msg:' + msg)
def display_short_msg(msg):
'''Display short message to the console'''
print(msg)
display.py
# only import one routine
from display import print_msg
print_msg('hey!')
print_short_msg --> Error!
# or import the whole module
import display
display.print_msg('hey!')
display.print_short_msg('hey!')
main.py
[code]
#DontForgetToCommit
Variable d'environnement qui permet de spécifier à l'interpréteur Python où aller chercher ses packages.
On en reparlera au moment des exos plus poussés
Les packages que vous utiliserez dans votre application:
#CestMaintenantQueVousAllezTomberEnAmour
A partir de maintenant, PyPi est votre meilleur ami !
[code]
Si vous aviez à afficher une barre de progression, vous le feriez réellement à la main ?
hints: pip installer, progressbar
Pour faire de son code un joli package installable !
[code]
"Hey ! si ton code dépend de N librairies externes, t'es mignon mais je fais comment moi pour m'y retrouver et utiliser ton script ?"
Pour les dépendances de développement, j'utilise pip qui prend en entrée un fichier requirements.txt
peio@tux-cf-53:~/python-startup/examples/06-files/refactoring [master]$ cat requirements.txt
pytest
pep8
nose
L'avantage avec Python, c'est qu'on peut faire du procédural et de l'objet !
Une classe est un modèle et un objet est une instance de ce modèle
class User(object):
'''
The User class!
'''
def __init__(self, first, last):
'''This is the constructor'''
self.first = first
self.last = last
def get_fullname()
'''Get the user fullname'''
return self.first +
", the marvellous " +
self.last + "!"
me = new User('Pierre', Roth')
ced = new User('Cedric', 'Jourdain')
diego = new User('Diego', 'Felipe')
print(ced.get_fullname())
>>>> Cedric, the marvellous Jourdain!
Définition d'une classe User
Définition d'objets User
def do_that(data):
if data['name'] is None:
return -1
def do_this(data):
if data is None:
return -2
rc = do_that(data)
if rc != 0:
return rc
data['another"] = 12
return do_that(data)
if __name__ == "__main__":
rc = do_this(None)
if rc == 0:
rc = do_this({"name": "me"})
if (rc == -1):
print("data does not contain 'name'")
elif (rc == -2):
print("data is None!")
def do_that(data):
if data['name'] is None:
raise Exception("data does not contain 'name'")
def do_this(data):
if data is None:
raise Exception("data is None!")
do_that(data)
data['another"] = 12
do_that(data)
if __name__ == "__main__":
try:
do_this(None)
do_this({"name": "me"})
except Exception as error:
print "An error occured: %s" % error
try ... except
Allez on s'y colle, voici les specs:
[code]
#AVousDeJouer
#SifflezSiBloqué
#CommitAChaqueEtapeEtCheckPEP8
Quelques questions "innocentes":
"Always leave the campground cleaner than you found it."
[code]
Cette solution - loin d'être idéale - reprend quelques concepts: SOLID pour encaisser plus facilement les changements.
Par exemple:
On n'en parle "que" maintenant mais on aurait dû attaquer par ça. Approche TDD qui permet une démarche architecturale et du code minimum.
#RefactorOnGreen
Lisez leur doc et installez-les, ça devrait prendre 2 minutes, n'est ce pas... !? ;o)
Un seul mot: I.N.D.I.S.P.E.N.S.A.B.L.E
[exemple]
En développement Agile (type SCRUM), on livre tout régulièrement, c'est à dire le bundle {code + tests + doc} Un tout cohérent à chaque itération.
Pour la génération de doc, je conseille le super outil sphinx
cd examples/06-files/refactoring
make doc-pdf
Windows n'est pas un environnement pour développeur
#FailOnWindows
#RTFM
Petit exercice
quote = {}
quote['content'] = 'Si tu lis la doc, tu fais partie du top 1% des développeurs'
quote['author'] = 'Christophe Porteneuve'
quote['company'] = 'Delicious Insights'
#PourLesWarriors
Pour faciliter le travail des contributeurs à votre code, c'est souvent pas mal d'ajouter une couche d'abstraction aux commandes habituelles.
Me concernant, j'utilise un bon vieux makefile...
peio@tux-cf-53:~/Desktop/perso/python-startup/examples/06-files/refactoring [master]$ make
Cheking PEP8 coding style...
Done.
Running tests...
PYTHONPATH=. nosetests -v
Test the decoding when a correct file is given ... ok
test_json_decoder.test_json_bad_format ... ok
test_json_decoder.test_json_not_found ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.029s
OK
#MerciPourVotreEcoute