TP programmation python¶

exercices de base¶

In [1]:
%matplotlib inline
import sys,os
import numpy as np
import scipy as sp
import matplotlib
import matplotlib.pyplot as plt
from random import random
import importlib
# initialisation
from validation.validation import info_etudiant, check_function,liste_functions, info_function
from validation.valide_markdown import test_markdown, test_code, test_algorithme
from IPython.display import display, Markdown, Latex
def printmd(string):
    display(Markdown(string))
# test si numero étudiant spécifier
try: NUMERO_ETUDIANT
except NameError: NUMERO_ETUDIANT = None 
if type(NUMERO_ETUDIANT) is not int :
    printmd("## ERREUR: numéro d'étudiant non spécifié!!!")
    NOM, PRENOM, NUMERO_ETUDIANT = info_etudiant()
    #raise AssertionError("NUMERO_ETUDIANT non défini")
# parametres spécifiques
_uid_    = NUMERO_ETUDIANT
np.random.seed(_uid_)
printmd("**Etudiant** {} {}  id={}".format(NOM,PRENOM,NUMERO_ETUDIANT))

ERREUR: numéro d'étudiant non spécifié!!!¶

Etudiant NBGrader Course id=2592889824

Consigne¶

L'objectif de ce TP est de tester vos connaissances en programmation Python

vous devez écrire les fonctions dont le nom est fixé, mais dont vous devez spécifier les arguments en fonction de la question posée.

Pour chaque exercice, on écrit le code dans une cellule, de façon autonome, donc en explicitant les bibliothèques à utiliser (même si elles ont été importées avant)

Algorithme de réussite¶

  1. Algorithme :

    • sur un papier, choisir un exemple pour comprendre ce qui est demandé
    • si nécessaire écrire des bouts de code Python pour comprendre comment faire
    • écrire l'algorithme décrivant ce qu'il faut faire en identifiant les données du problème, et le résultat attendu
  2. Programmation:

    • traduire l'algorithme en fonction python , en spécifiant les arguments et la valeur de retour.
    • attention au type des arguments (tableaux d'entiers, réel, ...)
    • utiliser une programmation simple, avec des boucles
  1. Vérification

    • choisir un jeu d'arguments quelconques pour vérifier son exécution.
    • dans une cellule, appeler la fonction avec ces arguments et vérifier le résultat.

Exercice 1: list_circ¶

Soient 2 entiers n et k donnés, on veut créer un tableau numpy d'entiers L de dimension n contenant les valeurs:

0 1 2 ... k-1 0 1 2 ... k-1 ...

Dans la cellule suivante, écrire les instructions correspondantes pour créer ce tableau en utilisant une boucle. Afficher le résultat pour vérifier

In [2]:
import numpy as np
n = 5
k = 3
## BEGIN SOLUTION
L = np.zeros(n,dtype=int)
for i in range(n):
    L[i] = i % k
print(L)
## END SOLUTION
[0 1 2 0 1]

Transformer le code précédent pour le transformer en fonction list_circ.

Ecrire la fonction list_circ dans la cellule suivante en changeant le nom des variables: p et q pour les 2 entiers et C pour le tableau

Vérification

Appeler la fonction précédente pour 2 valeurs de n et k aléatoires (utilisez randint) et mettre le résultat dans une variable L1. Affichez L1 et faire des tests pour

  1. vérifier le type de L1 (tableau numpy np.ndarray) avec type
  2. vérifier le type des éléments de L1 avec type
  3. vérifier la dimension du tableau L1

et afficher "erreur" en cas de non validation.

In [3]:
# fonction
## BEGIN SOLUTION
import numpy as np

def list_circ(p,q):
    ''' renvoie un tableau numpy de dimension p contenant  0 1 2 ..q-1 0 1 2 .. q-1 ....'''
    C = np.zeros(p,dtype=int)
    for i in range(p):
        C[i] = i % q
    return C
## END SOLUTION
# vérification pour des valeurs aléatoires
n = 1+np.random.randint(20)
k = 1+np.random.randint(10)
## BEGIN SOLUTION
L1 = list_circ(n,k)
print(n,k,L1)
if (type(L1) != np.ndarray) or (type(L1[0]) != np.int64) or (L1.size != n):
    print("erreur")
else:
    print('OK')
## END SOLUTION
8 3 [0 1 2 0 1 2 0 1]
OK
In [4]:
# ne pas modifier
assert(check_function(list_circ,'exo51'))
validation:  exo51 
Given integers n and k, return a numpy array of length n containing 0 1 2 ... k-1 0 1 2 ... k-1 ...
    

Exercise 2: repetition¶

Soit un entier n fixé, on veut créer un tableau numpy d'entiers R contenant

1 2 2 3 3 3 4 4 4 4 ... et finalement n répétés n fois.

On rappelle que la somme des n premiers entiers vaut n(n+1)/2

Dans la cellule suivante, écrire les instructions correspondantes pour créer ce tableau en utilisant une boucle. Afficher le résultat pour vérifier

In [5]:
import numpy as np

n = 4
## BEGIN SOLUTION
R = np.zeros(n*(n+1)//2, dtype=int)
for i in range(1,n+1):
    k = i*(i+1)//2
    R[k-i:k] = i
print(R)
## END SOLUTION
[1 2 2 3 3 3 4 4 4 4]

Transformer le code précédent pour le transformer en fonction repetition.

Ecrire la fonction repetition dans la cellule suivante en changeant le nom des variables: p pour l'entier et Rep pour le tableau

Vérification

Appeler la fonction précédente pour une valeur de n (aléatoire) et mettre le résultat dans une variable R1. Affichez R1 et faire des tests pour

  1. vérifier le type de R1 (tableau numpy np.ndarray) avec type
  2. vérifier le type des éléments de R1 avec type
  3. vérifier la dimension du tableau R1

et afficher "erreur" en cas de non validation.

In [6]:
# fonction
## BEGIN SOLUTION
def repetition(p):
    Rep = np.zeros(p*(p+1)//2, dtype=int)
    for i in range(1,p+1):
        k = i*(i+1)//2
        Rep[k-i:k] = i
    return Rep
## END SOLUTION## END SOLUTION
# verification
n = 1 + np.random.randint(20)
## BEGIN SOLUTION
R1 = repetition(n)
print(R1)
if (type(R1) != np.ndarray) or (type(R1[0]) != np.int64) or (R1.size != n*(n+1)//2):
    print("erreur")
else:
    print('OK')
## END SOLUTION
[ 1  2  2  3  3  3  4  4  4  4  5  5  5  5  5  6  6  6  6  6  6  7  7  7
  7  7  7  7  8  8  8  8  8  8  8  8  9  9  9  9  9  9  9  9  9 10 10 10
 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11]
OK
In [7]:
# ne pas modifier
assert(check_function(repetition,'exo54'))
validation:  exo54 
 Given an integer n, return a numpy array containing 1 2 2 3 3 3 4 4 4 4 ... and finally n repeated n times
    

Exercise 3: dist_max¶

Soit un tableau numpy d'entiers X, on veut calculer la plus grande distance entre 2 éléments consécutifs du tableau.

Dans la cellule suivante, écrire les instructions correspondantes pour calculer cette valeur en utilisant une boucle et en stockant le résultat dans la variable dm . Afficher le résultat pour vérifier

In [8]:
import numpy as np
X = np.array([7,5,1,3])
## BEGIN SOLUTION
dm = 0
for i in range(X.size-1):
        dm = max(dm, abs(X[i+1]-X[i]))
print(dm)
## END SOLUTION
4

Transformer le code précédent pour le transformer en fonction dist_max.

Ecrire la fonction dist_max dans la cellule suivante en changeant le nom des variables: tab pour le tableau et dmax pour le résultat.

Vérification

Appeler la fonction précédente avec un tableau numpy d'entiers quelconques (utilisant randint) et mettre le résultat dans la variable dmax. Affichez dmax et faire les tests pour

  1. vérifier le type de dmax
  2. vérifier le signe de dmax

et afficher "erreur" en cas de non validation.

In [9]:
# fonction
## BEGIN SOLUTION
import numpy as np
def dist_max(tab):
    dmax = 0
    for i in range(tab.size-1):
        dmax = max(dmax, abs(tab[i+1]-tab[i]))
    return dmax
## END SOLUTION
# verification
I = np.random.randint(1,20,size=10)
## BEGIN SOLUTION
dmax = dist_max(I)
print(I,dmax)
if (type(dmax) != np.int64) or (dmax < 0):
    print("erreur")
else:
    print('OK')
## END SOLUTION
[13  2  4 10  1  1 19  3 15  8] 18
OK
In [10]:
# ne pas modifier
assert(check_function(dist_max,'exo57'))
validation:  exo57 
Given a numpy array of integers, find the largest distance between two consecutive elements.
    

Fonction 4: moy_neg¶

Soit un tableau numpy d'entiers (positifs ou négatifs) passé en argument, écrire une fonction moy_neg qui renvoie la moyenne des éléments négatifs du tableau. Retourne 0.0 si aucun élément est négatif.

Vérification

Appeler la fonction précédente avec un tableau numpy d'entiers quelconques (utiliser randint) et mettre le résultat dans la variable mneg. Affichez mneg et faire les tests pour

  1. vérifier le type de mneg
  2. vérifier le signe de mneg

et afficher "erreur" en cas de non validation.

In [11]:
# fonction
## BEGIN SOLUTION
import numpy as np
def moy_neg(tab):
    res = 0.0
    n = 0
    for val in tab:
        if val < 0 :
            res = res + val
            n = n + 1
    if n > 0 : res = res/n
    return res
## END SOLUTION
# verification
I = 5 - np.random.randint(0,10,size=20)
## BEGIN SOLUTION
mneg = moy_neg(I)
print(I,mneg)
if (type(mneg) != np.float64) or (mneg > 0):
    print("erreur")
## END SOLUTION
[ 0  2  1  5  5  0 -2  2 -4 -3 -1  0 -1  5  5  1 -2  5 -3  3] -2.2857142857142856
In [12]:
# ne pas modifier
assert(check_function(moy_neg,'exo62'))

Fonction 5: max_sum¶

Soit un tableau numpy d'entiers (positifs ou négatifs) et un nombre entier n positif (et inférieur à la dimension du tableau) passés en argument, écrire une fonction max_sum qui renvoie la valeur du maximum des sommes de n éléments consécutifs du tableau.

On pourra utiliser la fonction python sum pour calculer la somme des éléments d'un tableau.

Vérification

Appeler la fonction précédente avec un tableau numpy d'entiers quelconques (utiliser randint) et mettre le résultat dans la variable msum. Affichez msum et faire les tests pour

  1. vérifier le type de msum
  2. vérifier la valeur de msum pour n=1 (doit retourner le max du tableau)

et afficher "erreur" en cas de non validation.

In [13]:
# fonction
## BEGIN SOLUTION
import numpy as np
def max_sum(tab,n):
    res = sum(tab[:n])
    for i in range(tab.size-n+1):
        S = sum(tab[i:i+n])
        if S > res :
            res = S
    return res
## END SOLUTION
# vérification
I = 5 - np.random.randint(0,10,size=20)
n = 4
## BEGIN SOLUTION
msym = max_sum(I,n)
print(I,msym)
if (type(msym) != np.int64) or (max_sum(I,1) != max(I)):
    print("erreur")
else:
    print('OK')
## END SOLUTION
[ 0  3 -3  0 -1 -2  3  1 -1  5  0  2  3 -4  2 -2  0  5 -1  5] 10
OK
In [14]:
# ne pas modifier
assert(check_function(max_sum,'exo68'))

Fonction 6: precis¶

Ecrire une fonction precis qui renvoie la précision machine eps, i.e. le plus petit réel tel que:

(1.+ eps) # 1 mais (1.+ eps/2) == 1.

Pour cela construire une suite de valeurs de eps à partir de 1.0, qui à chaque itération divise la valeur de eps par deux jusqu'à ce que la condition précédente soit vérifiée.

Vérification

appeler la fonction précédente et mettre le résultat dans la variable eps. Affichez eps et faire les tests pour

  1. vérifier le type de eps
  2. vérifier que eps vérifie bien les conditions imposées

et afficher "erreur" en cas de non validation.

In [15]:
# fonction
## BEGIN SOLUTION
def precis():
    eps = 1.0
    while (1.+eps) != 1.0 :
        eps = eps/2.0
    return 2*eps
## END SOLUTION
# verification
## BEGIN SOLUTION
eps = precis()
print(eps)
if (type(eps) != float) or ((1+eps)==1.0) or ((1+eps/2.)!=1.0):
    print("erreur")
else:
    print('OK')
## END SOLUTION
2.220446049250313e-16
OK
In [16]:
# ne pas modifier
assert(check_function(precis,'exo80'))

Fonction 7: norme_egale¶

Soient 2 vecteurs numpy de même dimension et un petit nombre réel eps, écrire une fonction norme_egale qui teste si les 2 vecteurs ont la même longueur (norme euclidienne) avec la précision eps. Dans ce cas la fonction renvoie True et False sinon.

On pourra utiliser la fonction numpy.linalg.norm en consultant la documentation

Vérification

Appeler la fonction précédente avec deux vecteurs numpy quelconques (utiliser rand) et mettre le résultat dans la variable res. Affichez res et faire les tests pour

  1. vérifier le type de res
  2. vérifier la valeur de res dans le cas ou Y=X
  3. vérifier la valeur de res dans le cas ou Y=X+err avec err=eps*norm(X)/4

et afficher "erreur" en cas de non validation.

In [17]:
# fonction
import numpy as np
## BEGIN SOLUTION
def norme_egale(X,Y,eps):
   dist = np.abs(np.linalg.norm(X) -  np.linalg.norm(Y))
   return dist <= eps 
## END SOLUTION
# verification
X = np.random.rand(5)
Y = np.random.rand(5)
eps = 1.0e-6
## BEGIN SOLUTION
res = norme_egale(X,Y,eps)
print(X,Y,res)
err = eps*np.linalg.norm(X)/4.
if (type(res) != np.bool_) or (norme_egale(X,X, eps)==False) or (norme_egale(X,X+err,eps)==False):
    print("erreur")
else:
    print('OK')
## END SOLUTION
[0.13992236 0.30795527 0.33763643 0.98573727 0.1468721 ] [0.55124496 0.38701307 0.30575371 0.01905744 0.69639028] False
OK
In [18]:
# ne pas modifier
assert(check_function(norme_egale,'exo82'))

FIN¶