13 - Interface Console
Le disposif qui permet de faire interagir un humain et un système informatique se nomme une interface.
Nous avons déjà pas mal travaillé avec l'interface graphique Turtle :

Nous allons présenter aujourd'hui un peu plus l'interface texte Console et les deux fonctions natives que propose Python pour gérer une interface texte :
- print pour afficher sur l'écran et
- input pour récupérer le texte tapé sur le clavier.

Nous allons également revoir la différence entre fonctions d'interface et fonctions gérant les données.
Logiciel nécessaire pour l'activité : Thonny
Evaluation ✎ : questions 02-03-14-15
Résumé : Version HTML ou fond blanc ou ou PDF (couleur ou gris)
1 - Afficher à destination d'un humain sur la console
Nous avons déjà vu comment afficher des choses sur la console.
Il faut utiliser la fonction native print.
Nous avons vu que cette fonction native n'a rien à voir avec le mot-clé return des fonctions :
le mot-clé return
Le mot-clé return provoque la réponse immédiate de la fonction. Son but ? RENVOYER une réponse au PROGRAMME qui avait demandé à la fonction ce travail. Il s'agit donc d'une donnée informatique (même si c'est juste None) que le système informatique pourra stocker dans une variable.
1
2 |
|
Si on utilise cette fonction en lui fournissant "Bon", que se passe-t-il sur la console ?
Réponse : ça dépend !
Cas 1 : Appel console avec stockage dans une variable
Regardons ce qui se passe si on stocke la réponse dans une variable.
>>> rep = repondre("Bon")
Moralité : aucun affichage. Par contre, la variable rep contient maintenant une information : la réponse de la fonction, à savoir le string "BonBon".
>>> rep
'BonBon'
Cas 2 : Appel console sans stockage dans une variable
>>> repondre("Bon")
'BonBon'
Cette fois, la réponse s'affiche dans la console après évaluation. Pourquoi ? Parce que. Parce que le concepteur de la console Python en a décidé ainsi : si un utilisateur tape une telle instruction-évaluation dans la console, on considère qu'à priori il veut la réponse ! Toute instruction se résumant à une évaluation est affichée dans la console Python.
C'est comme ça et c'est pratique.
Cas 3 : Appel dans un programme avec stockage dans une variable
Regardons ce qui se passe si on stocke la réponse dans une variable.
1
2
3
4 |
|
Moralité : aucun affichage. Par contre, la variable rep contient maintenant une information : la réponse de la fonction, à savoir le string "BonBon".
>>> rep
'BonBon'
Cas 4 : Appel dans un programme sans stockage dans une variable
1
2
3
4 |
|
Aucun affichage, contrairement au cas console, on n'affiche rien par défaut lorsqu'une instruction dans un programme est juste une évaluation.
Pourquoi ? Parce que. C'est le comportement décidé : dans un programme, l'affichage est une décision volontaire.
Du coup, comment afficher des résultats à destination d'un humain dans la console ? Réponse : il faut forcer l'affichage avec la fonction native print.
La fonction native print
La fonction native print ne renvoie rien vers le programme, même pas None. Son but ? AFFICHER dans l'interface de sortie un message à destination d'un UTILISATEUR HUMAIN. Le système informatique ne pourra donc rien stocker en mémoire à priori : le message ne lui ai pas destiné.
Retenez bien ceci : le print ne renvoie rien ! N'utilisez jamais un print si on vous demande de renvoyer une réponse.
Il s'agit juste d'une fonction native permettant d'interagir avec l'UTILISATEUR en lui permettant de visualiser quelque chose du comportement interne de l'ordinateur.
01° On demande à quelqu'un de réaliser une fonction qui renvoie 10 fois l'argument qu'on lui transmet.
Quelle est la réponse correcte à fournir ? Quelle est la version qu'il ne fait surtout pas noter sur sa copie ?
1
2
3
4
5 |
|
...CORRECTION...
La bonne réponse est la fonction fois10B puisqu'elle RENVOIE bien une réponse.
La fonction fois10B ne fait absolument pas le travail puisqu'elle ne fait qu'AFFICHER le résultat dans la console.
02° Utiliser le programme ci-dessous. Le programme provoque-t-il un affichage automatiquement ? Visualiser dans la console le contenu de la variable rep. Pourra-t-on réutiliser le "résultat" plus tard ?
1
2
3
4 |
|
>>> rep
'AAAAAAAAAA'
>>> type(rep)
?
...CORRECTION...
Pas d'affichage automatique de la réponse mais elle est stockée.
Puisque la réponse est stockée dans une variable, on pourra réutiliser cette chaîne plus tard.
03° Utiliser le programme ci-dessous. Le programme provoque-t-il un affichage automatiquement ? Visualiser dans la console le contenu de la variable rep. Pourra-t-on réutiliser le "résultat" plus tard ?
1
2
3
4 |
|
AAAAAAAAAA
>>> rep
>>> type(rep)
...CORRECTION...
Cette fois, c'est l'inverse : il y a un affichage automatique mais rien n'est stocké !
La fonction renvoie None et donc la variable ne contient ... rien.
Du coup, cette fonction ne sert à ... rien ?
On remarquera l'absence des guillemets sur l'affichage précédent : c'est normal : il est destiné à un humain. Il ne s'agit pas d'afficher le contenu réel de la variable mais juste en fournir une réprésentation. L'humain doit juste voir le message. Savoir que c'est un string, un interger ou un float n'a finalement aucune important pour lui.
04° On vous donne le code suivant.
1
2
3
4 |
|
Que contient reponse ?
Quel énoncé d'exercice correspond à cette fonction
- Créer une fonction qui renvoie la somme de a et de b
- Créer une fonction qui affiche la somme de a et de b
...CORRECTION...
La variable reponse contient la réponse de la fonction, à savoir la somme de 5 et 10, donc 15.
L'énoncé correct est donc réaliser une fonction qui renvoie la somme.
05° On vous donne le code suivant.
1
2
3
4 |
|
Que contient reponse ?
Quel énoncé d'exercice correspond à cette fonction
- Créer une fonction qui renvoie la somme de a et de b
- Créer une fonction qui affiche la somme de a et de b
...CORRECTION...
La variable reponse contient la réponse de la fonction, à savoir None !
C'est comme si on avait tapé ceci :
1
2
3
4
5 |
|
L'énoncé correct est donc réaliser une fonction qui AFFICHE la somme. Il ne sert à rien ici de tenter de mémoriser la réponse : elle n'existe pas.
Fonctions d'interface machine-utilisateur
On nomme fonctions d'interface avec l'utilisateur les fonctions dont la tâche est d'interagir avec l'utilisateur à travers l'interface choisie : une interface graphique comme Turtle ou une interface texte comme la console.
Si on respecte le concept "une tâche = une fonction", une telle fonction ne doit pas réaliser de stockage de données puisque c'est déjà une tâche en soi.
On parle également de fonctions d'interaction.
Il existe donc deux types de fonctions d'interface utilisateur-machine :
- Celles qui permettent la communication dans le sens programme vers l'utilisateur
- Celles qui permettent la communication dans le sens utilisateur vers programme
Exemple basique 1 : fonction d'interface Console vers Utilisateur
1
2
3
4
5 |
|
L'exécution de ce programme provoque l'affichage suivant :
Bonjour !
Pour fonctionner, cette fonction utilise la fonction native print mais la personne qui réalisera le programme n'a pas à s'en préoccuper : elle doit juste savoir qu'elle doit activer la fonction afficher.
Exemple basique 2 : fonction d'interface Turtle vers Utilisateur
1
2
3
4
5
6
7
8 |
|
L'utilisateur du programme précédent permet d'obtenir l'affichage suivant :

Pour fonctionner, cette fonction utilise la méthode write mais la personne qui réalisera le programme n'a pas à s'en préoccuper : elle doit juste savoir qu'elle doit activer la fonction afficher.
L'avantage des fonctions d'interface est donc qu'on n'a pas besoin de connaître les détails de l'interface sur laquelle on veut voir les choses s'afficher : on isole les particularités de cette interface d'affichage dans des fonctions bien spécifiques. Du coup, si on change d'interface, il suffira de modifier le code des fonctions d'interface mais le reste du programme devra toujours être le même !
Exemple basique 3 : prototype ou mode debug
Par contre, si vous voulez juste concevoir rapidement un petit programme sur la console, inutile de faire appel à une fonction d'affichage : vous avez le droit d'utiliser print directement !
1 |
|
06° Bien entendu, on peut utiiser une fonction qui renvoie une réponse et afficher ENSUITE sa réponse via un programme : il faut simplement demander poliment.
1
2
3
4
5 |
|
...CORRECTION...
Sur la ligne 5 : celle avec la fonction native print.
07° Peut-on dire que la fonction fois10B précédente est une fonction d'interface ?
...CORRECTION...
Non ! C'est une fonction qui réalise une tâche qui n'a rien à voir avec la communication avec l'utilisateur.
08°Quelqu'un propose de réaliser ceci. La fonction est opérationnelle, aucun problème. Mais quel est le problème ?
1
2
3
4 |
|
...CORRECTION...
Cette fonction n'est pas "acceptable" car elle sert à exécuter deux choses :
- Une tâche consistant à réaliser un calcul sur les données et à fournir la réponse
- Une tâche consistant à afficher sur l'Interface
Une fonction, une tâche
Dans l'activité Une Fonction Une Tâche, nous avions vu que lorsqu'on réalise un code en tentant de le rendre le plus propre possible, on doit donc s'évertuer à :
- Encapsuler chaque tâche dans une fonction
- Réaliser les tâches complexes en faisant appel à des fonctions réalisant des tâches basiques
Nous pouvons donc rajouter que, lorsqu'on veut réaliser le code le plus propre possible, on doit créer des fonctions qui n'appartiennent
- soit à la catégorie des fonctions d'interface : elles permettent de communiquer avec l'utilisateur ou gère l'interface (graphique) mais ne modifie pas les données du programme en lui-même
- soit à la catégorie des fonctions gérant les données (calcul et stockage) mais elles n'interagissent pas directement avec l'utilisateur.
2 - Lire les entrées clavier
Nous avons vu comment gérer cette communication avec TURTLE et sa programmation événementielle : il fallait utiliser les méthodes onclick pour permettre au programme de recevoir les informations de la souris et onkey pour recevoir les informations du clavier.
Nous allons voir qu'on peut écouter le clavier lorsqu'on utilise l'interface CONSOLE.
Pour cela, il faudra utiliser la fonction native input.
fonction native input
Il s'agit de la fonction d'interface Console permettant la communication Utilisateur vers Programme.
Cette fonction réalise trois choses :
- Elle affiche sur la console le string qu'on lui passe en paramètre : cela permet de poser une question.
- Elle bloque le programme en attendant que l'utilisateur tape quelque chose sur le clavier et valide la saisie en tapant sur ENTREE
- Elle répond en renvoyant au programme sous forme d'un string ce que l'utilisateur vient de taper sur le clavier.
09° Faire des essais dans la console Python tel que présenté ci-dessous.
Questions
- Que fait le programme en attendant la réponse de l'utilisateur ?
- Que renvoie la fonction input ?
- A quoi voit-on que la réponse de l'utilisateur est toujours fournie sous forme d'un string ?
>>> input("Quel est votre prénom ? ")
On pourrait alors taper quelque chose. Ci-desssous, le résultat si on tape Alice puis ENTREE.
>>> input("Quel est votre prénom ? ")
Quel est votre prénom ? Alice
'Alice'
...CORRECTION...
Le programme est bloqué en attendant la réponse de l'utilisateur. La fonction input ne permet donc pas de faire de la programmation événementielle : nous sommes obligé de suivre le déroulement du programme dans l'ordre imposé par le code.
On remarque que la fonction native input renvoie ce qu'on vient de taper sous forme d'un string : la réponse sur la console est entourée de guillemets.
10° Que va contenir la variable reponse si l'utisateur tape Bob+ENTREE sur le clavier ? Vérifier en évaluant la variable dans la console.
>>> reponse = input("Quel est votre prénom ? ")
Quel est votre prénom ? Bob
...CORRECTION...
La variable reponse va contenir la réponse de la fonction native input, à savoir un string 'Bob'.
>>> reponse = input("Quel est votre prénom ? ")
Quel est votre prénom ? Bob
>>> reponse
'Bob'
10° Sans lancer réellement le programme, dire ce que devrait afficher Python si on dit qu'on a 5 à gauche et 10 à droite ?
1
2
3
4
5
6 |
|
Combien d'argent dans la poche Gauche ? 5
Combien d'argent dans la poche Droite ? 10
Au total, vous avez ??? euros.
...CORRECTION...
Combien d'argent dans la poche Gauche ? 5
Combien d'argent dans la poche Droite ? 10
Au total, vous avez 510 euros.
Rappel : concaténation
On retrouve l'"addition" de strings, ce qu'on nomme la concaténation.
Puisque les réponses récupérées par un input sont toujours des strings, on concaténe le string '5' et le string '10', ce qui donne '510' :
>>> '5' + '10'
'510'
>>> 'Bon' + 'bon'
'Bonbon'
>>> 5 + 10
15
Sur le dernier exemple, on voit que l'addition des deux entiers donne bien un entier.
Si on veut parvenir à additionner, il faut donc parvenir à convertir des strings en entiers. Pour cela, il faut simplement utiliser la fonction native int qui tente de convertir si c'est possible. Attention, si l'utilisateur tape quelque chose de non interprétable en entier, ça provoquera une erreur.
11° Lancer ce nouveau programme qui demande des choses à l'utilisateur ET convertit les réponses en entier. Est-ce que cela marche mieux ? Sur quelle(s) ligne(s) convertit-on les réponses en entiers ?
1
2
3
4
5
6
7
8
9 |
|
Combien d'argent dans la poche Gauche ? 5
Combien d'argent dans la poche Droite ? 10
Au total, vous avez ??? euros.
...CORRECTION...
Combien d'argent dans la poche Gauche ? 5
Combien d'argent dans la poche Droite ? 10
Au total, vous avez 15 euros.
C'est beaucoup mieux. La conversion se fait sur les lignes 2 et 5.
12° Modifier le programme pour qu'il sache gérer les centimes et donc les nombres à virgule.
...CORRECTION...
Il suffit d'utiliser la fonction de conversion float plutôt que la fonction de conversion float.
13° Expliquer étape par étape ce qui se passe ligne 1 si on rentre la valeur 5 ?
1
2
3
4
5
6 |
|
Combien d'argent dans la poche Gauche ? 5
Combien d'argent dans la poche Droite ? 10
Au total, vous avez ??? euros.
...CORRECTION...
Il faut revenir à la notion d'évaluation séquentielle.
L'interpréteur commence par exécuter la demande d'utilisation de input.
gauche = int(input("Combien d'argent dans la poche Gauche ? "))
On obtient donc ceci :
gauche = int('5')
Il reste à appliquer la fonction native int :
gauche = int('5')
Ce qui donne ceci :
gauche = 5
On peut donc affecter la variable gauche a la valeur 5.
Erreur courante
On arrive souvent à ce type d'erreur lorsqu'on oublie de convertir une partie des réponses uniquement :
>>> 5 + '10'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
La réponse de l'interpréteur Python est clair : il ne sait pas additionner ou concaténer des entiers avec des strings.
Comme vous pouvez le voir, nous utilisons simplement la fonction native input. Voyons comment nous pourrions l'encapsuler dans une fonction d'interface de façon à pouvoir plus facilement modifier notre programme en cas de changement d'interface.
Si on liste les tâches à faire :
- Il nous faut une fonction d'interface recuperer_un_entier qui renvoie la valeur entiere transmise par l'utilisateur.
- Une fonction de gestion de données trouver_le_total qui renvoie la somme de deux entiers.
- Une fonction d'interface afficher qui permet d'afficher un résultat destiné à l'utilisateur humain.
Voici le programme en version prototype rapide de travail
1
2
3
4
5
6 |
|
Voici le même programme en respectant la séparation des tâches dans des fonctions et la séparation claire entre fonction d'interface et fonction de gestion de données.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 |
|
14° Tester le second programme pour vérifier qu'il fonctionne correctement.
15° Le code du prototype est clairement plus concis que le second programme. Néanmoins si on décide de changer d'interface de communication, doit-on lire et modifier tout le code dans le premier programme ? Doit-on lire et modifier tout le code dans le second programme ?
...CORRECTION...
Si on veut changer d'interface, il faut relire tout le code du premier programme...
Par contre, dans le second programme, on pourra se limiter à modifier les fonctions d'interface !
La séparation Interface / Données peut paraître un peu artificiel sur un projet de 10 lignes, mais je vous assure qu'avec 30 000 lignes de code, on est bien content d'avoir séparer gestion de l'interface et gestion des données !
3 - Erreurs courantes avec les prints et les inputs
Voici deux erreurs "courantes" qu'il ne faudra jamais faire vous-même.
Petite erreur : erreur d'encapsulation
On voit assez souvent des fonctions qui gèrent à la fois l'interface ET les données.
1
2
3
4
5
6
7
8
9 |
|
Ici, c'est acceptable si le but est juste de faire un prototype rapide mais on voit clairement que notre fonction fait à la fois de l'interaction avec l'utilisateur et de la gestion des données. On voit du print mélanger avec du return par exemple.
Voici une solution où on ne mélange pas les deux types d'action. La partie liaison regroupe les fonctions qui vont appel aux fonctions d'interface et aux fontions de gestion de données.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 |
|
C'est plus propre, mais on passe de 9 lignes à 35 !
Dans le cadre d'un petit projet maison, pas d'inquiétude, la solution 1 est donc acceptée quand même. Par contre, il faut savoir que ce n'est pas propre : en cas de changement d'interface, il faut falloir relire tout le code pour savoir ce qu'on peut récupérer ou pas.
Vous allez voir en cours d'année que je ne cherche pas non plus à garantir la séparation interface / gestion dans toutes les activités.
L'important : savoir qu'on devrait le faire sur un vrai gros projet.
L'erreur suivante est par contre une vraie grosse erreur qui vous garantit des points en moins sur vos copies ! Le code suivant est vraiment un code abominable.
Grossière erreur à ne jamais reproduire. Jamais. Never.
Lorsqu'on utilise une fonction, on lui transmet les données à traiter via les paramètres de réception.
Exemple avec la fonction addition :
1
2
3
4 |
|
Si on veut additionner 5 et 10, on lance l'appel suivant :
>>> addition(5, 10)
15
On voit parfois une version limite de ce style de fonction :
1
2
3
4
5
6 |
|
Ce code n'est vraiment pas top :
- On mélange interface et données
- On ne peut pas imposer des valeurs pour faire des vérifications automatiques : il faut que quelqu'un tape les entrées !
Nous arrivons maintenant au vrai cas abominable en terme de compréhension des fonctions :
1
2
3
4
5
6 |
|
Comme vous le voyez, produire ce type de code montre clairement que le concepteur n'a pas compris que les paramètres a et b sont des valeurs qu'on transmet à la fonction pour qu'elle les gère justement.
Voilà pourquoi il faudra toujours être vigilant si vous voulez créer un programme autonome qui gère des communications de l'utilisateur.
4 - Exemple de jeu autonome
Il existe en réalité deux façons de réaliser une "application" avec Python :
- Faire un programme autonome sur lequel l'utilisateur n'a pas la main : il est obligé de faire exactement ce qu'on veut de lui. Pratique pour faire un "jeu" pour quelqu'un qui n'y connait rien en informatique. Il suffit de taper les réponses.
- Utiliser le mode interactif de Python (avec Thonny par exemple) en créant des fonctions qu'on place en mémoire puis en faisant l'appel à ces fonctions directement depuis la console Python de Thonny. Cela nécessite de s'y connaitre un peu en informatique.
Voici par exemple un jeu AUTONOME où on demande à l'utilisateur des additions et qui compte les points.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 |
|
16° Utiliser cette version du jeu en jouant une partie ou deux. Vérifier que vous comprennez le cheminement du programme en lui-même.
Il nous manque encore quelques notions sur l'interaction entre les variables globales du programme et les fonctions pour vous proposer l'équivalent en mode interactif directement depuis Thonny. Mais vous activez les fonctions depuis la console depuis assez longtemps maintenant pour comprendre qu'on pourrait très bien se passer de print et input et ne travailler qu'avec des fonctions :
- L'utilisateur peut fournir des valeurs aux fonctions à travers les arguments qu'il envoie
- L'utilisateur peut interroger le contenu des variables directement depuis la console
5 - FAQ
Quand l'utilisateur tape une lettre cela provoque une erreur ! On peut faire quelque chose ?
C'est bien le problème des informations qui proviennent d'un humain. Il a tendance à répondre n'importe quoi.
Je ne peux pas vous fournir de solution utilisant uniquement des notions déjà abordées.
Activité publiée le 28 08 2019
Dernière modification : 15 11 2020
Auteur : ows. h.