5. Variables et types de données#

5.1. Variables et affectations#

En programmation impérative, l’un des aspects les plus important est la manipulation des données. Pour cela, nous devons pouvoir les stocker.

Une variable permet de référencer des données pour les réutiliser ensuite. Pour créer une variable il suffit de lui affecter une valeur avec l’opérateur =. Ceci a pour effet de créer une liaison entre un nom et une donnée.

Une fois, une liaison crée, il est possible de s’en servir. Par exemple avec la fonction print qui permet d’afficher à l’écran le contenu d’une variable.

a = 1
print(a)
1

Nous avons déjà vu qu’il est impossible de se servir d’une variable, par exemple pour en afficher à l’écran le contenu, si cette dernière n’a pas été créée. Cela entraine une erreur ; le programme s’arrête.

Ainsi, sur l’exemple suivant, l’affectation qui crée la variable b (ligne 2) est après son utilisation (ligne 1). Cela entraine une erreur lors de l’exécution du programme et l’affichage de cette dernière.

Il faut apprendre à lire les messages d’erreur. Ici on nous indique que le nom b, à la ligne 1, n’est pas lié à une valeur. L’interpréteur nous dit qu’il est “non défini”.

print(b)
b = 2
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 print(b)
      2 b = 2

NameError: name 'b' is not defined

5.2. Nom des variables#

Le nom d’une variable peut contenir toute combinaison de caractères alpha-numériques et souligné (_) pourvu qu’elle ne débute par un chiffre et ne corresponde pas à un mot clef du langage. Voici quelques exemples de noms acceptables: a, une_variable, uneAutre, a2. Voici d’autres noms qui eux ne sont pas autorisés : 1autre (commence par un chiffre), if (est un mot clef réservé du langage).

Notons enfin que les noms sont sensibles à la distinction entre majuscules et minuscules (ma_variable ≠ Ma_VaRiAbLE).

Enfin, pour des questions d’encodage des caractères (nous rentrerons pas le détail), les lettres accentuées sont à bannir dans les noms de variables.

5.3. Visualisons l’affectation dans la mémoire#

Nous allons tenter de voir plus en détail le processur de l’affectation et ce qui se passe dans la mémoire. Dans la vidéo ci-dessous, nous utilisons la fonction python id. Cette fonction n’étant pas implémenter dans notre outils web vous n’aurez pas la possibilité de reproduire en direct cette expérience.

Je vous invite à regarder cette vidéo qui explique des éléments important de Python. Il faut exécuter la cellule suivante pour que la vidéo apparraisse.

5.4. Les types numériques#

5.4.1. Qu’est ce qu’un type de données ?#

Les données ont toujours un type qui définit les valeurs que peuvent prendre ces dernières ainsi que les opérateurs qui peuvent leur être appliqués. Voici quelques types classiques que nous utiliserons :

  • Un entier 2

  • Un nombre à virgule 3.14

  • Une chaîne de caractères "Python"

  • Une liste d’entiers [3, 2, 1]

Pour connaître le type d’une donnée, on utilise la fonction type.

a = 3
print(type(a))
a = 3.14
print(type(a))

L’exemple ci-dessus montre qu’en Python, seules les données ont un type. Il n’y a pas de type attaché aux variables. La variable a est successivement associée à un nombre entier puis un nombre à virgule flotante.

5.4.2. Les nombres entiers et à virgule flotante#

En Python, le type correspondant aux entiers est le type int. Ces litéraux sont par exemple 0, 1, -10 ou 986758.

Pour représenter les nombres à virgule, on utilise les float. Les valeurs 3.1415, -1.2, 0.0 mais aussi 0. sont des exemples de litéraux.

Python dispose d’un ensemble d’opérations d’arithmétique sur les nombres : addition, soustraction, produit, division réelle, division entière, reste de la division entière et exponentiation.

5.4.3. Les opérations sur les nombres#

Python dispose d’un ensemble d’opérations de base sur les nombre : addition, soustraction, produit, division réelle, division entière, reste de la division entière et exponentiation.

Attention, contrairement à certain langage, le résultat d’une division réelle sur des int est un float (voir l’exemple ci-dessous).

print( "Addition : 9+2" )
print(9+2)
print( "Soustraction : 9-2" )
print(9-2)
print( "Produit : 9*2" )
print(9*2)
print( "Division reelle : 9/2" )
print(9/2)
print( "Division entiere : 9//2 " )
print(9//2)
print( "Reste de la division entiere : 9%2" )
print(9%2)
print( "Exponentiation : 9**3 soit 9*9*9" )
print(9**3)

5.5. Exercices : variables et opérations simples#

Voici quelques exercices simples. Pour les réaliser vous n’aurez besoin que de l’interpréteur Python. Vous l’utiliserez « comme une calculette » pour vous familiariser avec les variables.

La solution aux exercices est systématiquement fournie mais elle est cachée. Pourquoi ? Car si vous regardez la solution avant d’avoir cherché à résoudre le problème par vous même, vous n’avancerez pas. Rappelez-vous encore et toujours, que pour la programmation, si l’on essaie pas, on n’avance pas.

Question : Créez deux variables a et b et affectez-leur les valeurs 5 et 10. Créez une variable c contenant le résulat de a+b. Créez une variable d contenant le résultat de c*a.

Voici une correction possible.

Utilisation de l’opérateur d’affectation =.

a = 5
b = 10
c = a + b
d = c*a

Question : Augmentez de un, la valeur contenu dans d.

Voici une correction possible.

Rappelez vous que le symbole = en Python n’est pas une égalité en mathématique, c’est une affectation. On calcule le résultat de l’opération à droite du symbole puis on stocke le résultat dans la variable à gauche.

d=d+1

Question : Faites la division entière de 22 avec 3. Comprenez vous pourquoi le résultat est 7 ?

Voici une correction possible.

Le résultat est 7 car 22 = 7*3 + 1.

22/3

Question : Calculez le reste des divisions entières de 3, 17 et 1879 avec 2. Comprenez-vous pourquoi le résultat est toujours 1 ?

Voici une correction possible.

Les nombres 3, 17 et 1879 sont tous impairs, c’est pour cela que le reste de la division entière avec 2 est toujours 1. Avec des nombres pairs, le résultat serait toujours 0. Autrement dit, si le reste de la division entière d’un nombre x avec 2 est 0 alors x est pair sinon, il est de 1 et x est impair.

3 % 2
17 % 2
1879 % 2

Question : Calculez le résultat du calcul suivant. Vous pouvez utiliser des variables pour décomposer le calcul. \(2^{10} * ((30 / (4+1)) - 5) * 0.0009765625\)

Voici une correction possible.

Le résultat est \(1.0\), c’est un nombre à virgule flotante. Attention, en anglais comme en Python, le séparateur pour la partie décimale d’un nombre est le point là où les français utilise la virgule. Ne vous trompez pas.

a = 2**10
b = ((30/(4+1))-5)
a * b * 0.0009765625

5.6. Compléments sur l’affectation#

Dans les langages de programmation, une expression est une combinaison de variables, de littéraux, d’opérateurs et de fonctions. Une expression est évaluée lors de l’exécution d’un programme et renvoie (est substituée par) la valeur resultant de son calcul. Cette valeur peut ensuite être utilisée.

Dans le cas d’une affectation. Le résultat du calcul de l’expression à droite du symbole = est lié avec la variable placée à gauche.

L’affectation est donc différente de l’égalité mathématique et il n’est pas supprenant de rencontrer des affectations telles que : v = v + 1.

Lors de l’évaluation de cette instruction, la valeur associée à v sera additionnée avec la valeur 1 puis le résultat obtenu sera associé à la variable v. On peut abréger l’instruction ci-dessus en :v += 1.

Ceci est valable pour tous les opérateurs arithmétique de base.

  • var += k

  • var -= k

  • var /= k

  • var //= k

  • var %= k

  • var *= k

  • var **= k

Vous devriez maintenant être capable de comprendre l’exemple suivant et deviner son résultat avant d’exécuter le code.

v = 10
print( v )
v += v*v+1 # v= v+(v*v+1)
print( v )

5.7. Entrée/sortie et conversions de types#

Nous avons déjà vu comment afficher des chaines de caractères avec la fonction print() cependant nous souhaiterions afficher des chaines plus complexes. Pour cela nous utilisons l’opérateur + de concaténation de chaines de carcatères.

s1 = "une chaine "
s2 = "suivie d'une autre"
s = s1 + s2
print( s )

Cet opérateur ne permet de mettre bout à bout que des chaines de caractères. Ainsi l’exemple suivant ne s’exécutera pas sans erreur : can only concatenate str (not "float") to str.

Pour que l’on puisse faire cette concaténation, il est nécessaire de convertir le nombre à virgule flotante en une chaine. Pour cela on utilise la fonction str() qui convertie n’importe quelle valeur en chaine de caractères.

Modifiez le code en utilisant str(3.1415).

s = "La valeur de Pi est : " + 3.1415
print( s )

En complétement avec la fonction print; nous utiliserons la fonction input() pour demander à l’utilisateur de saisir du texte. Cette fonction vaut la valeur saisie, sous la forme d’une chaîne de caractères.

s = input()
print( "La chaine saisie est : " + s)

Cette fonction nous permet de demander à un utilisateur de saisir des nombres mais attention car la fonction renvoie une valeur de type chaine de caractères (str). Elle est ne peut donc être utilisée dans un calcul numérique. Ainsi l’exemple suivant génère une erreur à la ligne 4.

print("Votre annee de naissance ?")
n = input()
print( "Le type de la variable n est : " + str( type(n) ) )
age = 2018 - n
print(age)

Pour résoudre ce problème il faut convertir la chaine en une valeur numérique. On utilise la fonction int(). Cette dernière prend en paramètre une valeur de n’importe quel type et renvoie un entier. La fonction float fonctionne de la même façon mais renvoie un nombre à virgule flotante. Vous devriez maintenant pouvoir corriger le code ci-dessus pour qu’il ne génère plus d’erreurs en modifiant la ligne 4 : age = 2018 - int(n)

5.8. Exercices#

Question : Convertissez la valeur 13.7 en un entier.

Voici une correction possible.

On utilise la fonction int(). On obtient une troncation du nombre, ce n’est pas un arrondi.

int(13.7)

Question : Convertissez l’entier 6 en un nombre à virgule flotante.

Voici une correction possible.

On utilise la fonction float(). Pour Python, les nombres 6 et 6.0 sont distincts, ils ne sont pas de même nature.

float(6)

Question : Calculez la formule suivante, où \(x\) est un nombre saisi par l’utilisateur : \(x + 6.5\).

Il faut saisir une chaîne de caractère, mais attention, il faut la convertir avant de s’en servir dans le calcul.

x = float(input())
x+6.5

Note

Si on omet la convertion en float, on obtient une erreur. Ce que nous dit le message d’erreur est que l’opération de + ne peut pas être utilisé entre des chaînes de caractères et des nombres : can only concatenate str (not "int") to str. On ne peut le faire qu’une chaîne de caractères et une autre.

x = input()
x+10

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [9], line 2
      1 x = input()
----> 2 x+10

TypeError: can only concatenate str (not "int") to str

On peut la convertir en nombre à virgule flotante. Dans ce cas, si on saisi 13.5 comme valeur pour x, on obtiendra 20.0. Le résultat d’une opération avec un nombre à virgule est toujours un nombre à virgule, même si la partie décimale est nulle.

x = float(input())
x+6.5

On peut tout aussi bien convertir la chaîne de caractères en entier. Et dans ce cas, si on saisi 13 on obtiendra 19.5. La encore, on obtient un nombre à virgule.

x = int(input()) x+6.5

Mais attention, Python ne sait pas convertir une chaîne de caractères en entier si le nombre contient une virgule. Donc si on saisi 13.5 on obtient une erreur : invalid literal for int() with base 10: '13.5'.

x = int(input()) x*10

C’est un peu particulier, Python sait convertir un nombre à virgule flotante en entier (il fait une troncation), mais il ne sait pas convertir directement une chaîne de caractères qui représente un nombre à virgule. On peut le faire en deux temps si c’est vraiment ce que l’on veut. On obtient alors encore 19.5.

x = int(float(input())) x+6.5

Question : Testez l’opération suivante « x. » * 3. Avez-vous une idée de ce qui se passe ?

L’opération (ici *) réalisée dans un calcul dépendant de la nature des opérandes. Comme on s’y attend, l’opération * entre des entiers ou des nombres à virgules est l’opération mathématique classique. Par contre lorsqu’on fait intervenir une chaîne de caractères et un entier alors c’est une opération permettant la multiplication de la chaîne.

"x." * 3
"x.x.x."

Note

Attention, ceci n’est pas possible avec un nombre à virgule. Le message d’erreur est clair. Cette opération ne peut pas être réaliser avec autre chose qu’un entier : can't multiply sequence by non-int of type 'float'.

"x." * 3.5

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [6], line 1
----> 1 "x." * 3.5

TypeError: can't multiply sequence by non-int of type 'float'

Rappelez vous donc que la fonction d’un opérateur dépend des opérandes. Dans ces deux exemples, le + entre deux chaîne de caractères permet de construire une nouvelle chaîne qui est la concaténation d’autres chaînes.

"Une chaine " + "et une autre."
'Une chaine et une autre.'


"La valeur est : " + str(3) + "."
'La valeur est : 3.'

Mais attention, on ne peut faire apparaitre un + qu’entre des chaînes de caractères. L’opération sans la conversion explicite de l’entier en chaîne donne une erreur : can only concatenate str (not "int") to str. Là encore le message est assez clair. Apprenez à les lire.

"La valeur est : " + 3 + "."

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [18], line 1
----> 1 "La valeur est : " + 3 + "."

TypeError: can only concatenate str (not "int") to str