Comme promis suite à cet échange avec Mateo21, voici un retour critique, argumenté et constructif sur le cours « Démarrez votre projet avec Python ». Tel que celui-ci aurait été reçu à la validation sur ZdS
Vu l'ampleur du boulot, et le temps que j'ai de disponible, je vais m'y prendre partie par partie.
Les vidéos ne m'intéressant pas, je me bornerai, comme entwanne hier soir, au texte écrit.
EDIT: Je suis revenu pour commenter la suite, mais cette horripilante limite des 24h me force à mettre mon commentaire à la suite de ce message, plutôt que pouvoir le reposter.
Disclaimer : Je rappelle à toutes fins utiles que ce commentaire se veut
constructif. Mon but n'est pas de descendre ce tuto en flèche, mais de le juger
objectivement tout en proposant des améliorations.
Préambule
Je tiens à noter en préambule que j'aime bien la dynamique et l'énergie qui se dégagent du texte. Le ton est parfaitement maîtrisé, c'est sympa à lire, ça s'articule bien. Là dessus, chapeau, le texte est de bonne facture. Ma critique se bornera donc au fond, et non à la forme.
Pas mal. "C'est facile à apprendre, utile en milieu professionnel, et on va
faire un projet rigolo". Le cours est très bien ciblé, je suppose, par rapport
à son public et son objectif.
Python est un langage parfait pour débuter. Il fonctionne sur tous les
systèmes d’exploitation (Windows, Mac et Linux) et vous n’avez pas à utiliser
un logiciel spécifique pour voir le résultat de votre code. Vous avez juste
besoin d’un ordinateur. Et de votre tête. Alouette.
Le ton est génial, mais la phrase confuse, voire carrément fausse : il y a besoin de
l'interpréteur installé sur l'ordinateur. Autant ce n'est pas du tout un
problème sous Mac OS ou Linux, mais sous Windows, en revanche, ce point est
source d'embrouilles, en particulier pour les débutants, qui galèrent à trouver
une façon propre de distribuer leur programme.
Vu que ce cours n'a probablement pas pour objectif de s'attaquer à ce problème
épineux (pour lequel il n'existe aucune solution qui sorte du lot aujourd'hui),
je virerais purement et simplement cette mention. Peut-être voulais-tu dire
qu'il n'y avait pas besoin d'un IDE spécifique ou d'un compilateur… mais là,
ton lecteur est débutant, il n'a aucune idée de tout ça.
Bonne idée… en ce moment le domaine est en plein boum. Les entreprises galèrent
à trouver des bons profils, donc ça paye. En tout cas le secteur n'est pas
bouché.
Le débat Python 2 versus Python 3 continue de faire rage, même si de plus en
plus de développeurs se rangent vers la dernière version. Cela va faire
bientôt 10 ans qu’elle est sortie et les modules les plus utilisés ont déjà
migré à Python 3. C’est pourquoi j’utiliserai cette version dans ce cours.
J'aurais accepté de lire ça dans un tutoriel en 2012 ou 2013, mais là, même la
Python Software Foundation a un parti pris beaucoup plus prononcé : Python 2
est obsolète. Il est encore utilisé sporadiquement par des programmes un
peu critiques dont les entreprises n'estiment pas qu'il est rentable de les
porter, mais aujourd'hui, en 2017, Python, c'est Python 3.6. On est quand même
une version majeure et SIX versions mineures au dessus de la dernière vraie
version de Python 2 (2.6), sachant que 2.7 est une
version de transition dans laquelle certaines fonctionnalités sont backportées pour
faciliter le travail de migration.
Bref, à ta place, je me mouillerais un peu plus dans ce débat : tu n'as pas
besoin de marcher sur des œufs. Cela dit je salue la transparence qui consiste
à mentionner l'existence des deux versions parallèles.
Sous Mac et Windows
Je ne me prononce pas.
Sous Linux
Il faut inciter plus fortement que ça à utiliser apt-get. Les deux options
que tu présentes ne sont pas équivalentes : installer la version de Python 3
supportée nativement par l'OS est beaucoup plus confortable (et je suppose
que tu ne vas pas parler d'asyncio dans ce cours, donc le lecteur s'en fout d'avoir la dernière version
s'il a au moins Python 3.4, soit le cas 99.99 fois sur 100 aujourd'hui ).
Si tu tiens toujours à parler de la compilation depuis les sources, il faut
alors ne pas oublier de citer toutes les dépendances. Sous Ubuntu :
le package build-essential (qui apporte make, gcc et consorts)
les bibliothèques libssl, zlib, TCL-tk, (j'en oublie), tout ça en version
-dev.
… Tu te sens de supporter les armées de débutants qui sont en train
d'essayer de compiler l'interpréteur et qui sont totalement perdus sur le forum ?
Oui ?
Ok. J'enfonce le clou. Après 10 ans à faire du Python sous Linux, je suis encore aujourd'hui obligé de me taper des allers retours entre la configuration de la compilation et le gestionnaire de paquets pour installer les dépendances qui me manquent pour compiler Python, soit 3 ou 4 boucles à lire la sortie de la config, apt-cache search et sudo apt-get install. Alors certes je le fais pas tous les 4 matins non plus, mais je sais ce qui se passe à chaque étape et lire la sortie des différents scripts.
Le débutant, tu le sens toujours capable d'y arriver en moins d'une demi-journee ?
Non ?
Je m'en doutais.
Quitte à ne pas être exhaustif, autant éviter d'induire les gens en erreur.
Typiquement un débutant sous Fedora ou Suze devrait utiliser yum au lieu de
apt-get, mais ton texte l'incite à compiler les sources à la place.
Tu ne t'en rends peut-être pas compte, mais la seule raison pour laquelle je
comprends ce dont tu parles, c'est parce que j'ai vu sur un screenshot plus
loin que tu tournes sur un Mac… Et parce que j'utilise le shell comme je
respire sur mon ordi. Par contre, là, le type qui tourne sous Windows et qui ne
connait pas grand chose à tout ça, tu viens de le perdre.
Je trouve ce paragraphe un peu gratuit, et clivant : utiliser la console sous
Windows est une plaie. Ce serait bien d'être sympa avec les utilisateurs de
Windows en mentionnant IDLE, ou un terminal alternatif comme console2.
Découvrez le vocabulaire de Python
On en arrive au point chaud, le mètre-étalon qui sert à comparer tous les tutos
Python au premier coup d'oeil : la définition d'une variable. Et au premier
coup d'œil tu t'en sors… pas trop mal, à vrai dire, mais il y a des trucs à
corriger impérativement, à commencer par le plus critique :
Une variable stocke une information dans la mémoire de l’ordinateur tant que
l’interpréteur Python est ouvert.
S'il y a une notion qui, mal apprise/comprise, peut rendre tout un
apprentissage de Python à refaire, c'est la notion sous-entendue par ce petit
verbe: « stocker ». On est en plein dans ce que j'écrivais plus haut : je
t'attendais au tournant précisément là-dessus. Et je vais me permettre
d'insister lourdement sur ce sujet.
Avant d'objecter que tu as un parti pris uniquement pratique et que je suis en
train de pinailler sur la théorie, il faut bien comprendre que, d'une façon ou
d'une autre, le but de ton cours est que le débutant acquière la bonne
intuition de ce que sont les variables. En fait, les années d'aide dispensée
sur les forums m'ont appris que c'est la notion sur laquelle il ne faut surtout
pas se rater, parce qu'elle influence la compréhension du programmeur sur tout
le reste de son langage. À ce titre, il ne suffit pas de donner des
informations "exactes", ou "pas fausses", il faut à tout prix essayer de donner
la bonne représentation mentale, ou la bonne métaphore, si tu préfères.
En Python, une variable n'a rien, mais vraiment, rien à voir avec le
stockage des données. Dans le mind set du développeur Python, la mémoire est
un non-problème, les objets flottent dans un bouillon de mémoire : ils sont là
quand on en a besoin, et ils disparaissent par magie quand ils ne servent plus
à rien. En toute rigueur, si tu vas jeter un oeil au code-source de l'interpréteur Python standard,
une variable ce n'est rien d'autre que l'association,
dans un dictionnaire (le scope lexical), d'un nom et d'une référence sur un objet…
Alors bien sûr on ne va pas présenter les choses comme ça aux débutants, il
faut leur donner une image, et je vais me permettre de te proposer celle qui est communément admise comme la plus juste : le débutant
doit s'ancrer dans le crâne qu'une variable est un nom qu'on donne aux
choses, point barre. Si on part de là, la métaphore la plus naturelle pour
donner un nom à une chose est de lui coller une étiquette avec son nom dessus.
Dans ton texte au contraire, à partir du moment où tu utilises le terme
stocker, le lecteur va immédiatement se représenter une variable comme une
boîte, un carton avec un volume suffisant pour contenir une donnée : c'est
vrai en C, et cette métaphore n'est pas déconnante dans ce langage. Mais si tu
commences à réfléchir avec des boîtes, tu n'as aucun moyen intuitif de
comprendre la notion de référence, alors qu'elle est centrale en Python
puisque tout est une référence.
On pourrait rétorquer à quoi bon s'encombrer de références ? Eh bien parce que sur un forum Python, tu vas retrouver, dans à peu près 10% des posts, un débutant complet qui ne comprend pas pourquoi tel code a modifié telle liste, et que LA clé pour éviter toute cette confusion et cette frustration, c'est systématiquement de lui expliquer
que c'est parce qu'il manipule plusieurs références sur le même objet.
Je ne dis pas qu'il faut expliquer ça tout de suite. Mais il faut a minima préparer le terrain, et préparer le terrain c'est déjà ne pas mettre cette image, très fausse, de boîtes en carton dans lesquelles on stocke des valeurs, au profit de celle de l'étiquette.
L'étiquette, elle, peut être décollée d'un objet pour être collée sur un autre,
elle peut être détruite sans détruire l'objet qu'elle nomme, et surtout sa
taille ne varie pas selon l'objet sur lequel elle est collée : elle ne coûte
rien ! Si on va dans des considérations encore plus avancées d'un point de vue
technique, lorsque tu crées une variable dans le scope local, tu te donnes le
moyen de retrouver ton objet plus vite, ce qui colle plutôt bien à cette
optimisation facile en Python, qui consiste à créer une variable locale avant
d'entrer dans une boucle pour éviter de réaliser indirections à l'intérieur.
Et la métaphore ne s'arrête pas là. Pense à cette annonce en gare de la
SNCF : « Nous vous demandons d'étiquer tous vos bagages. Tout bagage abandoné
sera systématiquement détruit »... exactement comme un objet qui n'est plus
référencé par aucune variable.
Bref, tu l'auras compris : il faut absolument que ton cours mette cette
métaphore dans la tête du lecteur plutôt que n'importe quelle autre. Je te fais
confiance pour trouver une façon sympa de l'exprimer.
C'est trop court et pas aussi évident que tu le sous-entends. Tu devrais
disséquer un traceback ou au moins préciser que c'est la dernière ligne la
plus importante, histoire d'être clair.
Types d'objets
Typo : « faisons un tour d'horizons » → « un tour d'horizon ».
Alors, me direz-vous certainement, pourquoi ne pas avoir le même type
d’information partout ? La réponse est assez simple : vous voudrez effectuer
des actions différentes selon le type de votre objet.
Suggestion : Un petit parallèle avec le monde réel.
« Vous êtes d'accord avec moi si je vous dis qu'on ne fait pas la même chose
avec poignée de porte et un cure-dents ? Eh bien c'est parce que ce sont des
objets de types différents. ».
Listes
Les lignes d'un tableau excel ? D'où ça sort ?? Je ne comprends vraiment pas le
rapport.
Pourquoi pas simplement… une liste de courses ? Une todo-list ? Les 4 frères
Dalton ?
Là, si je m'imagine un tableau excel, je vois immédiatement deux dimensions. Je
ne suis vraiment pas convaincu par cet exemple.
Tuples
Attention en disant que ça sert « À stocker des données dont la valeur est
importante et ne doit pas changer ». C'est très inexact :
>>> a = [1]
>>> b = [2]
>>> mon_tuple = (a, b)
>>> mon_tuple
([1], [2])
>>> a.append(3)
>>> mon_tuple
([1, 3], [2])
Et PAF ! Les boîtes et les étiquettes qui te reviennent telles un élastique
dans le nez.
Les tuples servent à créer des structures dont le nombre d'éléments ne bouge pas. On
peut penser à des coordonnées (x, y), des couleurs (rouge, vert, bleu), des
paires (key, value) lorsque l'on itère les objets d'un dictionnaire. Ce qui
est important, c'est que les tuples imposent à leurs éléments une structure
fixe. Comme les coordonnées GPS de Paris dans ton exemple. Les éléments d'un tuple n'ont de sens que tous ensemble ; séparément ils ne veulent plus rien dire. C'est ça qu'il faut rendre explicite.
Dictionnaires
À la manière d’un vrai dictionnaire, vous accédez aux différentes définitions
en regardant la lettre qui vous intéresse. C’est très pratique quand la
position dans une liste ne compte pas.
Je débute, on est en train de m'expliquer un dictionnaire et on me parle de
position dans une liste… Je ne comprends pas.
Avant d'insister sur le fait qu'il n'y a pas d'ordre dans le dictionnaire, il
faut montrer ce que c'est. Tu peux d'ailleurs t'aider de l'appellation
générique officielle : « tableau associatif ». Une structure dans laquelle tu
associes des clés et des valeurs, comme des mots et leur définition.
Là, avant même d'avoir vu ce que c'est vraiment, le lecteur vient de s'embourber une comparaison floue avec une liste (quand la position dans la liste ne compte pas… encore faut-il comprendre que tu sous-entends qu'un dictionnaire indexe ses éléments via les clés, or cette notion est sous-entendue dans ta phrase et le lecteur, en principe, n'a que très peu de chances d'avoir déjà croisé la notion d'indexation), et une
règle à propos de l'ordre…
Souviens-toi que tu es une fervente partisane du paradigme qui veut qu'on apprenne "en faisant", par la pratique (je t'attends au tournant, tout ça tout ça) : montre-leur d'abord, puis explique ensuite.
La suite n'aide pas, parce que c'est tout confus de cette définition que le lecteur tombe
sur le retour de la vengeance d'Excel :
Si nous reprenons notre comparaison avec un tableur, un dictionnaire peut
être vu comme une nouvelle feuille :
Je ne comprends vraiment pas du tout cette comparaison. Vraiment, vraiment
pas. Tu ne pourrais pas trouver un exemple un peu moins… un peu plus… un dictionnaire français →anglais ?
Un répertoire nom → numéro de téléphone ?
L'exercice pratique
# Regroupez leurs chansons par album dans un grand dictionnaire. (dictionary)
dict… Oh, attends, je reviens en arrière…
Je m'aperçois qu'à aucun moment tu ne mentionnes au lecteur le
véritable nom des types de données que tu viens d'énumérer (int, float,
list, tuple, dict). Ça c'est hyper embêtant : il ne peut pas les inventer !
Pire, tu parles de types différents, plus haut. C'est un truc que tu peux
montrer par la pratique (on revient au tournant. ):
Alors certes, « c'est quoi class ? », eh bien « c'est un
synonyme de type », et basta.
Conclusion de la partie 1
Je m'aperçois que je cogne pas mal sur cette partie 1, mais c'est vraiment parce que cette
partie est la pierre sur laquelle tout le reste doit se construire. Si elle
n'est pas de niveau, bien calée, mais un peu branlante, tu peux empiler ce que
tu veux par-dessus, ça sera bancal.
Puis ouvrez ce fichier avec votre éditeur de texte favori. Personnellement
j’utilise Sublime Text, mais d’autres options sont possibles. Un éditeur de
texte aussi basique de Notepad (sous Windows) suffit.
De grâce ! Ça fait 15 ans que tous les tutoriels proposent Notepad++ au lieu de
Notepad sous Windows. Essaye de coder pendant 5 minutes dans un éditeur sans
auto-indentation ni coloration syntaxique : ça ne te fait vraiment rien
d'infliger ça à des gens qui ne savent même pas encore programmer ?
Allons, ça ne mange pas de pain de leur donner un lien vers un outil qui tient
un minimum la route. Par ailleurs tu pourrais aussi donner un petit lien sur le
chapitre sur Vim du cours de Mateo21 pour les utilisateurs de Linux.
Ou alors dis-leur carrément d'installer Sublime, mais donne-leur une
indication claire. Il vaut mieux que ceux qui ont déjà un éditeur de texte ne
t'obéissent pas, plutôt que tous les autres soient paumés dans la jungle des
éditeurs.
Je suis peut-être puriste, psycho-rigide ou tatillon, mais s'il y a une
convention standard pour présenter son code en Python (la
PEP-08), il faut la respecter. Tes
exemples de code vont être copiés-collés, réutilisés comme modèle, étudiés,
repris… Mettre un minimum ton code en forme pour ne pas avoir des lignes de
15km de long (la PEP-08 recommande 80 caractères, même si ça peut paraître
violent au départ), quand celui-ci fait office de référence, ce n'est pas en
option.
Ça, NON :
quotes = ["Ecoutez-moi, Monsieur Shakespeare, nous avons beau être ou ne pas être, nous sommes !", "On doit pouvoir choisir entre s'écouter parler et se faire entendre."]
characters = ["alvin et les Chipmunks", "Babar", "betty boop", "calimero", "casper", "le chat potté", "Kirikou"]
Ça, oui !
quotes = [
"Ecoutez-moi, Monsieur Shakespeare, nous avons beau être ou ne pas être, nous sommes !",
"On doit pouvoir choisir entre s'écouter parler et se faire entendre."
]
characters = [
"alvin et les Chipmunks",
"Babar",
"betty boop",
"calimero",
"casper",
"le chat potté",
"Kirikou"
]
Mais passons, là on est sur une considération cosmétique. Le point suivant est,
hélas, beaucoup plus grave que ça.
Tu viens de faire entrer du texte accentué dans un fichier à des gens
sous Windows, Linux et/ou Mac, en tapant ton exemple sur ton Mac…
Et l'encodage, on en parle ou bien comment ça se passe ?
Sous Linux et Mac, tout va bien, les gens sont la plupart du temps, comme
Python, en UTF-8. Mais sous Windows, si tu ne leur dis rien de plus, dans le
meilleur des cas Python leur affichera ceci :
'Ecoutez-moi, Monsieur Shakespeare, nous avons beau �tre ou ne pas �tre, nous sommes !'
Et au pire, soit dans 99% des cas puisque l'encodage par défaut de Windows est
latin-1 :
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xea in position 51: invalid continuation byte
Qu'est-ce que tu disais, déjà, dans la partie précédente ?
Python est apprécié des débutants notamment pour ses messages d’erreurs.
D’autres programmes auraient affiché Error, et basta, mais Python aime ses
développeurs et leur donne un peu plus de détails !
Ah oui, heureusement ! C'est évident que cette signifie que :
Les chaînes sont en Unicode en Python 3,
Python considère par défaut qu'elles sont encodées en UTF-8 lorsqu'il lit un
fichier de code,
L'immense majorité des éditeurs sous Windows utilise le Latin-1,
En fait c'est juste que l'utilisateur aurait dû faire attention à l'encodage
utilisé lors de la sauvegarde de son fichier, ou bien mentionner, en première
ligne de son module, le commentaire suivant :
# -*- coding: latin-1 -*-
Je suis sûr que les débutants vont A-DO-RER Python pour leur avoir expliqué
tout ça de façon très claire dans son message d'erreur.
On me signale dans l'oreillette que je viens de tomber dans le sarcasme. Toutes
mes excuses. Je me reprends.
Par contre ce n'est pas fini : puisque dans la première partie tu incites les
gens à utiliser leur terminal, ces caractères accentués, même si leur encodage
est déclaré correctement, n'ont aucune chance de s'afficher correctement sous
Windows. D'où l'idée d'utiliser une console alternative, ou IDLE.
Bref, il y a de très grosses lacunes dans ce chapitre. Il manque vraiment
trop d'infos pour que ce soit acceptable pour les utilisateurs de Windows, et
crois moi, les gens qui aident les débutants sur le forum vont te maudir pour
ça.
Le dilemme
À ce point de ma lecture, il me semble tout à fait évident que ce cours n'a pas
du tout été écrit pour être multi-plateformes. Je suis donc face à un choix :
Soit je continue à tirer sur l'ambulance quand il va s'agir des débutants
sous Windows.
Soit je considère à partir de maintenant que Windows, on s'en fout, c'est 70%
de lectorat perdus pour le moment, et je poursuis mon commentaire en me
bornant à GNU-Linux et Mac OS.
Vu que ceci n'est pas une vraie validation (le cours est déjà publié), que je
suis linuxien jusqu'aux gencives et que, malgré les apparences, je ne suis pas
sadique, je choisis l'option 2 : on est entre unixoïdes consentants, on utilise
tous un système d'exploitation moderne et bien foutu, et tant pis pour les
windowsiens à pull bleu.
Profitons de cet intermède pour souffler un bon coup, prendre un café/fumer une
clope, et reprenons, soulagés de nous être débarrassés de cette ennuyeuse
responsabilité.
Nous allons commencer par écrire du pseudo-code, c’est-à-dire écrire ce que
nous voulons que le programme fasse avec nos propres mots. Il s’agit d’une
pratique très courante chez les développeurs.
« Très courante » ? Moui… enfin c'est pas très important.
Tout mon code est écrit en anglais. Non pas que je souhaite mettre en avant
mes incroyables talents linguistiques, mais plutôt car la langue du
développement est l’anglais. Qui sait ce que deviendra votre projet demain ?
Vous pouvez choisir de le rendre disponible en open source pour que chacun
puisse y contribuer, y compris des non-francophones. Ou bien vous pouvez le
vendre. En plus les accents français ne sont pas acceptés dans les noms de
variables. Bref, coder en anglais est une bonne pratique. Rassurez-vous : il
s’agit de mots simples et vous comprendrez tout.
YES !! Là tu viens de marquer des points, j'approuve totalement.
Soit ça n'a pas du tout été exécuté, soit ça a été exécuté sur Python 2. Mais
en Python 3, l'opérateur de division retourne systématiquement un float :
>>> 1 / 1
1.0
Du coup, en dessous tu parles de division entière mais tu ne montres pas
l'opérateur correspondant :
Vous commencez par écrire if, puis entre parenthèse vous indiquez la
condition à remplir et terminez la ligne par deux points (sans espace avant
!).
Hmm, j'ai l'impression que le code juste au-dessus devait comporter des
parenthèses, que l'erreur a été remontée, et que le code a été corrigé à
l'arrache sans adapter l'explication en-dessous. C'est ballot !
L’importance de l’indentation est souvent sous-estimée, pourtant elle est à
la source des principales erreurs de débutant·e·s ! Prenez le temps de vous
relire et de vérifier qu’il y a bien deux espaces, et non un ou trois !
Comment quitter le programme ? En utilisant le mot-clé ‘pass’ :
Quitter le programme ? Non. "Ne rien faire", plutôt, pass n'a rien à voir avec
quitter le programme, même si dans l'exemple que tu montres, ne rien faire
revient à quitter le programme.
Une explication plus détaillée est indispensable ici.
Répétez une action grâce aux boucles
Oui, j'ai sauté le chapitre sur les fonctions. Je n'ai rien vu de choquant.
Mots-clés : Vous pouvez utiliser le mot-clé “break” pour arrêter la boucle en
cours de route. Pour aller à la fin d’une étape, sans exécuter le reste du
code d’une condition, utilisez le mot-clé “continue”.
Trois remarques :
Montre des exemples ! Tu apprends aux gens en faisant, non ?!
L'explication du mot-clé continue est incompréhensible : tu confonds
"condition" et "itération", et juste à la lecture de cette phrase il est
impossible de savoir ce que tu veux dire. Montre des exemples !
Montre des exemples !
Conclusion sur la partie 2
Bon, ben on a perdu 70% du public cible en cours de route, ce n'est pas rien…
:-/
Pour le reste, j'ai le sentiment un peu désagréable que ça te gonflait d'écrire
certaines parties, donc que tu les as un peu torchées pour passer à des choses
moins ennuyeuses à écrire. Ça peut se comprendre, c'est humain.
Que quelqu'un ait décidé sciemment de publier cette partie en l'état, par
contre, c'est plus gênant. Et que des corrections aient été visiblement
apportées à chaud au texte sans vérifier si elles ne cassaient pas sa cohérence
également…
Enfin bon, j'espère simplement que ça sera corrigé prochainement.
Ici un co-auteur du cours Python, je collabore avec Céline. Merci pour tes retours et tes suggestions ! Tu soulèves des points vraiment pertinents, notamment sur l'installation sous Linux et les types d'objets. On va en tenir compte. Je sais pas si c'est une évidence, mais on est tout à fait en mesure de modifier un cours existant. Evidemment les mises à jour de vidéos sont plus longues (on les fait plutôt en batch), mais c'est vraiment pas compliqué de corriger un texte.
Pour ce qui est des autres commentaires, ils remettent en cause des partis-pris pédagogiques conscients. Par exemple : oui, on connaît la différence entre une valeur et une référence. Si on a choisi de présenter les choses comme ça, c'est par souci d'efficacité. Est-ce qu'on a fait un mauvais choix ? Je ne peux pas en être sûr, mais je ne pense pas. On verra peut-être débouler dans les forums des hordes d'apprentis pythonistes se demandant pourquoi le dictionnaire contenu dans le tuple a été modifié, ou bien s'étonnant de ne pas pouvoir utiliser une liste comme clé d'un dictionnaire. Et si c'est le cas, on fera notre mea culpa et on reverra notre copie. Mais je suis plutôt optimiste.
En attendant, merci pour vos relectures attentives ! Elles sont utiles et on attend les suivantes.
On verra peut-être débouler dans les forums des hordes d'apprentis pythonistes se demandant pourquoi le dictionnaire contenu dans le tuple a été modifié, ou bien s'étonnant de ne pas pouvoir utiliser une liste comme clé d'un dictionnaire. Et si c'est le cas, on fera notre mea culpa et on reverra notre copie. Mais je suis plutôt optimiste.
OK, alors je vais utiliser un super-pouvoir, qui est de regarder dans une boule de cristal qui s'avère être virtuellement en ma possession…
Plus sérieusement, je n'ai pas besoin de spéculer sur ce point.
Sachant que vous avez utilisé strictement la même approche Vincent Le Goff (qui a rédigé l'autre tuto Python d'OC il y a 8 ans), et que pendant toutes les années qui ont suivi, c'est moi qui ai modéré et animé le forum Python du SdZ/OC, je peux vous l'affirmer avec certitude : oui, les débutants débaroulent sur le forum sans avoir compris ça depuis des années, et ce tuto n'apporte aucun élément de compréhension supplémentaire qui pourrait changer la donne.
De plus je ne suis pas le premier à soulever ce point, et je ne le tire pas de mon chapeau. C'était déjà un biais universellement connu dans les cours Python, même en 2012, comme en atteste, par exemple ce billet de blog.
Edit : D'autant que, choisir de parler d'étiquettes au lieu de boîtes, ça n'est ni plus long, ni moins efficace. Bref, ça ne mange pas de pain, et ça ne coûte pas grand chose à corriger. Du coup j'ai beaucoup mal à imaginer ce que vous pouvez encore espérer de ce parti pris pédagogique conscient.
d'abord, merci aux auteurs du tutorial d'avoir pris le temps de l'écrire. Ensuite, merci à Nohar pour ce compte-rendu très intéressant.
J'avais envie de poser une question sur ce tuto (en recopiant purement et simplement le code de lecture des fichiers json dans la partie bonus, j'obtiens une erreur que je n'arrive pas à déchiffrer). Mais je vais attendre de lire plus avant les commentaires qui seront faits par Nohar.
Ceci étant dit, je me permettrai une observation : j'ai la bonne habitude de chercher dans les forums avant de poster un nouveau sujet. J'ai été surpris en découvrant que ce post date de ce mois-ci. J'y ai donc découvert que le tuto que je suivais était un nouveau tuto (je n'y avais pas fait attention du tout, et étant donné qu'il tient en 4h, j'ai voulu faire celui-la avant le 2e qui est plus long). Je suis surpris de voir qu'il ait été validé en l'état et qu'il fasse partie des cours "officiels", si je puis m'exprimer ainsi. Je pars du principe que mon incompréhension sur la partie JSON est ma faute uniquement. Mais, par exemple, et comme Nohar l'a mentionné, j'ai eu beaucoup de frustrations et d'incompréhensions avec la console, jusqu'à ce que j'aperçoive le screenshot du mac.
(note : si vous vous demandez qui fait la remarque, j'ai un très vieux profil sur le SdZ mais j'ai arrêté de consulter le site depuis plus de 10ans, et ne suis revenu que récemment (il ya trois jours!) essayer de me remettre à la programmation. Je n'ai donc pas d'intérêt caché à soutenir ou infirmer la remarque de telle ou telle personne).
Je suivrai donc ce thread avec intérêt. Merci néanmoins aux auteurs d'avoir pris le temps d'écrire ce tuto. En attendant, j'ai aussi pu lire dans l'autre thread dédié au sujet (que Mateo21 a fermé), que le cours de V. le Goff datait d'il y a 8 ans. Est-il toujours à jour ? Devrais-je me reporter sur celui-ci ? Ou est-ce que vous (je m'adresse surtout à Nohar, ici, en fait :p) auriez un tutoriel que vous considérez comme LE meilleur tuto pour débutant pour ne pas passer à côté de ces concepts que vous évoquez (notamment la distinction étiquette/boite, qui m'a paru plutôt éthérée). [edit: note au sujet des tutos: je parle parfaitement l'anglais, donc si vous considérez que le tuto le plus progressif/complet/pointilleux/whatever est rédigé en anglais, n'hésitez pas]
Merci à vous et bonne soirée.
- Edité par benjamin.dubreu 19 février 2017 à 20:16:43
Le cours de V. Le Goff est, certes, toujours à jour, mais cela fait 8 ans qu'il enseigne certains trucs faux et dangereux. Notamment une utilisation à la légère et absolument pas portable de la fonction os.system qu'on retrouve dans pratiquement tous les programmes d'exemple en console.
Sinon, la référence francophone reste le livre de Gérard Swinnen (Apprendre à programmer avec Python 3 ) qui est librement téléchargeable en PDF sur le net. Ce livre est un petit peu ancien, mais c'est une valeur sûre. Si je voulais être pointilleux, j'aurais principalement deux reproches à lui faire : il s'appesantit un peu trop sur les boucles while (au point que les débutants ont tendance à utiliser while ensuite à toutes les sauces, là où la boucle for serait tout indiquée, et à la fois plus safe et plus idiomatique), et il ne respecte pas les conventions de nommage de la PEP-08 (la coding-style standard de Python). En dehors de ça, il a le mérite d'être très complet, pédagogique et formateur, donc c'est une ressource solide.
On va me reprocher de faire de la pub, mais une adaptation du Swinnen est en cours sur ZesteDeSavoir, puisque sa licence le permet. Le but étant de porter le contenu, puis de corriger les défauts de ce livre. Il n'est pas encore publié sur ZdS, mais je le mentionne parce que parmi toutes les ressources francophones en Python, cela montre que c'est le livre de Swinnen qui a été choisi comme base pour l'effort de portage et de réédition, par une communauté de gens qui font vraiment attention à tous ces trucs là.
Quant à la suite de mes commentaires sur le présent tuto, j'attends de voir dans quelle mesure mes présentes remarques seront prises en compte pour savoir si ça vaut le coup que je repasse encore un certain nombre d'heures à relire/commenter la suite. Ce n'est pas spécialement de la défiance, c'est surtout que je cherche quand même à rentabiliser le temps que j'y passe.
merci pour ta réponse ! J'avais effectivement noté les nombreux tutos disponibles sur le site de la doc, et je comptais m'y attaquer après avoir épuisé les ressources disponibles en français. Je vais donc commencer par Swinnen, en tenant compte de tes remarques.
Merci d'avoir pris le temps de répondre dans un délai si court.
PS : je note que mon post précédent est un peu brouillon. La raison pour laquelle je suis surpris de voir que le tuto dont il est question dans ce post soit "officiel", c'est qu'on a l'impression, de prime abord, que c'est par celui là qu'il faut commencer : c'est le premier résultat (avant celui de V Le Goff), et il est de seulement 4h (on pourrait penser qu'il s'agit d'un préambule, un premier cours à suivre "pour voir"). Or, visiblement, commencer par là n'est pas nécessairement une bonne chose. Just my two cents.
Hello Nohar et les autres personnes qui ont fait des retours !
Ici Céline, l'auteur du cours. J'ai lu avec grande attention les retours plus ou moins bienveillants que vous avez formulés. Je suis une fervente partisane de l'amélioration continue et je fais des mises à jour régulières en fonction des retours des utilisateurs donc cela ne me dérange absolument pas... à condition que les messages que je reçois restent courtois. On ne peut pas dire que ça ait été particulièrement le cas dans le thread précédent et on sent beaucoup de sarcasme dans ton retour.
Mais je ne suis pas mauvaise joueuse ! Je salue tes remarques et je te remercie du temps que tu as pris pour relire les deux premières parties. Etant donné que je souhaite que mes cours soient le plus qualitatif possible (toi et moi avons le même but apparemment !), j'ai apporté les modifications suivantes :
Python est un langage parfait pour débuter. Il fonctionne sur tous les systèmes d’exploitation (Windows, Mac et Linux) et vous n’avez pas à utiliser un logiciel spécifique pour voir le résultat de votre code. Vous avez juste besoin d’un ordinateur. Et de votre tête. Alouette.
Le ton est génial, mais la phrase confuse, voire carrément fausse : il y a besoin de l'interpréteur installé sur l'ordinateur. Autant ce n'est pas du tout un problème sous Mac OS ou Linux, mais sous Windows, en revanche, ce point est source d'embrouilles, en particulier pour les débutants, qui galèrent à trouver une façon propre de distribuer leur programme.
Vu que ce cours n'a probablement pas pour objectif de s'attaquer à ce problème épineux (pour lequel il n'existe aucune solution qui sorte du lot aujourd'hui), je virerais purement et simplement cette mention. Peut-être voulais-tu dire qu'il n'y avait pas besoin d'un IDE spécifique ou d'un compilateur… mais là, ton lecteur est débutant, il n'a aucune idée de tout ça.
C'est effectivement ce que je voulais dire et, en effet, c'est confus pour les utilisateurs Windows. J'ai donc enlevé la phrase (c'est dommage car j'aimais bien "et de votre tête. Alouette." ^_^)
J'aurais accepté de lire ça dans un tutoriel en 2012 ou 2013, mais là, même la Python Software Foundation a un parti pris beaucoup plus prononcé : Python 2 est obsolète. Il est encore utilisé sporadiquement par des programmes un peu critiques dont les entreprises n'estiment pas qu'il est rentable de les porter, mais aujourd'hui, en 2017, Python, c'est Python 3.6. On est quand même une version majeure et SIX versions mineures au dessus de la dernière vraie version de Python 2 (2.6), sachant que 2.7 est une version de transition dans laquelle certaines fonctionnalités sont backportées pour faciliter le travail de migration.
Bref, à ta place, je me mouillerais un peu plus dans ce débat : tu n'as pas besoin de marcher sur des œufs. Cela dit je salue la transparence qui consiste à mentionner l'existence des deux versions parallèles.
Oui, j'ai beaucoup hésité à en parler et nous en avons discuté avec Régis. Etant donné que le sujet est toujours évoqué lors de conférences, je me suis dit qu'il était normal de l'indiquer. Cela fait partie du paysage Python et ne pas le savoir est un peu dommage (je trouve).
Sous Linux
En effet, j'ai supprimé l'option et n'ai laissé que APT-GET.
Tapez sudo apt-get install python3 dans votre console.
J'ai affiné mon explication en reprenant le concept d'étiquettes que j'avais effectivement vu ailleurs (et qui est également valable dans le langage de manière générale).
Les messages d'erreur.
Je reviendrai sur ce point dans un autre cours mais j'ai ajouté une ligne.
Typo : « faisons un tour d'horizons » → « un tour d'horizon ».
Merci
Listes
ok, j'ai enlevé le tableau.
Tuples
ok, modifié.
Dictionnaires
ok, modifié.
J'ai déjà vu la comparaison avec un Excel dans d'autres articles et elle m'a parlé lorque j'ai commencé à coder. Mais, dans le doute, je l'ai enlevée.
Exercice pratique
> Pire, tu parles de types différents, plus haut. C'est un truc que tu peux montrer par la pratique (on revient au tournant. ):
Je le montre dans la vidéo mais j'ai ajouté une ligne.
Partie 2 : posez les fondations de votre programme
Hmm, j'ai l'impression que le code juste au-dessus devait comporter des parenthèses, que l'erreur a été remontée, et que le code a été corrigé à l'arrache sans adapter l'explication en-dessous. C'est ballot !
Hum, pas vraiment, c'est ma phrase qui était mal écrite. J'ai réécrit.
J'ai supprimé l'explication car je n'utilise pas ces mots-clés à cet endroit là donc finalement ce n'était pas très utile. J'ai mis à jour le code final.
Je te remercie vraiment d'avoir pris le temps de relire ces deux premières parties. Cela améliore la qualité du cours et c'est tout ce que je souhaite. Si tu as d'autres remarques je les prendrai en compte mais j'apprécierais vraiment que le ton soit plus aimable. Vous mentionnez la PEP8 et les nombreuses conventions qui font de Python un langage agréable à utiliser. Pourquoi ne pas appliquer nos propres règles de savoir-vivre ?
Bref, si tu es de passage à Paris je prendrai avec grand plaisir une bière avec vous pour débattre de tout cela de vive voix
Je veux bien croire que je suis tombé dans le sarcasme par endroits (je l'ai même explicitement remarqué), mais je t'assure que je l'ai lissé autant que possible. Je pense que c'est avant tout un problème de référentiel.
Je ne doute pas que tu as écrit ton cours en y mettant une bonne dose d'efforts, qu'il t'a pris des dizaines d'heures de travail et je sais bien que ça demande un paquet de courage pour venir à bout de la rédaction d'un contenu comme celui-ci. Je connais ça, pour m'être prêté plusieurs fois à cet exercice, j'en suis bien conscient et je respecte tout à fait ton travail, mais je sais aussi que dans ces conditions il est également assez difficile de recevoir un feedback négatif dessus.
De l'autre côté (du ring), écrire une critique qui soit à la fois négative et constructive n'est pas non plus une sinécure. Lorsque je lis un cours Python, puisque c'est une techno chère à mon cœur et dans laquelle je cultive l'expertise et l'aide que j'apporte sur les forums (comme celui de ce site) depuis des années, il faut bien voir plusieurs choses (et je pense que ce sont également des éléments de compréhension pour l'hostilité d'entwanne) :
Les erreurs des débutants qui sont inhérentes à un cours mal appris ou qui les a induit en erreur sont pénibles, et même accablantes pour nous. Parce qu'il faut répéter inlassablement la même correction, les mêmes explications, patiemment, régulièrement, sans jamais se fatiguer ou s'énerver sur le débutant (c'est pas sa faute si c'est le 48ème du mois), et ce pendant des des années (vraiment, des années). À partir de là, voir un nouveau cours qui fait une erreur bien connue est hyper énervant. Ce n'est pas de ta faute, mais ça relève quand même de ta responsabilité.
Il est très difficile de faire un feedback négatif qui marque sans pour autant braquer. Je suis moi-même auteur. Quand je lis une critique négative sur un de mes contenus, c'est humain, mais mon premier réflexe est souvent de me dire quelque chose comme "ah non mais pff, il est en train de pinailler sur un détail, on s'en fout de ça, c'est juste lui qui n'a rien compris", au risque de laisser passer un truc vraiment grave. Du coup il faut que le retour soit marquant… et l'ironie est une solution comme une autre. Ça n'a rien de personnel contre toi. Par contre je remarque que les points sur lesquels je me suis montré le plus mordant (et c'était de loin les plus importants) ont tous été corrigés.
Je ne suis pas un killer de l'expression écrite. Certaines formulations ont pu rendre mon retour plus abrupt que nécessaire, et pour ça je te présente mes excuses.
Vous mentionnez la PEP8 et les nombreuses conventions qui font de Python un langage agréable à utiliser. Pourquoi ne pas appliquer nos propres règles de savoir-vivre ?
C'est pris en compte pour la suite.
Bref, si tu es de passage à Paris je prendrai avec grand plaisir une bière avec vous pour débattre de tout cela de vive voix
Je ne dis jamais non à une bière. D'ailleurs ça pourrait même être plus facile de discuter de la suite du tuto de vive voix, histoire d'éviter les biais et les désagréments d'une critique publique et écrite.
Edit: Je viens de relire les deux premières parties rapidement, pour voir les changements. À première vue c'est nickel.
Mince alors, mon message n'était pas bienveillant.
Quitte à me répéter, il s'adressait avant tout aux potentiels lecteurs du cours, et à ceux qui pourraient en faire la publicité.
Car le cours était clairement à déconseiller dans l'état où je l'ai lu (je ne l'ai pas relu depuis les récentes mises à jour et ne compte pas le faire, ça m'a déjà pris bien assez de temps).
Mais les remarques que j'ai faites qui n'ont pas été prises en compte restent toujours valables
Quand je vois maintenant parler d'« amélioration continue » sur ce sujet, je crois comprendre que les modifications se font en live sur le cours, et qu'on a donc dit adieu à tout processus de validation.
Ça explique pas mal de choses.
Oui oui, j'ai bien compris et j'ai conscience de la frustration que tout cela peut provoquer. C'est pourquoi j'ai pris le temps de bien lire tous les retours (y compris ceux d'entwanne ;-) ) et de modifier mon cours en conséquence. On a le même but !
Par contre je remarque que les points sur lesquels je me suis montré le plus mordant (et c'était de loin les plus importants) ont tous été corrigés.
J'ai modifié tous les points, y compris ceux pour lesquels tu n'avais pas été mordant ! ;-) Je le redis : je prends en compte les retours et les applique quand ils me semblent pertinents.
Je ne dis jamais non à une bière. D'ailleurs ça pourrait même être plus facile de discuter de la suite du tuto de vive voix, histoire d'éviter les biais et les désagréments d'une critique publique et écrite.
C'est très rassurant pour nous les étudiants de voir que les cours sont mis à jour et surtout Python, car je vais commencer dans quelques jours ce parcours.
Je bloque dans la deuxième partie du cours sur les fonctions, au moment des paramètres. Je ne comprends rien à ce qu'on me demande de faire. Je peux copier le code ou la même structure, mais je ne comprends pas comment ça fonctionne.
Pourquoi dois-je écrire my_liste en paramètre ?
Pourquoi je dois mettre quote = my_liste[0] en dessous ?
Bref, jusque-là tout allait bien, mais là vraiment, je ne comprends rien, que ce soit le texte ou la vidéo. J'arrive à le faire, y'a pas de soucis sur ça, mais je ne comprends pas ce que je fais.
C'est quoi my_liste ? On l'a définit nulle part avant.
Si je veux que ma fonction puisse fonctionner pour toutes mes listes, pourquoi je dois intégrer "quote=my_listes[0]" ?
Bref, Nohar, tu dis que cette partie ça va, mais honnêtement moi j'y connais rien, et du coup sur ce passage je ne comprends strictement rien (alors que le reste c'était plutôt oklm).
Merci pour le cours en tout cas, et aussi pour ce forum permettant d'éclaircir le fond, mais j'avoue là je veux bien un peu d'aide Je vais bidouiller un peu et avancer dans le cours voir si les choses s'éclaircissent.
Merci par avance pour votre attention
..........
EDIT 1 : Bon, je reviens après avoir bidouillé un peu, et y'a vraiment des trucs que je ne comprends pas. Je vous envoie mes lignes de codes :
>>> citations = [ "Essayons d'abord de lui faire changer d'avis.", "Y'a qu'à en faire qu'une bouchée !", "Attaquons le pendant qu'il dort !" ]
>>> personnages = [ "Le bon", "La brute", "Le truand" ]
Donc jusque là j'ai à peu près respecté les instructions qu'on me demande de faire, et quand je fais : >>> pop(citations) ça me sort bien : Essayons d'abord de lui faire changer d'avis.
Ce que je ne comprends pas du coup, c'est que lorsque je fais : >>> pop(personnages) ça me sort : Le bon
Dans la ligne de code, la dernière action c'est : print(citations) Et en plus il y a : citations = liste[0]
Comment se fait-il alors que ça marche avec la liste "personnages" ? Vraiment je capte pas ce qu'il se passe.
Et si je change 0 par 1 ou 2, ça marche très bien aussi, j'ai respectivement la 2ème et 3ème citation, et le 2e et 3e personnage.
Puis pareil, si dans ma fonction je change "citations" par "personnages", tout marche de la même manière. Ça marche même quand je définis ma fonction comme ça :
>>> def pop(liste): liste = liste[1] print(liste) pass
Moi vraiment pas comprendre du coup !
...........
EDIT 2 : Bon, je reviens encore pour dire que lorsque j'entre :
>>> def pop(liste): liste[1] print(liste) pass
Et que j'applique la fonction sur la liste personnages ou citations, ça ne marche plus comme avant car la réponse c'est toute la liste en question, à savoir :
['Le bon', 'La brute', 'Le truand']
ou
["Essayons d'abord de lui faire changer d'avis.", "Y'a qu'à en faire qu'une bouchée !", "Attaquons le pendant qu'il dort !"]
Bref, là encore, je ne comprends pas pourquoi ça fait ça....
Actuellement ta fonction pop ne fait rien à la liste (aucune altération) et tu confonds renvoyer une valeur et l'afficher.
L'objectif de la fonction pop est de renvoyer une valeur tout en la supprimant de la liste. Il faut donc certes récupérer cette valeur, mais aussi la supprimer.
Ensuite, pour renvoyer une valeur il faut utiliser le mot-clé return dans une fonction, et pas faire appel à print qui n'a au final aucun effet sur le déroulement de la fonction.
La fin du cours est vraiment faite à la rash. Les parties BONUS on comprend absolument rien à ce qui est fait.
with open("characters.json") as f
On comprend rien à comment marche le "with", le "open()" et le "as". D'ailleurs moi j'ai tout fait comme c'est dit, et IDLE m'indique une erreur dans la fonction car le fichier characters.json est introuvable. Bref, vraiment mal expliqué, ça va super vite, c'est un peu frustrant honnêtement.
Je ne sais pas pourquoi le cours de 40 heures sur Python a été archivé. Je l'avais suivi et il me semblait assez complet et très clair. Ce n'est pas surprenant qu'un cours de 4 heures soit incompréhensible ... J'ai fait une demande à OC pour ramener ce cours, mais je n'ai pas encore reçu de réponse.
Le Tout est souvent plus grand que la somme de ses parties.
Oui, il me semblait qu'il y avait un cours de 40h, je voulais le faire, je ne l'ai pas retrouvé. Archivé cela signifie qu'on ne peut plus du tout le suivre ?
Le Tout est souvent plus grand que la somme de ses parties.
Le cours « Démarrez votre projet avec Python »
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Work hard play hard my friend!
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
Work hard play hard my friend!
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.