From ab9070c62c1b642d16506292d61bca9670987717 Mon Sep 17 00:00:00 2001 From: Dimitri Merejkowsky Date: Thu, 14 Feb 2019 15:38:34 +0100 Subject: [PATCH] Atelier 6 --- sessions/python-06.md | 215 ++++++++++++++++++++++++++++++++++++- sources/numbers/numbers.py | 14 +++ 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 sources/numbers/numbers.py diff --git a/sessions/python-06.md b/sessions/python-06.md index 1093666..37937fe 100644 --- a/sessions/python-06.md +++ b/sessions/python-06.md @@ -4,7 +4,7 @@ # -\center \huge Les classes +\center \huge Orienté objet et classes # Paradigmes @@ -250,3 +250,216 @@ class Car: * Instance: objet issue d'une classe * Méthode: fonction dans une classe (qui prend `self` en premier argument) * Attribut: variable dans un objet + +# + +\center \huge Modules + +# Un fichier = un module + +Et oui, vous faites des modules sans le savoir depuis le début :) + +Un fichier `foo.py` correspond au module `foo` + +# Attention + +C'est pas tout à fait réciproque. Le module `foo` peut venir d'autre chose +qu'un fichier. + +\vfill + +On y reviendra. + +# Importer un module + +Ou: accéder à du code provenant d'un *autre* fichier source. + + +```python +# Dans foo.py +a = 42 +``` + +\vfill + +```python +# Dans bar.py +import foo +print(foo.a) + +``` +\vfill + +* Affiche '42' + +# Espaces de noms +On dit aussi *namespace*. + +Du point de vue de `bar.py`, `a` est dans l'*espace de nom* foo. + +* On retrouve la syntaxe pour accèder à un attribut: `.`. +(ce n'est pas un hasard) + +* Les namespaces sont automatiques en Python + +# Importer dans le REPL + +```python +# dans foo.py + +def ma_fonction(): + return 42 +``` + +```python +# dans le REPL +>>> import foo +>>> foo.ma_fonction() +42 +``` + +* Plus sympa que de rajouter des `print()` à la fin de `foo.py` ;) + +# Les imports ne sont faits qu'une seule fois + +```python +# Dans foo.py +print("Je suis le module foo et tu viens de m’importer") + +``` + +```python +>>> import foo +Je suis le module foo et tu viens de m’importer +>>> import foo + +``` + +On retrouve le concept de *cache*. + +# Attention + +Il faudra donc redémarrer le REPL à chaque fois que le code change. + +Parfois, les gens conseillent d'utiliser `reload()` mais cette fonction n'est pas toujours fiable :/ + +# Un raccourci + +``` +>>> from foo import * +>>> ma_fonction() +42 +``` + +* Utile dans le REPL +* Pas une très bonne idée dans du vrai code + * On perd la trace de où vient la variable * Possibilité de collisions de noms + +# Retour sur les scripts + +Un script, par opposition à un module n'est pas censé être importé. + +Une solution est de mettre des tirets dans le nom: + +```python +# Dans foo.py +import my-script + +``` + +* Essaye de soustraire `script` à `my` +* ça ne fonctionne pas + + +# Retour sur main() + +La méthode `main()` ne *doit* pas être exécutée quand on importe le code! + +Solution: + +```python +# Dans foo.py +def my_function(): + # Fonction utile qui peut être ré-utilisée + +def main(): + # Fonction d'entrée principale + # Utilise my_function() + + +# magie! +if __name__ == "__main__": + main() +``` + + +# Explication (partielle) de la magie + +Le `if` n'est vrai *que* quand on lance `python3 foo.py`, mais pas quand on appelle `import foo` depuis +un autre module. + +La variable magique `__name__` est égale au nom du module quand il est importé, et à `__main__` sinon. + + +# La librarie standard (1) + +* Une collection de modules directement utilisables fournis à l'installation de Python. +* on a déjà vu `sys`, pour `sys.exit()` ou `sys.argv` + +# La librarie standard (2) + +Toute la librarie standard est documentée - même en Français. + +https://docs.python.org/fr/3/library/index.html + +* Gardez-là sous votre oreiller :) + +# La librarie standard (3) + +Beacoup de choses dedans. (*batteries included*) + +De quoi faire de la manipulation de texte, des statistiques, du réseau, de la concurrence, etc ... + + +# + +\center \huge Atelier + +# Jouons avec les API Web + +API web: un serveur avec qui on peut parler depuis un programme. + +Il en existe des quantités sur internet. + +Aujourd'hui on va utiliser `numbersapi.com` + +# Numbersapi + +Example: On fait une requête sur `http://numbersapi.com/42`, on récupère du texte +contenant un fait intéressant (*trivia* en anglais) à propos du nombre 42 . + +# Squelette + +```python +import sys +import urllib.request + +BASE_URL = "http://numbersapi.com/" + +def main(): + number = sys.argv[1] + url = BASE_URL = number + with urllib.request.urlopen(url) as request: + response = request.read().decode("utf-8") + print(response) + + +if __name__ == "__main__": + main() + +``` + +# Idée + +* Transformer ceci en une classe réutilisable +* Gérer les autres fonctionnalités de numbersapi.com (dates, tirages aléatoires, etc ...) diff --git a/sources/numbers/numbers.py b/sources/numbers/numbers.py new file mode 100644 index 0000000..e236a1b --- /dev/null +++ b/sources/numbers/numbers.py @@ -0,0 +1,14 @@ +import sys +import urllib.request + + +def main(): + number = sys.argv[1] + with urllib.request.urlopen("http://numbersapi.com/" + number) as request: + response = request.read().decode("utf-8") + print(response) + + +if __name__ == "__main__": + main() +