Petits rappels et mises à jour

publicité
C1 – Informatique – PSI
Petits rappels et mises à jour
Architecture d’un ordinateur
Il est important de connaître un minimum de vocabulaire sur les ordinateurs : processeur, mémoire, périphérique, bus,
mémoire vive, mémoire de masse, mémoire morte, système d’exploitation, environnement de développement…
Codage des nombres
On dit souvent qu’un ordinateur travaille en « binaire ». Qu’est-ce et pourquoi ? Représentation des entiers naturels, des
entiers relatifs et des nombres à virgules. Signe, exposant, mantisse (Norme IEEE 754).
Algorithmique et programmation
-
-
Algorithme : ensemble de règles opératoires dont l’application permet de résoudre un problème en un nombre fini
d’opérations.
Programme : séquences d’instructions et de données enregistrées sur un support et susceptibles d’être traitée par
un ordinateur, c’est la traduction d’un algorithme dans un langage particulier, à la fois interprétable par la machine
et compréhensible par l’homme. C’est un assemblage d’instructions, regroupées dans le code source. Son parcours
est appelé flot d’exécution.
Procédure : fonction particulière qui ne renvoie rien.
Q1. Quelles sont toutes les caractéristiques d’une variable ?
Q2. Citer les types de données possibles avec le langage Python ?
En Python, il existe en fait les entiers longs et les courts. Les entiers courts sont codés sur 32 bits (de −231 à 231 − 1). Les
entiers longs n’ont pas de limite prédéfinie, elle dépend juste de la mémoire attribuée à l’interpréteur Python par le
système d’exploitation. En Scilab, il existe plusieurs représentations des entiers : int8 (entier codé sur 8 bits, donc 1 octet),
int16…
Les listes peuvent être définies en "compréhension", c’est-à-dire avec des éléments donnés par une expression quand un
indice parcourt un ensemble.
Il existe aussi d’autres types non compris de base, mais pouvant être ajoutés avec différents modules, c’est le cas du type
decimal à précision infinie en utilisant le module Decimal.
PSI 2015 – 2016, Lycée St Louis
Page 1
C1 – Informatique – PSI
Q3. Voici un programme écrit en langage Python, détailler et expliquer toutes les étapes si on l’exécute :
i=5
j=i+8
print(i,j,’sont les deux valeurs’)
i = 12
print(i,j,’sont les deux valeurs’)
Q4. D'après vous, que fait ce programme ? Détailler les étapes.
a = 11
print(a)
a = a+1
print(a)
a = ‘a’+’1’
print(a)
Q5. Expliquer ces lignes de code :
(1+2) == 3
(0.1+0.2) == 0.3
Q6. Donner les réponses aux commandes suivantes écrites en Python :
L = [1, 0.2, ‘Python’, [2,4], (1,2,3)]
T = (1, 0.5, 1/3)
C = "Python c’est trop bien !"
len(L)
len(T)
len(C)
L[3]
L[4][1]
L[1:3:2]
L+L
L[2:88]
T[-2]
C[8]
C[0:len(C)-1]
Une grande différence au niveau des listes est que Python compte à partir de 0 et termine à la longueur de la liste-1, alors
que Scilab compte à partir de 1 et termine à la longueur de la liste. Donc pour faire appel au 1 élément d’une liste, on
utilisera a[0] en Python et a(1) en Scilab.
Q7. Voici une liste définie dans la console : L1 = [1, 2, 3, [1, 2, 3], 4, 5, 6], comme elle est assez longue, on souhaite en
faire une copie et ne pas modifier la liste initiale.
PSI 2015 – 2016, Lycée St Louis
Page 2
C1 – Informatique – PSI
Q8. Méthodes qui peuvent s’appliquer à des listes en Python seulement. Il en existe de nombreuses déjà définies. Pour
chacune des suivantes, expliquer très brièvement ce qu’elle fait, en considérant L : une liste et x une variable :
L.append(x)
L.pop()
L.extend(L)
L.pop(3)
L.insert(2,x)
L.index(x)
L.remove(x)
L.sort() et L.reverse()
L.count(x)
Le langage Python est un langage de Programmation Orientée Objet (POO : notion HP). En simplifiant, une méthode est
une fonction associée à une valeur (entier, liste…). Une valeur à laquelle est associée des méthodes est un objet. D’une
manière générale, la syntaxe d’appel d’une méthode est objet.methode(arguments). En simplifiant, ce n’est pas très
différent de l’appel d’une fonction où l’objet serait passé comme un argument supplémentaire, c’est-à-dire methode(objet,
arguments).
Q9. Utilisation de fonctions :
def nomdelafct(parametres) :
instructions # Vitesse
instructions
return resultat
function [l1] = nomdelafct(l2)
instructions
instructions // Vitesse
endfunction
Q10. Quels sont les résultats attendus après l’exécution de ces programmes ?
def f1(x) :
def f2(x) :
print(x**3)
return(x**3)
a = f1(2)
print(a)
a = f2(2)
print(a)
i=5
def f():
i=6
f()
print("la valeur de i est : "+str(i))
PSI 2015 – 2016, Lycée St Louis
Page 3
C1 – Informatique – PSI
def incr(e):
e = e+1
print(e)
e = 10
incr(e)
print(e)
function inc(e)
e = e+1
disp(e)
endfunction
e = 10
incr(e)
disp(e)
def f(x):
while (True):
x=x+1
if (x == 1000):
return 2 * x
print(f(500))
b = 12
if b < 18:
print (b)
elif 3 < b < 24:
print(‘a’)
else :
print(‘non’)
if b < 18 then
disp(b)
elseif 3 < b & b < 24 then
disp(‘a’)
else
disp(' non ')
end
def fonction1(n):
s,i = 0,1
while s < n:
s += i
i += 1
return i-1
def f(x):
global b
b = 10
return x + 1
a=3
b=4
print(f(a)+b)
def fonction2(n):
s,i = 0,1
while s < n:
s += i
i += 1
return i-1
a=3
b=4
print(f(a)+b)
def f(x):
global b
b = 10
return x + 1
def fonction3(n):
s,i = 0,1
while i <= n:
s += i
i += 1
return s
def f(x):
global b
b = 10
return x + 1
def g(x):
global a
a = 10
return 2 * x
def g(x):
global a
a = 10
return 2 * x
def g(x):
global a
a = 10
return 2 * x
a=3
b=4
print(b+f(a))
def f(x):
v=1
return g(x) + v
def f(x):
v=1
return g(x) + v
def f(x):
v=1
return g(x) + v
a=3
print(f(6)+a)
a=3
print(a+f(6))
a=3
print(a+f(6)+a)
L’utilisation de global n’est pas à privilégier ! L’intérêt est ici de faire la différence entre les variables locales et globales.
Il est essentiel de définir une documentation à chaque fonction ! Un nom bien choisi et des variables compréhensibles
aideront (il faut à tout prix évitez les a,b et c à tout bout de champ). Voici la façon officielle de faire (entre 3 guillemets), qui
permettra d’afficher cette documentation avec la commande help. Ne pas hésiter à utiliser des commentaires si vous en
sentez le besoin avec #.
PSI 2015 – 2016, Lycée St Louis
Page 4
C1 – Informatique – PSI
def cube(x) :
""" Donne le cube d’un nombre"""
return x**3
En tapant help(cube) dans la console, le résultat est :
Help on function cube in module __main__:
cube(x)
Donne le cube d’un nombre
Seules les opérations de base sont chargées par défaut dans la mémoire de Python. Il faut importer les autres fonctions
(qui sont regroupées souvent dans des bibliothèques ou modules). Parmi les modules les plus utiles, on peut citer :
math qui contient toutes les fonctions habituellement utilisées en analyse ;
- random qui permet de générer des nombres pseudo-aléatoires ;
- fractions qui permet de manipuler des nombres rationnels en valeur exacte ;
- numpy qui fournit des outils variés pour le calcul scientifique ;
- matplotlib.pyplot pour le tracé de courbes ;
- …
On peut aussi imaginer créer un fichier qui regroupe toutes les fonctions dont on a besoin et un autre qui contient le
déroulement réel des instructions nécessaires à la résolution de notre problème. Il suffira alors d’importer le fichier de
fonctions au début de celui d’instruction pour avoir accès aux fonctions. L’intérêt est la grande lisibilité qui découlera de
cette façon de faire.
Pour pouvoir utiliser les fonctions de ces modules, il faut les importer, il existe plusieurs façons de faire (liste non
exhaustive) :
import numpy → importe le module numpy tout entier et il faudra utiliser nompy.cos pour la fonction cosinus.
import numpy as np → importe le module numpy tout entier et il faudra utiliser np.cos pour la fonction cosinus.
from numpy import cos → importe seulement la fonction cosinus de numpy, il faudra utiliser cos.
Attention aux conflits entre des commandes de modules différents portant les mêmes noms !
Q11. Ecrire les instructions nécessaires pour afficher tous les diviseurs d’un entier n, l’entier n devant être obtenu par
une demande à l’utilisateur.
1
Q12. Déterminer le rang du dernier terme strictement positif de la suite récurrente définie par 𝑢𝑛+1 = 2 𝑢𝑛 − 3𝑛, la
valeur de 𝑢0 étant donnée dans la variable notée u_0.
Q13. On peut distinguer les fonctions totales (renvoient toujours un résultat quelle que soit la valeur des arguments) des
fonctions partielles (il n’est pas toujours possible de renvoyer un résultat). Un exemple classique est la division par
zéro qui est impossible. Ainsi, la fonction suivante peut interrompre le bon déroulement du programme :
def divm2(x, y):
return (y+3)/(x-2)
Comment faire pour ne pas stopper tout le programme, à cause d’une mauvaise valeur rentrée pour le 1er
argument de cette fonction ?
PSI 2015 – 2016, Lycée St Louis
Page 5
C1 – Informatique – PSI
Q14. Comment peut-on choisir entre plusieurs algorithmes de résolution d’un même problème ?
Q15. Montrer la terminaison de cet algorithme : Calcul du PGCG de deux entiers avec l’algorithme d’Euclide
def Euclide_PGCD(a,b):
while (b>0):
r=a%b
a,b = b,r
return a
Q16. Montrer la correction d’un algorithme.
On peut montrer qu’un algorithme se termine bien, sans pour autant qu’il ne donne toujours le bon résultat : c’est un
problème de correction.
Il faut alors contrôler l’algorithme en utilisant ce que l’on appelle un invariant de boucle. Un invariant de boucle est une
propriété, qui :
- est vérifiée après la phase d’initialisation ;
- reste vraie après l’exécution d’une itération ;
- conjointement à la condition d’arrêt, permet de montrer que le résultat attendu est bien celui qui est calculé.
Reprendre le cas de l’algorithme précédent permettant d’évaluer le PGCD de deux entiers, invariant de boucle : « Le PGCD
de 𝑎𝑛 et 𝑏𝑛 reste constant ».
Q17. Montrer la correction d’un algorithme : Insertion d’un réel dans une liste de nombres réels triés par ordre
croissant. On cherche à démontrer la correction du programme ci-dessous. On prendra comme invariant la
propriété suivante : la juxtaposition des listes tronquées T[0:i] et L[i+1 : n+1] est égale au tableau initial.
def Insertion_element(T,x):
n = len(T)
i = n-1
L = [0 for k in range(n+1)]
PSI 2015 – 2016, Lycée St Louis
Page 6
C1 – Informatique – PSI
while T[i] > x and i >= 0:
L[i+1] = T[i]
i = i-1
L[i+1] = x
for k in range(i+1):
L[k] = T[k]
return L
Q18. Montrer la complexité d’un algorithme.
En plus d’être correct, on demande à un algorithme d’être efficace. Cette efficacité peut être évaluée par :
- le temps que prend l’exécution de l’algorithme : c’est la complexité en temps. Le temps d’exécution dépend de la taille
des données fournies en entrées ;
- les ressources nécessaires à son exécution : c’est la complexité en mémoire. Avec le développement des techniques de
stockage (mémoires vives, mémoires flash, etc.), la limitation en espace et en vitesse d’accès n’est plus vraiment
d’actualité.
Notation
𝛩(1)
Type de complexité
𝛩(𝑛2 )
Complexité constante
𝛩(ln(𝑛))
Complexité logarithmique
𝛩(𝑛)
𝛩(𝑛 ln(𝑛))
𝛩(𝑛2 )
𝛩(𝑛3 )
Complexité linéaire
Complexité quasi-linéaire
Complexité quadratique
Complexité cubique
𝛩(𝑛𝑝 )
𝛩(𝑛ln(𝑛) )
𝛩(2𝑛 )
Complexité polynomiale
Complexité quasi-polynomiale
𝛩(2𝑛 )
Complexité exponentielle
𝛩(! 𝑛)
Complexité factorielle
𝛩(𝑛 ∗ ln(𝑛))
𝛩(𝑛)
𝛩(ln(𝑛))
Nous allons illustrer le calcul de complexité temporelle sur deux algorithmes permettant de calculer le nombre 𝑥𝑛 , où 𝑛 est
un entier positif et 𝑥 un nombre réel.
def exponentiation_naive(x,n):
res = 1
while n > 0:
res = res*x
n = n-1
return res
def exponentiation_rapide(x,n):
res = 1
while n > 0:
if n % 2 == 1:
res = res*x
x = x**2
n = n//2
return res
PSI 2015 – 2016, Lycée St Louis
Page 7
Téléchargement