Licence CC BY-NC-ND, Thierry Parmentelat & Arnaud Legout

from IPython.display import HTML
HTML(filename="_static/style.html")

les nombres#

les types de base pour les nombres sont:int, float, complex, bool

les entiers#

  • les int ont une précision illimitée

    • Python peut calculer nativement

92857234957203457234572203957 * 948572349572039457029347529347
88081805538117400166084413860573792922096998567618527026079

ceux qui ont eu à faire ça en C apprécieront

nombres : division#

les opérations usuelles ne posent pas de souci, c’est bien sûr + - * avec ( et )
mais la division mérite quelques mots:

# division exacte/flottante
8 / 5
1.6
# division entière (quotient)
8 // 5
1
# reste div. entière
8 % 5
3

nombres : opérateurs#

# bcp d'autres opérations disponibles
# et notamment:

2 ** 32         # puissance
4294967296
# tous les opérateurs peuvent être utilisés
# pour faire un effet de bord comme ceci

x = 10
x += 2
x
12

conversions#

int(234.5)      # cast float ➔ int
234

à retenir !

un type en Python est aussi une usine à objets,
il peut être utilisé comme une fonction
ici l’appel int(234.5) consiste à appeler le type int
pour fabriquer un objet, de type int donc, à partir de la valeur 234.5

moins crucial

il existe aussi des fonctions floor() et ceil() dans le module math
toutefois la méthode ci-dessus est plus générale, elle s’applique à tous les types en Python

nombres complexes#

# pour écrire un complexe
# il faut utiliser j et non pas i

1j * 1j
(-1+0j)
a = 3 + 4j

# partie réelle
a.real
3.0
# partie imaginaire
a.imag          
4.0

les attributs, encore..

remarquez qu’ici à nouveau, le terme a.real consiste à rechercher l’attribut real dans l’objet (désigné par) a

le module math#

# pour anticiper un peu
# sur les listes...
# ici on veut les 6 derniers
# symboles dans le module math

import math

dir(math)[-6:]
['sumprod', 'tan', 'tanh', 'tau', 'trunc', 'ulp']
math.tau
6.283185307179586
math.sin(math.pi)
1.2246467991473532e-16

exo: entrainez-vous à chercher dans google

entraînez vous à trouver rapidement la doc de ce module dans google en cherchant par exemple “python module math

https://www.google.com/search?q=python+module+math

décortiquons un peu

après l’import, la variable math désigne donc un objet de type module
et à nouveau, l’écriture math.tau consiste à rechercher l’attribut tau dans cet objet module
et pareil exactement pour math.sin, qui désigne … un objet fonction

booléens#

# il y a aussi le type booléen

10 <= 12
True
# avec comme valeurs True et False

10 >= 12
False
# True c'est presque exactement 1

True == 1
True
# et False presque exactement 0

False == 0
True
# mais pas tout à fait quand même

type(True)
bool
# alors que

type(1)
int

opérateurs sur les booléens#

# tout simplement avec les mots-clé and, or, et not

x = 10

(8 <= x) and (x <= 12)
True
# cela dit dans ce cas-là on peut écrire
# de manière plus simple

8 <= x <= 12
True
# pour tester l'égalité (on en a déjà parlé)

x == 10
True
# pour tester l'inégalité

x != 10
False

opérateurs is et in#

  • is permet de savoir si deux objets sont le même objet - c’est-à-dire correspondent à la même adresse en mémoire

  • in permet de savoir si un objet fait partie d’un autre objet

avec ces deux opérateurs, le not permet des syntaxes plutôt lisibles

  • x is not y

  • x not in y

voyons cela sur un exemple vous vous souvenez de l’exemple avec les deux objets liste ?

# ici on crée deux objets liste distincts

# le premier (avec deux références)
a = b = [1, 2]
# le deuxième
c = [1, 2]
%load_ext ipythontutor
%%ipythontutor curInstr=2

a = b = [1, 2]
c = [1, 2]

du coup on peut écrire des choses comme

a is b
True
# plus lisible que   not (a is c)
a is not c
True
a == c
True
a != c
False

ou encore comme

1 in a
True
# plus lisible que   not (1 in a)
1 not in a
False

test sur un booléen#

# on peut - bien sûr - faire un `if`
# (ou un while) sur un booléen
a = 3
b = 4

type(a == b)
bool
# ici le sujet du if est bien booléen

if a == b:
    print("pareils")
else:
    print("différents")
différents

test sur un non-booléen#

# mais aussi : avec n'importe quoi d'autre
# ici le sujet du if est un nombre

if a:
    print("pas faux")
pas faux
# en fait équivalent à ceci:

if bool(a):
    print("pas faux")
pas faux

valeurs “fausses” ?

les valeurs “fausses” correspondent à un nombre nul, ou à un container vide (liste, chaine, ..)

tests sur une valeur non booléenne & conversion#

en fait ce qui est à l’oeuvre ici, c’est la mécanique générale pour convertir entre types de données:

# si on appelle int() on convertit en entier

int(3.4)
3
# eh bien de la même manière
# si on appelle bool() on convertit en booléen

bool(3.4)
True
# un nombre nul est "faux"

bool(0)
False
# une chaine vide est "fausse"

bool("")
False
# un nombre non nul est "vrai"
bool(1)
True
# une chaine non vide - même avec 
# un seul espace - est "vraie"
bool(" ")
True

l’encodage des flottants#

  • représentés en machine comme des fractions en base 2

  • le plus souvent une approximation

    • quand pas une fraction binaire exacte

  • pas une spécificité de Python

# flottant = imprécision structurelle !

0.1 + 0.2
0.30000000000000004

float = 64 bits#

  • sur une machine 64 bits, un float est encodé en double précision, i.e. avec:

    • 1 bit de signe

    • 11 bits pour représenter l’exposant

    • 52 bits pour représenter la mantisse

# pour obtenir des infos sur la précision des flottants

import sys
sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

à retenir

sur 64 bits, l’erreur relative est de l’ordre de \(10^{-15}\) / \(10^{-16}\)

pas spécifique à Python#

  • pas un problème spécifique à Python

  • si vous ne faites pas de l’analyse numérique

    • ce problème n’a probablement aucun impact pour vous

  • sinon, vous êtes déjà au courant

    • et vous savez notamment qu’il ne faut pas tester avec une égalité stricte

    • mais plutôt avec un presque égal : utiliser math.isclose

0.3 == 0.1 + 0.2
False
import math

math.isclose(0.3, 0.1+0.2)
True

contournements#

pour contourner#

  • le module decimal, pour travailler sur des nombres décimaux

    • avec plus de précision et de contrôle qu’avec le type float

  • le module fractions permet de travailler sur des rationnels

exemples - decimal#

from decimal import Decimal
x = Decimal('0.1') + Decimal('0.2')
x == Decimal('0.3')
True

exemples - fractions#

from fractions import Fraction
x = Fraction(1, 10) + Fraction(2, 10)
x
Fraction(3, 10)
x == Fraction(3, 10)
True
x == 0.3
False

plus exotique#

entrer un entier en hexa, binaire, octal#

pour créer des entiers sous forme littérale, dans d’autres bases

# hexadécimal
0xff
255
# binaire
0b11111111
255
# octal
0o377
255

afficher un entier sous forme hexa, binaire, octale#

dans l’autre sens, trouver la représentation en base n
sous forme de chaine de caractères du coup

hex(255)    # traduire en hexa (-> str)`
'0xff'
bin(255)    # traduire en binaire (-> str)
'0b11111111'
oct(255)    # traduire en octal (-> str)
'0o377'

fonctions prédéfinies ou builtin

remarquez que nous n’avons pas défini les variables hex, bin et oct
ce sont des fonctions prédéfinies, connues de Python dès le lancement
le terme anglais pour désigner de telles fonctions est builtin

opérations bitwise#

y = 4
y | 2      # bitwise OR de 0100 (4) et 0010 (2)
6
y & 2      # bitwise AND de 0100 (4) et 0010 (2)
0
y & 15     # bitwise AND de 0100 (4) et 1111 (15)
4
~ y        # bitwise NOT - en pratique ~x == -(x+1)
-5
  • rarement utile d’utiliser les opérations bitwise en Python usuel

  • mais par contre très utile avec numpy et pandas
    pour manipuler notamment les masques

décalages#

x = 3
y = x << 10 # décalage à gauche
y
3072
2**11 + 2**10
3072
x          # l'argument n'est pas modifié
3
y >> 3     # décalage à droite
384
2**8 + 2**7
384