Programmer en Python en 2nde

Variables, opérateurs, saisie et affichage : types de variables et opérateurs

Crédits

Toute la structure html/css/js et une partie du contenu ont été réalisés par Nicolas Buyle-Bodin professeur au lycée Lacassagne, avec l'aide de Jean-Manuel Mény, professeur au lycée de la plaine de l'Ain. Ils ont travaillé pendant plusieurs centaines d'heures pour créer un site de formation à destination des enseignants du secondaire de l'académie de Lyon d'une grande qualité visible sur le portail Mathématiques du site académique. Ils ont eu la gentillesse de placer leur code source sous licence Creative Commons BY-NC-SA Respect de la Paternité - Pas d'utilisation commerciale - Partage des conditions initiales à l'identique..

Nous les en remercions chaleureusement.

Type d'une variable

Dans les langages de programmation comme Python, un nombre comme 502 et un mot comme "classe", ne sont évidemment pas représentés de la même façon dans l'ordinateur, même si l'unité fondamentale de codage en informatique est le bit qui peut prendre deux valeurs 0 ou 1.

La façon dont une valeur est représentée dans le langage s'appelle son type.

En Python, un entier est de type int et un mot est de type str, qui signifie chaîne de caractères .

De plus, tous les nombres n'appartiennent pas au même type, par exemple les nombres réels sont approchées en machine par un sous-ensemble des décimaux qui est l'ensemble des flottants, de typefloat.

Enfin, dans les structures de test, nous utiliserons des booléens, des valeurs de type bool, qui ne prend que deux valeurs logiques True ou False.

En général, on ne peut pas réaliser une opération dont les opérandes sont des valeurs de types différents. Python applique toutefois des conversions de type implicites : on peut ainsi ajouter deux valeurs de types int et float et le résultat sera de type float.

In [8]: a = 502

In [9]: type(a)
Out[9]: int

In [10]: a = 502

In [11]: print(type(a))
<class 'int'>

In [12]: b = "pa"

In [13]: print(type(b))
<class 'str'>

In [14]: a = a + a

In [15]: a
Out[15]: 1004

In [16]: b = b = b

In [17]: b
Out[17]: 'pa'

In [19]: b = b + b

In [20]: print(b)
papa

In [21]: c = 1/3

In [22]: print(type(c))
<class 'float'>

In [23]: a + b
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-bd58363a63fc> in <module>()
----> 1 a + b

TypeError: unsupported operand type(s) for +: 'int' and 'str'

In [24]: d = a + c

In [25]: d
Out[25]: 1004.3333333333334

In [26]: print(type(d))
<class 'float'>

In [27]: e = True

In [28]: print(type(e))
<class 'bool'>

In [28]: f = False

In [29]: e and f
Out[29]: False

Le type int

En Python, les entiers signés (psoitifs et négatifs)) appartiennent au type int, qui n'est limité en taille que par la place disponible en mémoire.

Contrairement aux autres nombres réels, les entiers sont représentés de façon exacte en machine et doivent donc être privilégiés pour les calculs nécessitant une grande précision.

Les opérateurs arithmétiques usuels, présentés dans la page Découverte : console permettent de réaliser des opérations avec des entiers.

Opérateurs arithmétiques
+ Addition
- Soustraction
* Multiplication
/ Division à valeur réelle (type float)
// Division à valeur entière (type int), quotient de la division euclidienne
% Reste de la division euclidienne
** Exponentiation ou Puissance
( Parenthèse ouvrante
) Parenthèse fermante

Le type float

Les flottants sont des nombres décimaux dont le développement en base 2 est fini et ils sont de la forme $(-1)^s \times 2^{e} \times 1,\underbrace{010000100101\ldots 1}_{\text{mantisse m sur } 52 \text{ bits}}$ où le bit de signe $s$ est codé sur 1 bit, l'exposant $e$ est codé sur $11$ bits et la mantisse $m$ représentant le développement en base 2 de la partie fractionnaire est codé sur $52$ bits.

Les nombres entiers, de type int, sont représentés de façon exacte en machine mais ce n'est pas forcément le cas des nombres décimaux de type float. En classe de mathématiques, on apprend que les nombres réels à développement décimal infini, comme $\sqrt{2}$, peuvent être approchés par des nombres décimaux comme $1,4$. Mais un ordinateur, ne représente même pas $1,4$ de façon exacte car il compte en base $2$ et le développement de $1,4$ en base $2$ est infini.
Par conséquent, cela n'a pas de sens de tester l'égalité entre deux décimaux (type float), si on ne se donne pas une marge d'erreur acceptable. On donne ci-dessous quelques exemples, l'opérateur d'égalité mathématique, en Python, est noté ==.
Pour plus de détails on pourra consulter la page Arithmétique en nombres à virgule flottante : problèmes et limites de la documentation Python.

In [23]: 3 * 1.4
Out[23]: 4.199999999999999

In [24]: 3 * 1.4 == 4.2
Out[24]: False

In [25]: 0.1 + 0.1 == 0.2
Out[25]: True

In [26]: 0.1 + 0.1 + 0.1 == 0.3
Out[26]: False

In [27]: 3 * 0.1
Out[27]: 0.30000000000000004

Les flottants supportent les mêmes opérateurs arithmétiques usuels que les entiers . De plus ces opérateurs acceptent un opérande de type float et l'autre de type int, le résultat sera alors de type float.

Enchaîner les opérateurs

  1. Dans Pyzo, créer un nouvel onglet de l'éditeur de programme Python et l'enregistrer sur le disque dans le dossier Python2nde précédemment créé, sous le nom de fichier operateurs.py. On peut inclure la date du jour dans le nom de fichier, c'est pratique pour l'indexation.
  2. Loris effectue un aller-retour en vélo entre sa maison et celle de sa grand-mère distantes de 10 kilomètres. A l'aller il rouler à la vitesse moyenne de 23 km/h, il reste une heure chez sa grand-mère et au retour il s'arrête pour cueillir des mûres le long de la route et sa vitesse moyenne n'est que de 17 km/h.
    • Créer une cellule Exo 1 question 1 puis recopier le programme ci-dessous en le complétant afin qu'il calcule dans une variable tempsTotal la durée totale du trajet aller-retour.
      
      distance = 10
      vitesseAller = 23
      vitesseRetour = 17
      tempsAller = ....     #à compléter
      tempsRetour = ...     #à compléter
      tempsVisite = 1
      tempsTotal = ....     #à compléter
      print(tempsTotal)
      
    • Compléter le programme précédent avec le calcul de la vitesse moyenne de Loris sur l'ensemble du trajet aller-retour, sans inclure le temps de visite chez sa grand-mère.
  3. Le prix d'une matière première est de 873 euros la tonne au début de l'année. Ce prix subit des variations saisonnières : au premier trimestre il augmente de 347 euros, au second trimestre il augmente de 25 %, au troisième trimestre il subit une baisse de 50 % et enfin il diminue de 100 euros.
    • Créer une cellule Exo 1 question 2 puis recopier le programme ci-dessous en le complétant afin qu'il calcule l'évolution de la variable prix en complétant le programme ci-dessous
      
      	prix = 873       #prix au début de l'année
      	prix = ....      #prix à la fin du premier trimestre
      	prix = ....      #prix à la fin du second trimestre
      	prix = ....      #prix à la fin du troisième trimestre
      	prix = ....      #prix à la fin de l'année
      	
    • Reprendre la question précédente dans une cellule Exo 1 question 3, en utilisant les opérateurs raccourcis d'affectation présentés ci-dessous.
raccourcis
n = n+1 n += 1
n = n-1 n -= 1
n = n*2 n *= 2
n = n/3 n /= 3
n = n//2 n //= 2

		
		
  • Corrigé question 1 (1/2)
  • Corrigé question 1 (2/2)
  • Corrigé question 2 (1/2)
  • Corrigé question 2 (2/2)
Le programme complété :

distance = 10
vitesseAller = 23
vitesseRetour = 17
tempsAller = 10/23     #à compléter
tempsRetour = 10/17     #à compléter
tempsVisite = 1
tempsTotal = tempsAller + tempsRetour + tempsVisite     #à compléter
print(tempsTotal)
On obtient le résultat :
2.02301790281
Le programme complété :

distance = 10
vitesseAller = 23
vitesseRetour = 17
tempsAller = 10/23     
tempsRetour = 10/17    
tempsVisite = 1
tempsTotal = tempsAller + tempsRetour + tempsVisite     
vitesseTotal = 20  / (tempsTotal - tempsVisite)
print(vitesseTotal)
On obtient le résultat :
19.55
Le programme complété :

prix = 873                      #prix au début de l'année
prix = prix + 347               #prix à la fin du premier trimestre
prix = prix * (1 + 25/100)      #prix à la fin du second trimestre
prix = prix / 2                 #prix à la fin du troisième trimestre
prix = prix - 100               #prix à la fin de l'année
print(prix)
On obtient le résultat :
662.5
Le programme complété :

prix = 873        #prix au début de l'année
prix += 347       #prix à la fin du premier trimestre
prix *= 1.25      #prix à la fin du second trimestre
prix /= 2         #prix à la fin du troisième trimestre
prix -= 100       #prix à la fin de l'année
print(prix)
On obtient le résultat :
662.5

Expression algébrique

Associer chacun des trois programmes (le résultat du programme est le contenu de la variable a dans chaque cas) ci-dessous à l'une des expressions en glissant les étiquettes de la bande horizontale du bas sur les zones grisées.

2+3*(6+7) 2+3*(6+7)
(2+3)*(6+7) (2+3)*(6+7)
(2+3)*6+7 (2+3)*6+7
  • Commentaire

Il suffit de tester pour vérifier...


		
		

Le type str

Syntaxe des chaînes de caractères

En Python, les caractères, les mots, les phrases et autres combinaisons des caractère alphabétiques ou de mise en forme (tabulations, espaces) appartiennent au type str, qui signifie chaîne de caractères.

Pour distinguer les chaînes de caractères des mots clefs du langage et des identificateurs de variables, on les délimite par des symboles spéciaux : l'apostrophe ', le guillemet " ou un délimiteur triplé ''' ou """.


In [5]: a = 'une chaine délimitée par des apostrophes'

In [6]: print(type(a))
<class 'str'>

In [7]: print(a)
une chaine délimitée par des apostrophes

In [8]: b = "une chaine délimitée par des guillemets"

In [9]: print(type(b))
<class 'str'>

In [10]: c = 'Des "guillemets" dans une chaine'

In [11]: c
Out[11]: 'Des "guillemets" dans une chaine'

In [12]: d = "L'apostrophe dans une chaine"

In [13]: d
Out[13]: "L'apostrophe dans une chaine"

In [14]: e = 'L\'apostrophe échappée avec un backslash'

In [15]: e
Out[15]: "L'apostrophe échappée avec un backslash"

In [16]: f = """Une chaine 
    ...:        multiligne avec "guillemets"
    ...:        et l'apostrophe
    ...:        """

In [17]: f
Out[17]: 'Une chaine \n       multiligne avec "guillemets"\n       et l\'apostrophe\n       '

Opérateurs sur les chaînes de caractères

  • L'opérateur in permet de tester l'appartenance d'un caractère ou d'une sous-chaîne à une chaîne de caractères.
    
    		In [20]: chaine = 'Bonjour'
    		
    		In [21]: 'b' in chaine
    		Out[21]: False
    		
    		In [22]: 'B' in chaine
    		Out[22]: True
    		
  • L'opérateur + permet de concaténer deux chaînes de caractères. Attention, l'opérateur - n'est pas défini pour les chaînes de caractères.
    
    		In [28]: chaine = 'Bonjour'
    		
    		In [29]: chaine2 = chaine + ' à tous.'
    		
    		In [30]: print(chaine2)
    		Bonjour à tous.
    		
  • La fonction len permet d'obtenir le nombre de caractères contenus dans une chaîne de caractère. Attention les caractères invisibles comme les espaces et les fins de ligne comptent !
    
    		In [31]: chaine2
    		Out[31]: 'Bonjour à tous.'
    		
    		In [32]: print(len(chaine2))
    		15
    		
  • La méthode lower permet de convertir tous les caractères en minuscules. La méthode upper permet de convertir tous les caractères en majuscules. Il s'agit de méthodes internes qu'on applique avec la syntaxe chaine.lower() ou chaine.upper().
    
    		In [33]: chaine3 = chaine2.lower()
    		
    		In [34]: chaine3
    		Out[34]: 'bonjour à tous.'
    		
    		In [35]: chaine4 = chaine2.upper()
    		
    		In [36]: chaine4
    		Out[36]: 'BONJOUR À TOUS.'
    		
  • Avec la syntaxe chaine[index] permet de lire un caractère dans une chaîne de caractère : les caractères sont indexés de 0 pour le premier à len(chaine) - 1 pour le dernier. Une autre indexation à partir de la fin de la chaîne est disponible : le dernier caractère est index par -1 et le premier par -len(chaine). Si aucun caractère n'est repéré par l'index demandé, on obtient une erreur index out of range.
    
    		In [37]: chaine
    		Out[37]: 'Bonjour'
    		
    		In [38]: chaine[0]
    		Out[38]: 'B'
    		
    		In [39]: chaine[1]
    		Out[39]: 'o'
    		
    		In [40]: chaine[len(chaine) - 1]
    		Out[40]: 'r'
    		
    		In [41]: chaine[-1]
    		Out[41]: 'r'
    		
    		In [42]: chaine[-2]
    		Out[42]: 'u'
    		
    		In [43]: chaine[-len(chaine)]
    		Out[43]: 'B'
    		
    		In [44]: chaine[len(chaine)]
    		---------------------------------------------------------------------------
    		IndexError                                Traceback (most recent call last)
    		<ipython-input-44-e70a16679e7b> in <module>()
    		----> 1 chaine[len(chaine)]
    		
    		IndexError: string index out of range
    		
    		
  • Avec la syntaxe chaine[debut:fin:pas] permet de lire une sous-chaîne dans une chaîne de caractère en prenant tous les caractères de l'index debut inclus jusqu'à l'index fin exclu avec un pas fixé, qui peut être négatif. On parle de slicing . Par défaut l'index de début est 0, l'index de fin est len(chaine) et le pas est de 1 et on laisse vide ces paramètres si on utilise les valeurs par défaut.
    
    		In [68]: chaine = 'Bonjour'
    		
    		In [69]: chaine[0:2]
    		Out[69]: 'Bo'
    		
    		In [70]: chaine[-3:-1]
    		Out[70]: 'ou'
    		
    		In [71]: chaine[-3:]
    		Out[71]: 'our'
    		
    		In [72]: chaine[0:2]
    		Out[72]: 'Bo'
    		
    		In [73]: chaine[0:2]
    		Out[73]: 'Bo'
    		
    		In [74]: chaine[-3:]
    		Out[74]: 'our'
    		
    		In [75]: chaine[2:5]
    		Out[75]: 'njo'
    		
    		In [76]: chaine[:]
    		Out[76]: 'Bonjour'
    		
    		In [77]: chaine[::2]
    		Out[77]: 'Bnor'
    
    		In [78]: chaine[1:5:2]
    		Out[78]: 'oj'
    
    		In [79]: chaine[::-1]
    		Out[79]: 'ruojnoB'
    		
Les chaînes de caractères sont non mutables, c'est-à-dire qu'elles sont accessibles en lecture seule et qu'elles ne peuvent pas être modifiées.

		In [63]: chaine = 'papa'
		
		In [64]: chaine[-1]
		Out[64]: 'a'
		
		In [65]: chaine[-1] = 'i'
		---------------------------------------------------------------------------
		TypeError                                 Traceback (most recent call last)
		<ipython-input-65-0fc03e1416a6> in <module>()
		----> 1 chaine[-1] = 'i'
		
		TypeError: 'str' object does not support item assignment
		

Jouer avec une chaîne de caractères

  1. Dans Pyzo, insérer une nouvelle cellule Exo 3 à la suite du fichier operateurs.py.
  2. A partir du code ci-dessous, créer de nouvelles chaînes de caractères :
    • chaine2 est constituée uniquement du premier et du dernier caractère de chaine1.
    • chaine3 est constituée uniquement des deux premiers caractères de chaine1 suivis des deux derniers.
    • chaine4 contient tous les caractères de chaine1 d'index pair.
    • chaine5 contient tous les caractères de chaine1 d'index impair.
    • L'ordre des caractères de chaine1 est inversé dans chaine6.

		
		
  • Corrigé question 2
Le programme complété :

chaine1 = "algorithmique"
chaine2 = chaine1[0] + chaine1[-1]
chaine3 = chaine1[:2] + chaine1[-2:]
chaine4 = chaine1[::2]
chaine5 = chaine1[1::2]
chaine6 = chaine1[::-1]
print(chaine2)
print(chaine3)
print(chaine4)
print(chaine5)
print(chaine6)
On obtient le résultat :
ae
alue
agrtmqe
loihiu
euqimhtirogla

Le type bool

Un type avec deux valeurs

Le type booléen, noté bool en Python, ne contient que deux valeurs True ou False


	In [47]: a = True
	
	In [48]: print(type(a))
	<class 'bool'>
	
	In [49]: b = False
	
	In [50]: print(type(b))
	<class 'bool'>
	

Booléens et tests

Les valeurs booléennes sont obtenues comme résultats de tests de comparaison (égalité, inégalité).

test symbole
Est-ce égal ? ==
Est-ce distinct ? !=
Est-ce strictement inférieur à ? <
Est-ce strictement supérieur à ? >
Est-ce inférieur ou égal à ? <=
Est-ce supérieur ou égal à ? >=

		In [51]: 5 == 3
		Out[51]: False
		
		In [52]: a = (5 == 3)
		
		In [53]: type(a)
		Out[53]: bool
		
		In [54]: a
		Out[54]: False
		
		In [55]: b = (5 > 3)
		
		In [56]: type(b)
		Out[56]: bool
		
		In [57]: b
		Out[57]: True
		
		In [58]: c = (5 != 3)
		
		In [59]: c
		Out[59]: True
		

Théorème de Pythagore

  1. Dans Pyzo, insérer une nouvelle cellule Exo 4 à la suite du fichier operateurs.py.
  2. On considère un triangle dont les longueurs des côtés sont stockées dans les variables a, b et c. Saisir le code suivant, prévoir les valeurs affichées avant l'exécution puis vérifier en exécutant :
    
    a = 3
    b = 4
    c = 5
    print(a, b, c)
    print(c**2 == a**2 + b**2)
    		
  3. Compléter le code précédent avec les instructions suivantes, prévoir les valeur affichées avant l'exécution puis vérifier en exécutant. Que peut-on observer ?
    
    a /= 10
    b /= 10
    c /= 10
    print(a, b, c)
    print(c**2 == a**2 + b**2)
    a /= 10
    b /= 10
    c /= 10
    print(a, b, c)
    print(c**2 == a**2 + b**2)
    		

		
		
  • Corrigé question 1
  • Corrigé question 2
Le programme affiche la valeur booléenne True puisque 3, 4 et 5 constituent un triplet pythagoricien.

Mathématiquement on a l'équivalence : \[ c^2 = a^2 + b^2 \Longleftrightarrow \left(\frac{c}{10}\right)^2 = \left(\frac{a}{10}\right)^2 + \left(\frac{b}{10}\right)^2 \] On devrait donc obtenir la valeur booléenne True pour tous les tests d'égalité c ** 2 == a ** 2 + b ** 2 si on divise par 10 tous les nombres d'un triplet pythagoricien (ce qui revient à diviser par 10 toutes les dimensions d'un triangle rectangle qui estera rectangle même après réduction).
Dans l'ordinateur c'est différent, puisqu'on le rappelle, si la machine manipule des représentations exactes des entiers, ce n'est pas le cas pour les décimaux qui sont représentés de façon approchée par des flottants. Ces derniers sont des décimaux dont le développement en base 2 est fini. Pour plus de détails on pourra consulter la page Arithmétique en nombres à virgule flottante : problèmes et limites de la documentation Python.
En pratique, il n'est donc pas raisonnable de vouloir comparer deux flottants. Pour ce faire on fixe une marge d'erreur et on peut utiliser par exemple la fonction isclose en l'important depuis le module math.

.

Voici un code modifiée avec isclose.


from math import isclose
a = 3
b = 4
c = 5
print(a, b, c)
print(c**2 == a**2 + b**2)
a /= 10
b /= 10
c /= 10
print(a, b, c)
print(c**2 == a**2 + b**2)
a /= 10
b /= 10
c /= 10
print(a, b, c)
print(c**2 == a**2 + b**2)
print(isclose(c**2, a**2 + b**2))
		

Le résultat affiché est le suivant :

3 4 5
True
0.3 0.4 0.5
True
0.03 0.04 0.05
False
True