198 lines
13 KiB
Plaintext
198 lines
13 KiB
Plaintext
== Boite à outils
|
||
|
||
=== Python
|
||
|
||
Le langage https://www.python.org/[Python] est un https://docs.python.org/3/faq/general.html#what-is-python[langage de programmation] interprété, interactif, orienté objet (souvent), fonctionnel (parfois), open source, multi-plateformes, flexible, facile à apprendre et difficile à maîtriser.
|
||
|
||
.https://xkcd.com/353/
|
||
image::images/xkcd-353-python.png[]
|
||
|
||
A première vue, certains concepts restent difficiles à aborder: l'indentation définit l'étendue d'un bloc (classe, fonction, méthode, boucle, condition, ...), il n'y a pas de typage fort des variables et le compilateur n'est pas là pour assurer le filet de sécurité avant la mise en production (puisqu'il n'y a pas de compilateur 😛).
|
||
Et malgré ces quelques points, Python reste un langage généraliste accessible et "bon partout", et de pouvoir se reposer sur un écosystème stable et fonctionnel.
|
||
|
||
Il fonctionne avec un système d'améliorations basées sur des propositions: les PEP, ou "**Python Enhancement Proposal**".
|
||
Chacune d'entre elles doit être approuvée par le http://fr.wikipedia.org/wiki/Benevolent_Dictator_for_Life[Benevolent Dictator For Life].
|
||
|
||
Si vous avez besoin d'un aide-mémoire ou d'une liste exhaustive des types et structures de données du langage, référez-vous au lien suivant: https://gto76.github.io/python-cheatsheet/[Python Cheat Sheet].
|
||
|
||
NOTE: Le langage Python utilise un typage dynamique appelé https://fr.wikipedia.org/wiki/Duck_typing[*duck typing*]: "_When I see a bird that quacks like a duck, walks like a duck, has feathers and webbed feet and associates with ducks — I’m certainly going to assume that he is a duck_" (Source: http://en.wikipedia.org/wiki/Duck_test[Wikipedia (as usual)]).
|
||
|
||
==== PEP8 - Style Guide for Python Code
|
||
|
||
La première PEP qui va nous intéresser est la https://www.python.org/dev/peps/pep-0008/[PEP 8 -- Style Guide for Python Code]. Elle spécifie comment du code Python doit être organisé ou formaté, quelles sont les conventions pour l’indentation, le nommage des variables et des classes, ...
|
||
En bref, elle décrit comment écrire du code proprement, afin que d’autres développeurs puissent le reprendre facilement, ou simplement que votre base de code ne dérive lentement vers un seuil de non-maintenabilité.
|
||
|
||
Dans cet objectif, un outil existe et listera l'ensemble des conventions qui ne sont pas correctement suivies dans votre projet: pep8. Pour l'installer, passez par pip. Lancez ensuite la commande pep8 suivie du chemin à analyser (`.`, le nom d'un répertoire, le nom d'un fichier `.py`, ...). Si vous souhaitez uniquement avoir le nombre d'erreur de chaque type, saisissez les options `--statistics -qq`.
|
||
|
||
|
||
[source,bash]
|
||
----
|
||
$ pep8 . --statistics -qq
|
||
|
||
7 E101 indentation contains mixed spaces and tabs
|
||
6 E122 continuation line missing indentation or outdented
|
||
8 E127 continuation line over-indented for visual indent
|
||
23 E128 continuation line under-indented for visual indent
|
||
3 E131 continuation line unaligned for hanging indent
|
||
12 E201 whitespace after '{'
|
||
13 E202 whitespace before '}'
|
||
86 E203 whitespace before ':'
|
||
----
|
||
|
||
Si vous ne voulez pas être dérangé sur votre manière de coder, et que vous voulez juste avoir un retour sur une analyse de votre code, essayez `pyflakes`: cette librairie analysera vos sources à la recherche de sources d'erreurs possibles (imports inutilisés, méthodes inconnues, etc.).
|
||
|
||
Il existe une solution qui couvre ces deux domaines: https://github.com/PyCQA/flake8[flake8].
|
||
Sur base de la même interface que `pep8`, vous rencontreez en plus tous les avantages liés à `pyflakes`
|
||
|
||
|
||
==== PEP257 - Docstring Conventions
|
||
|
||
Python étant un langage interprété fortement typé, il est plus que conseillé, au même titre que les tests unitaires, de documenter son code.
|
||
Cela impose une certaine rigueur, mais améliore énormément la qualité (et la reprise) du code par une tierce personne. Cela implique aussi de **tout** documenter: les modules, les paquets, les classes, les fonctions, méthodes, ... Tout doit avoir un *docstring* associé :-).
|
||
|
||
WARNING: Documentation: be obsessed!
|
||
|
||
Il existe plusieurs types de conventions de documentation:
|
||
|
||
. PEP 257
|
||
. Numpy
|
||
. Google Style (parfois connue sous l'intitulé `Napoleon`)
|
||
. ...
|
||
|
||
Les https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings[conventions proposées par Google] nous semblent plus faciles à lire que du RestructuredText, mais sont parfois moins bien intégrées que les docstrings officiellement supportées (typiquement, par exemple par https://clize.readthedocs.io/en/stable/[clize] qui ne reconnait que du RestructuredText).
|
||
L'exemple donné dans les styleguide est celui-ci:
|
||
|
||
[source,python]
|
||
----
|
||
def fetch_smalltable_rows(table_handle: smalltable.Table,
|
||
keys: Sequence[Union[bytes, str]],
|
||
require_all_keys: bool = False,
|
||
) -> Mapping[bytes, Tuple[str]]:
|
||
"""Fetches rows from a Smalltable.
|
||
|
||
Retrieves rows pertaining to the given keys from the Table instance
|
||
represented by table_handle. String keys will be UTF-8 encoded.
|
||
|
||
Args:
|
||
table_handle: An open smalltable.Table instance.
|
||
keys: A sequence of strings representing the key of each table
|
||
row to fetch. String keys will be UTF-8 encoded.
|
||
require_all_keys: Optional; If require_all_keys is True only
|
||
rows with values set for all keys will be returned.
|
||
|
||
Returns:
|
||
A dict mapping keys to the corresponding table row data
|
||
fetched. Each row is represented as a tuple of strings. For
|
||
example:
|
||
|
||
{b'Serak': ('Rigel VII', 'Preparer'),
|
||
b'Zim': ('Irk', 'Invader'),
|
||
b'Lrrr': ('Omicron Persei 8', 'Emperor')}
|
||
|
||
Returned keys are always bytes. If a key from the keys argument is
|
||
missing from the dictionary, then that row was not found in the
|
||
table (and require_all_keys must have been False).
|
||
|
||
Raises:
|
||
IOError: An error occurred accessing the smalltable.
|
||
"""
|
||
----
|
||
|
||
C'est-à-dire:
|
||
|
||
. Une courte ligne d'introduction, descriptive, indiquant ce que la fonction ou la méthode réalise. Attention, la documentation ne doit pas indiquer _comment_ la fonction/méthode est implémentée, mais ce qu'elle fait concrètement (et succintement).
|
||
. Une ligne vide
|
||
. Une description plus complète et plus verbeuse
|
||
. Une ligne vide
|
||
. La description des arguments et paramètres, des valeurs de retour (+ exemples) et les exceptions qui peuvent être levées.
|
||
|
||
Un exemple (encore) plus complet peut être trouvé https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google[dans le dépôt sphinxcontrib-napoleon].
|
||
|
||
Pour ceux que cela pourrait intéresser, il existe https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring[une extension pour Codium], comme nous le verrons juste après, qui permet de générer automatiquement le squelette de documentation d'un bloc de code:
|
||
|
||
.autodocstring
|
||
image::images/environment/python-docstring-vscode.png[]
|
||
|
||
=== Environnement de développement
|
||
|
||
Concrètement, nous pourrions tout à fait nous limiter à Notepad ou Notepad++.
|
||
Mais à moins d'aimer se fouetter avec un câble USB, nous apprécions la complétion du code, la coloration syntaxique, l'intégration des tests unitaires et d'un debugger, ainsi que deux-trois sucreries qui feront plaisir à n'importe quel développeur.
|
||
|
||
Si vous manquez d'idées ou si vous ne savez pas par où commencer:
|
||
|
||
* https://vscodium.com/[VSCodium], avec les plugins https://marketplace.visualstudio.com/items?itemName=ms-python.python[Python]et https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens[GitLens]
|
||
* https://www.jetbrains.com/pycharm/[PyCharm]
|
||
* https://www.vim.org/[Vim] avec les plugins https://github.com/davidhalter/jedi-vim[Jedi-Vim] et https://github.com/preservim/nerdtree[nerdtree]
|
||
|
||
Si vous hésitez, et même si Codium n'est pas le plus léger (la faute à https://www.electronjs.org/[Electron]...), il fera correctement son travail (à savoir: faciliter le vôtre), en intégrant suffisament de fonctionnalités qui gâteront les papilles émoustillées du développeur impatient.
|
||
|
||
.Codium en action
|
||
image::images/environment/codium.png[]
|
||
|
||
=== Un terminal
|
||
|
||
_A priori_, les IDE footnote:[Integrated Development Environment] proposés ci-dessus fournissent par défaut ou _via_ des greffons un terminal intégré.
|
||
Ceci dit, disposer d'un terminal séparé facilite parfois certaines tâches.
|
||
|
||
A nouveau, si vous manquez d'idées:
|
||
|
||
. Si vous êtes sous Windows, téléchargez une copie de https://cmder.net/[Cmder]. Il n'est pas le plus rapide, mais propose une intégration des outils Unix communs (`ls`, `pwd`, `grep`, `ssh`, `git`, ...) sans trop se fouler.
|
||
. Pour tout autre système, vous devriez disposer en natif de ce qu'il faut.
|
||
|
||
.Mise en abîme
|
||
image::images/environment/terminal.png[]
|
||
|
||
=== Un gestionnaire de base de données
|
||
|
||
Django gère plusieurs moteurs de base de données.
|
||
Certains sont gérés nativement par Django (PostgreSQL, MariaDB, SQLite); _a priori_, ces trois-là sont disponibles pour tous les systèmes d'exploitation. D'autres moteurs nécessitent des librairies tierces (Oracle, Microsoft SQL Server).
|
||
|
||
Il n'est pas obligatoire de disposer d'une application de gestion pour ces moteurs: pour les cas d'utilisation simples, le shell Django pourra largement suffire (nous y reviendrons).
|
||
Mais pour faciliter la gestion des bases de données elles-même, et si vous n'êtes pas à l'aise avec la ligne de commande, choisissez l'une des applications d'administration ci-dessous en fonction du moteur de base de données que vous souhaitez utiliser.
|
||
|
||
* Pour *PostgreSQL*, il existe https://www.pgadmin.org/[pgAdmin]
|
||
* Pour *MariaDB* ou *MySQL*, partez sur https://www.phpmyadmin.net/[PHPMyAdmin]
|
||
* Pour *SQLite*, il existe https://sqlitebrowser.org/[SQLiteBrowser]
|
||
PHPMyAdmin ou PgAdmin.
|
||
|
||
|
||
=== Un gestionnaire de mots de passe
|
||
|
||
Nous en auront besoin pour gé(né)rer des phrases secrètes pour nos applications.
|
||
Si vous n'en utilisez pas déjà un, partez sur https://keepassxc.org/[KeepassXC]: il est multi-plateformes, suivi et s'intègre correctement aux différents environnements, tout en restant accessible.
|
||
|
||
image::images/environment/keepass.png[]
|
||
|
||
|
||
=== Un système de gestion de versions
|
||
|
||
Il existe plusieurs systèmes de gestion de versions.
|
||
Le plus connu à l'heure actuelle est https://git-scm.com/[Git], notamment pour sa (très) grande flexibilité et sa rapidité d'exécution.
|
||
Il est une aide précieuse pour développer rapidement des preuves de concept, switcher vers une nouvelle fonctionnalité, un bogue à réparer ou une nouvelle release à proposer au téléchargement.
|
||
Ses deux plus gros défauts concerneraient peut-être sa courbe d'apprentissage pour les nouveaux venus et la complexité des actions qu'il permet de réaliser.
|
||
|
||
.https://xkcd.com/1597/
|
||
image::images/xkcd-1597-git.png[]
|
||
|
||
Même pour un développeur solitaire, un système de gestion de versions (quel qu'il soit) reste indispensable.
|
||
|
||
Chaque "*branche*" correspond à une tâche à réaliser: un bogue à corriger (_Hotfix A_), une nouvelle fonctionnalité à ajouter ou un "_truc à essayer_" footnote:[Oui, comme dans "Attends, j'essaie vite un truc, si ça marche, c'est beau."] (_Feature A_ et _Feature B_).
|
||
Chaque "*commit*" correspond à une sauvegarde atomique d'un état ou d'un ensemble de modifications cohérentes entre elles.footnote:[Il convient donc de s'abstenir de modifier le CSS d'une application et la couche d'accès à la base de données, sous peine de se faire huer par ses relecteurs au prochain stand-up.]
|
||
De cette manière, il est beaucoup plus facile pour le développeur de se concenter sur un sujet en particulier, dans la mesure où celui-ci ne doit pas obligatoirement être clôturé pour appliquer un changement de contexte.
|
||
|
||
.Git en action
|
||
image::images/diagrams/git-workflow.png[]
|
||
|
||
Cas pratique: vous développez cette nouvelle fonctionnalité qui va révolutionner le monde de demain et d'après-demain, quand, tout à coup (!), vous vous rendez compte que vous avez perdu votre conformité aux normes PCI parce les données des titulaires de cartes ne sont pas isolées correctement.
|
||
Il suffit alors de
|
||
|
||
. sauver le travail en cours (`git add . && git commit -m [WIP]`)
|
||
. revenir sur la branche principale (`git checkout main`)
|
||
. créer un "hotfix" (`git checkout -b hotfix/pci-compliance`)
|
||
. solutionner le problème (sans doute un `;` en trop ?)
|
||
. sauver le correctif sur cette branche (`git add . && git commit -m "Did it!"`)
|
||
. récupérer ce correctif sur la branche principal (`git checkout main && git merge hotfix/pci-compliance`)
|
||
. et revenir tranquillou sur votre branche de développement pour fignoler ce générateur de noms de dinosaures rigolos que l'univers vous réclame à cor et à a cri (`git checkout features/dinolol`)
|
||
|
||
Finalement, sachez qu'il existe plusieurs manières de gérer ces flux d'informations.
|
||
Les plus connus sont https://www.gitflow.com/[Gitflow] et https://www.reddit.com/r/programming/comments/7mfxo6/a_branching_strategy_simpler_than_gitflow/[Threeflow]. |