• Aucun résultat trouvé

mesuredehoule January 20, 2021

N/A
N/A
Protected

Academic year: 2022

Partager "mesuredehoule January 20, 2021"

Copied!
27
0
0

Texte intégral

(1)

mesureDeHoule

January 20, 2021

[1]: import matplotlib.pyplot as plt

1 Partie I. Stockage interne des données

[2]: import numpy as np

1.1 Q1

On ne compte pas la première ligne. Il y a 8 caractères de 1 octet chacun (=8 bits) donc 8 octets par ligne.

La fréquence est 2Hz donc on saisit deux lignes par seconde.

En 20 minutes il y a

[3]: 20*60*2# nb de lignes en 20 minutes

[3]: 2400

[4]: no=20*60*2*8#octets saisis en 20 minutes print('{} octets, {} ko'.format(no, no/1000))

19200 octets, 19.2 ko Complément

Faisons une expérience. Dans un fichier texte, on a écrit ceci [5]: #lire le contenu de donnees.txt; ce n'est pas du Python

%cat donnees.txt blabla; kjhjh; 5456 +0.4256

+0.3174 -0.0825 +0.4256

(2)

+0.3174 -0.0825

[6]: f = open('donnees.txt','rb')# ça c'est du Python l1 = f.readline()

l2 = f.readline()# la 2eme ligne

print(len(l2))# il y a bien 8 octets sur la ligne f.close()

8

[7]: 3600*434 [7]: 1562400

1.2 Q2

On fait 20 minutes de prélèvement toutes les demi-heures, donc deux enregistrements par heure, 48 par jours pendant 15 jours

[8]: nbe=48*15#nb enregistrements nbe

[8]: 720

[131]: nto=nbe*no#nombre total d'octets saisis en 15 jours nto, nto/10**9, nto/10**6

[131]: (13824000, 0.013824, 13.824)

Une campagne consomme0.014×109 octets donc moins que un Go (lequel vaut 109 octets). Donc la carte mémoire est suffisante.

1.3 Q3

On ne stocke que 7 octets (un chiffre pour 1 octet), pas 8. Donc on gagne un pour 8, un huitième de mémoire

[10]: 1/8

[10]: 0.125

On gagne donc 12.5% de 13824000 octets soit [11]: 13824000/8

[11]: 1728000.0

(3)

A peu près 2Mo de gain de place.

1.4 Q4

Les données se trouvent dans le répertoire de travail sous forme d’un fichierdonnees.txt.

Proposer une suite d’instructions permettant de créer à partir de ce fichier une liste de flottants liste_niveaux contenant les valeurs du niveau de la mer.

[12]: def recup(fich):

f=open(fich,"r")

l=f.readlines()[1:]#on ne tient pas compte de la 1ere ligne return [float(d) for d in l]

[13]: recup("donnees.txt")

[13]: [0.4256, 0.3174, -0.0825, 0.4256, 0.3174, -0.0825]

1.5 Rappels : lecture/écriture

Rappels sur les méthodes des objets d’entrée-sortie : [14]: f=open("essai.txt",'w')#écriture avec écrasement

f.write("un\n") f.write("deux\n") f.close()

f=open("essai.txt",'r')#lecture print(f.readlines())

f.close()

['un\n', 'deux\n']

[15]: f=open("essai.txt",'a')#écriture avec ajout à la fin f.write("un\n")

f.write("deux\n") f.close()

f=open("essai.txt",'r')#lecture print(f.readlines())

f.close()

['un\n', 'deux\n', 'un\n', 'deux\n']

(4)

2 Partie II. Analyse “vague par vague”

2.1 Q5

Pour le signal représenté sur la Figure 2, que valent approximativement H1 ,H2 etH3 [16]: h1=6-(-3)#

h2=7-(-2)# max_{t\in[Z1,Z2]}n(t)-min_{t\in[Z2,Z3]}n(t) h3=5-(-1.5)# max_{t\in[Z2,Z3]}n(t)-min_{t\in[Z3,Z4]}n(t) h1,h2,h3# en mètres

[16]: (9, 9, 6.5) [17]: T1=15.5-4

T2=28.5-15.5

T1,T2# en secondes [17]: (11.5, 13.0)

2.2 Q6

Proposer une fonction moyenne

[18]: #création d'un horodate aléatoire pour les tests import random as rd

liste_niveaux=[rd.random()*(-1)**rd.randint(0,1) for i in range(20)]

liste_niveaux[:5]#pour voir [18]: [-0.48582096159839905,

0.7071680584880793, -0.3314732417043347, 0.9789544984188214, -0.6101904220867811]

[19]: def moyenne(t):#V1 r=0

for e in t:

r+=e

return r/len(t) moyenne(liste_niveaux) [19]: -0.14730640773691261 [20]: def moyenne(t):#V2

return sum(t)/len(t)

(5)

[21]: moyenne([10,15,12]) [21]: 12.333333333333334

2.3 Q7

Pour calculer l’intégrale, il nous faut connaître le pas. La fréquence d’échantillonage est de 2Hz c’est à dire un pas de 0.5s.

Considérons le trapèze formé des 4 points (tk,0); (tk, f(tk); (tk+1, f(tk+1); (tk+1,0).

Son aire algébrique est la moyenne de celle des rectangles de som- mets (tk,0); (tk,max(f(tk, f(tk+1)); (tk+1,max(f(tk, f(tk+1)); (tk+1,0) et (tk,0); (tk,min(f(tk, f(tk+1)); (tk+1,min(f(tk, f(tk+1)); (tk+1,0). Elle vaut donc

(tk+1−tk)f(tk+1) +f(tk)) 2

Il y a un trapèze de moins que de points dans la liste liste_niveaux.

[22]: def integrale_precise(ln):

h,r=0.5,0

for i in range(len(ln)-1):

r+=(ln[i]+ln[i+1])/2 return h*r

[23]: l = [1, -1, -2, 2, -2, -1, 6, 4, -2, -5]

integrale_precise(l) [23]: 1.0

[24]: def integrale_precise(ln):# V2; avec un peu moins de calculs h,r=0.5,0

r = (ln[0]+ln[-1]/2)/2

for i in range(1,len(ln)-1):

r += ln[i]

return h*r [25]: integrale_precise(l) [25]: 1.625

La valeur moyenne deη sur [0, T]est définie par

m= 1 T

T

t=0

η(t)dt

(6)

[26]: def moyenne_precise(ln):

h=0.5

T=len(ln)*0.5# A priori T vaut 20 minutes soit 1200 secondes return integrale_precise(ln)/T

2.4 Q8

On a supposé qu’aucun point n’était égal à la moyenne [27]: def first(t,m):

"""retourne le premier indice tel que t[i]>m et t[i+1]<m"""

n=len(t)

for i in range(len(t)-1):

if t[i]>m and t[i+1]<m:

return i

return -1 # on n'a pas trouvé i

def ind_premier_pzd(liste_niveaux):

m=moyenne(liste_niveaux) return first(liste_niveaux,m)

[28]: first([1, -1, -2, 2, -2, -1, 6, 4, -2, -5],0) [28]: 0

[29]: first([-1, -2, 2, -2, -1, 6, 4, -2, -5],0) [29]: 2

2.5 Q9

La complexité O(1) dans le meileur cas nous interdit de retourner la liste au préalable ou de la parcourir depuis le début : on commence par la fin !

[30]: def last(t,m):#O(n) n=len(t)

for i in range(1,n):

if t[-i]<m and t[-i-1]>m:

return n-i-1 return -2

def ind_dernier_pzd(liste_niveaux):

m=moyenne_precise(liste_niveaux)#O(n) return last(t,m)

(7)

[31]: last([1, -1, -2, 2, -2, -1, 6, 4, -2, -5],0) [31]: 7

[32]: last([1, -1, -2, -2, -2, -1, 6, 4],0) [32]: 0

[33]: last([-1, -1, -2, -2, -2, -1, 6, 4],0) [33]: -2

2.6 Q10

Compléter

def construction_successeurs(liste_niveaux):

n = len(liste_niveaux) successeurs = []

m = moyenne(liste_niveaux) for i in range(n-1):

if # À compléter

# À compléter return successeurs

[34]: def construction_successeurs(ln) : n=len ( ln )

successeurs =[]

m=moyenne ( ln )

for i in range ( n -1):

if ln[i]>m and ln[i+1]<m:

successeurs.append(i+1) return successeurs

[35]: construction_successeurs([1, -1, -2, 2, -2, -1, 6, 4, -2, -5]) [35]: [1, 4, 8]

[36]: moyenne([1, -1, -2, 2, -2, -1, 6, 4, -2, -5]) [36]: 0.0

(8)

2.7 Q11

[41]: def decompose_vague(ln):

les_succ=construction_successeurs(ln) r=[]

for i in range(len(les_succ)-1):

r.append(ln[les_succ[i]: les_succ[i+1]]) return r

[42]: ln =[1, -1, -2, 2, -2, -1, 6, 4, -2, -5]

decompose_vague(ln)

[42]: [[-1, -2, 2], [-2, -1, 6, 4]]

[43]: p=ind_premier_pzd(ln) ln[:p+1]

[43]: [1]

2.8 Q12

La principale difficulté est ici de respecter la définition de hauteur de vague : c’est la différence entre la hauteur maximum de la vague précédente et le minimum de la suivante.

On ne compare donc pas les maximums et minimums d’une même vague.

La hauteur de la dernière vague n’est pas définie par le sujet : on ne la calcule pas. Mais celle de la première vague est évaluée.

[117]: def proprietes(ln):

v=decompose_vague(ln)

H1=max(ln[:v[0]])-min(v[0])#1ere hauteur traitée à part T1=len(v[0])*0.5#1ere période

r=[[H1,T1]]

for i in range(len(v)-1):

v1,v2=v[i],v[i+1]#2 vagues successives

H=max(v1)-min(v2)#hauteur de la vague selon def page 2 T=0.5*len(v2)#période de la vague selon def page 2 r.append([H,T])

#noter qu'on n'a pas la hauteur de la dernière vague4 return r

[118]: ln =[1, -1, -2, 2, -2, -1, 6, 4, -2, -5]

proprietes(ln)

(9)

[118]: [[3, 1.5], [4, 2.0]]

3 III Contrôle des données

3.1 Q13

[119]: def hm(liste_niveaux):

prop = proprietes(liste_niveaux) # Détermination des propriétés des vagues return max([p[0] for p in prop])

[120]: hm(ln) [120]: 4

4 Q14

La bouclewhile fait le partitionnement. En sortie de boucle, les éléments plus petits que le pivot sont à gauche, les plus grands, à droite.

Dans cette version du tri rapide, le partitionnement gère deux indicesi, j. L’indiceiprogresse vers la droite,jvers la gauche. L’invariant maintenu dans la boucle principale est que à gauche deiil n’y ait que des éléments plus petits que le pivot, à droite dej que des éléments plus grands. Lorsqu’on a identifié deux tels éléments, on échange leurs places, ce qui fait que le nombre d’éléments qui ne sont pas à leur place diminue à chaque fois (et cela assure la terminaison).

Si i > j, le pivot n’a sur sa gauche que des éléments plus petits que lui et sur sa droite que des éléments plus grands. On peut donc sortir de la boucle principale : la position du pivot est trouvée.

Il reste à appliquer le tri rapide au sous-tableau à gauche de la première valeur inférieure au pivot et symétriquement à droite s’ils existent (d’où les tests g<jeti<d).

Le pivot est pris égal au premier élément de la portion de liste étudiée, c’est la seule chose qu’il fallait compléter. Au premier appel, i= 0 etj=|l| −1.

Enfin, le code proposé est une procédure qui trie une partie de la liste, celle qui est située en tre les indicesg etd.

[121]: from random import randint [122]: def triRapide ( l , g , d ) :

p=l[randint(g,d)][0]# le pivot, toute valeur entre les cases g et d i=g

j=d

while True :

while i<=d and l[ i ] [ 0 ] < p:

#chercher le 1er indice (en partant de la gauche) d'une hauteur >=p

(10)

i=i +1

while j>=g and l [ j ] [ 0 ] > p :

#chercher le premier indice (en partant de la droite) d'une hauteur␣

,<=p

j=j-1 if i >j :

"""

à gauche de j : les points plus petits que le pivot à droite de i : ceux plus grands

entre i et j : les points égaux au pivot """

break if i <j :

#à gauche, on met les points plus petits que p

#à droite, les plus grands l[ i ] ,l[ j ]= l[ j ] , l[ i ] i=i +1

j=j -1

print(l,i-1,j+1) if g<j :

triRapide ( l , g , j ) if i <d :

triRapide ( l , i , d) [123]: l=[[10,1],[4,5],[6,8],[12,11],\

[3,9],[1,8],[10,5],[15,5],[9,8],[34,0]]

print(l)

triRapide(l,0,len(l)-1) print(l)

[[10, 1], [4, 5], [6, 8], [12, 11], [3, 9], [1, 8], [10, 5], [15, 5], [9, 8], [34, 0]]

[[9, 8], [4, 5], [6, 8], [12, 11], [3, 9], [1, 8], [10, 5], [15, 5], [10, 1], [34, 0]] 0 8

[[9, 8], [4, 5], [6, 8], [10, 5], [3, 9], [1, 8], [12, 11], [15, 5], [10, 1], [34, 0]] 3 6

[[1, 8], [4, 5], [6, 8], [10, 5], [3, 9], [9, 8], [12, 11], [15, 5], [10, 1], [34, 0]] 0 5

[[1, 8], [4, 5], [6, 8], [9, 8], [3, 9], [10, 5], [12, 11], [15, 5], [10, 1], [34, 0]] 3 5

[[1, 8], [3, 9], [6, 8], [9, 8], [4, 5], [10, 5], [12, 11], [15, 5], [10, 1], [34, 0]] 1 4

[[1, 8], [3, 9], [4, 5], [9, 8], [6, 8], [10, 5], [12, 11], [15, 5], [10, 1], [34, 0]] 2 4

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [12, 11], [15, 5], [10, 1], [34, 0]] 3 4

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [12, 11], [15, 5], [10, 1], [34, 0]] 9 9

(11)

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [12, 11], [10, 1], [15, 5], [34, 0]] 7 8

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [10, 1], [12, 11], [15, 5], [34, 0]] 6 7

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [10, 1], [12, 11], [15, 5], [34, 0]]

[124]: sum((i+1 for i in range(3))) [124]: 6

5 Q 15

Voir après la définition de triInsertion. On insère un test en début de fonction qui calcule la différence entre detg. Si celle-ci est plus petite que 15, on appelle le tri par Insertion.

6 Q16

Rappel du sujet

Compléter :

def triInsertion(liste,g,d):

for i in range(g+1,d+1):

j = i-1

tmp = liste[i]

while # À compléter

liste[j+1] = tmp

Dans la boucle while, on décale toutes les cases d’un cran vers la droite. Tout se passe comme si on maintenait un ‘trou’ décalé vers la gauche pendant la boucle whilepuis bouché en sortie de boucle avec la dernière instructionliste[j+1] = tmp.

[125]: def triInsertion(l,g,d):# version donnée par le sujet

#tri la liste entre les indices g,d inclus

print("entree TriI :{},{},{}".format(l[g:d+1],g,d))# pour les tests for i in range(g+1,d+1):# donné par le sujet

j=i-1#donné par le sujet tmp=l[i]# donné par le sujet

while l[j][0]>tmp[0] and j>=g: #complété à partir d'ici l[j+1]=l[j]

j=j-1

(12)

l[j+1]=tmp

print("Sortie TriI :{},{},{}".format(l[g:d+1],g,d))# pour les tests [126]: l=[[10,0],[5,0],[7,0],[2,0],[6,0],[0,0]]

print(l)

triInsertion(l,1,4) l

[[10, 0], [5, 0], [7, 0], [2, 0], [6, 0], [0, 0]]

entree TriI :[[5, 0], [7, 0], [2, 0], [6, 0]],1,4 Sortie TriI :[[2, 0], [5, 0], [6, 0], [7, 0]],1,4 [126]: [[10, 0], [2, 0], [5, 0], [6, 0], [7, 0], [0, 0]]

Ce code de Tri par insertion est certes efficace (une seule opération d’écriture dans la boucle interne contre deux dans le code de mon cours) mais la lignel[j+1]=tmp a troublé certains d’entre vous.

Pour coller plus à mon cours, on pouvait écrire des échanges pendant la boucle et supprimer la dernière instruction :

[54]: def triInsertion(l,g,d):# version plus proche du cours

#tri la liste entre les indices g,d inclus

print("entree TriI :{},{},{}".format(l[g:d+1],g,d)) for i in range(g+1,d+1):# donné par le sujet

j=i-1#donné par le sujet tmp=l[i]# donné par le sujet

while l[j][0]>tmp[0] and j>=g: #complété à partir d'ici l[j+1],l[j]=l[j],l[j+1]

j=j-1

print("Sortie TriI :{},{},{}".format(l[g:d+1],g,d)) [55]: l=[[10,0],[5,0],[7,0],[2,0],[6,0],[0,0]]

print(l)

triInsertion(l,1,4) l

[[10, 0], [5, 0], [7, 0], [2, 0], [6, 0], [0, 0]]

entree TriI :[[5, 0], [7, 0], [2, 0], [6, 0]],1,4 Sortie TriI :[[2, 0], [5, 0], [6, 0], [7, 0]],1,4 [55]: [[10, 0], [2, 0], [5, 0], [6, 0], [7, 0], [0, 0]]

7 Q 15 (retour)

Pour mes tests, je choisis 3 et non 15 (valeur indiquée par le sujet) comme seuil d’appel : c’est plus facile à tester !

(13)

On observe que dès que la portion d eliste à trier est plus petite que 3, c’est effectivement le tri par insertion qui termine le travail amorcé par le tri rapide.

[56]: def triRapide ( l , g , d, e=3 ) : if d-g<e:

"""

on serait tenté de mettre d-g<=e mais ce ce serait oublier qu'alors on traiterait les indices g,g+1,..,g+e

c'est à dire (e+1) indices

"""

triInsertion(l,g,d) else:

print("entree TriR :{},{},{}".format(l,g,d)) i,j=g,d

p=l[randint(g,d)][0]

while True :

while i<=d and l[ i ] [ 0 ] < p:

#chercher le 1er indice d'une hauteur d-g>=p i=i +1

while j>=g and l [ j ] [ 0 ] > p :

#chercher le dernier indice d'une hauteur <=p j=j-1

if i >j :

#le pivot devrait être entre i et j break

if i <j :

#à gauche, on met les points plus petits que p

#à droite, les plus grands l[ i ] ,l[ j ]= l[ j ] , l[ i ] i=i +1

j=j -1 if g<j :

triRapide ( l , g , j ) if i <d :

triRapide ( l , i , d) [57]: l=[[10,1],[4,5],[6,8],[12,11],\

[3,9],[1,8],[10,5],[15,5],[9,8],[34,0]]

print(l)

triRapide(l,0,len(l)-1) print(l)

[[10, 1], [4, 5], [6, 8], [12, 11], [3, 9], [1, 8], [10, 5], [15, 5], [9, 8], [34, 0]]

entree TriR :[[10, 1], [4, 5], [6, 8], [12, 11], [3, 9], [1, 8], [10, 5], [15, 5], [9, 8], [34, 0]],0,9

entree TriR :[[9, 8], [4, 5], [6, 8], [10, 5], [3, 9], [1, 8], [12, 11], [15, 5], [10, 1], [34, 0]],0,5

(14)

entree TriR :[[1, 8], [4, 5], [6, 8], [3, 9], [10, 5], [9, 8], [12, 11], [15, 5], [10, 1], [34, 0]],0,3

entree TriI :[[4, 5], [6, 8], [3, 9]],1,3 Sortie TriI :[[3, 9], [4, 5], [6, 8]],1,3 entree TriI :[[10, 5], [9, 8]],4,5

Sortie TriI :[[9, 8], [10, 5]],4,5

entree TriR :[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [12, 11], [15, 5], [10, 1], [34, 0]],6,9

entree TriI :[[15, 5], [12, 11], [34, 0]],7,9 Sortie TriI :[[12, 11], [15, 5], [34, 0]],7,9

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [10, 1], [12, 11], [15, 5], [34, 0]]

[58]: # seconde version

def triRapide ( l , g , d, e=3 ) :

print("entree TriR :{},{},{}".format(l,g,d)) i,j=g,d

p=l[randint(g,d)][0]

while True :

while i<=d and l[ i ] [ 0 ] < p:

#chercher le 1er indice d'une hauteur d-g>=p i=i +1

while j>=g and l [ j ] [ 0 ] > p :

#chercher le dernier indice d'une hauteur <=p j=j-1

if i >j :

#le pivot devrait être entre i et j break

if i <j :

#à gauche, on met les points plus petits que p

#à droite, les plus grands l[ i ] ,l[ j ]= l[ j ] , l[ i ] i=i +1

j=j -1 if g<j :

if j-g<15:

triInsertion(l,g,j) else:

triRapide ( l , g , j ) if i <d :

if d-i<15:

triInsertion(l,i,d) else:

triRapide ( l , i , d) [59]: l=[[10,1],[4,5],[6,8],[12,11],\

[3,9],[1,8],[10,5],[15,5],[9,8],[34,0]]

(15)

print(l)

triRapide(l,0,len(l)-1) print(l)

[[10, 1], [4, 5], [6, 8], [12, 11], [3, 9], [1, 8], [10, 5], [15, 5], [9, 8], [34, 0]]

entree TriR :[[10, 1], [4, 5], [6, 8], [12, 11], [3, 9], [1, 8], [10, 5], [15, 5], [9, 8], [34, 0]],0,9

entree TriI :[[9, 8], [4, 5], [6, 8], [10, 5], [3, 9], [1, 8]],0,5 Sortie TriI :[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5]],0,5 entree TriI :[[12, 11], [15, 5], [10, 1], [34, 0]],6,9

Sortie TriI :[[10, 1], [12, 11], [15, 5], [34, 0]],6,9

[[1, 8], [3, 9], [4, 5], [6, 8], [9, 8], [10, 5], [10, 1], [12, 11], [15, 5], [34, 0]]

8 Q17

La variance est la moyenne des carrés moins le carré de la moyenne,selon KH.

[60]: def kh(t):

"""variance par Koenig Huyghens"""

m2=moyenne([e**2 for e in t]) m=moyenne(t)

return m2-m**2 def ecartType(t):

return kh(t)**0.5 [61]: t=[1,2,3]

m2=moyenne([e**2 for e in t]) m=moyenne(t)

kh(t),m2,m

[61]: (0.666666666666667, 4.666666666666667, 2.0)

8.1 Q17

Dans l’algorithme proposé,

def skewness(liste_hauteurs):

n = len(liste_hauteurs)

et3 = (ecartType(liste_hauteurs))**3 S = 0

for i in range(n):

S += (liste_hauteurs[i] - moyenne(liste_hauteurs))**3

(16)

S = n/(n-1)/(n-2) * S/et3 return S

pour une liste de longueur n, le calcul de la moyenne (en O(n)) se fait à chaque passage dans la boucle, donc en O(n2).

Le calculer une fois pour toute avant la boucle, ramène le calcul à unO(n) [62]: #comprendre les divisions successives :

6/2/3

[62]: 1.0

[63]: def skewness(lh):

n=len(lh)

e3=(ecartType(lh))**3 m=moyenne(lh)

S=0

for i in range(n):

S+=(lh[i]-m)**3 S=n/(n-1)/(n-2)*S/e3 return S

8.2 Q18

Non, pas de différence de type de complexité pour Skewness et Kurtosis : elles sont toutes les deux en O(n).

En effet, la seule boucle dans leur code est celle qu’il faut pour évaluer la somme :

• une différence suivi d’une élévation d’un nombre au cube pour Skewness pour chaque passage dans la boucle : donc O(1)par passage

• une différence suivi d’une élévation d’un nombre à la puissance 4 pour Kurtosis pour chaque passage dans la boucle : doncO(1)par passage

Les autres opérations(hors boucles) dans les deux fonctions sont enO(1)

9 Partie IV BDD

IL FAUT EXPLIQUER LES REQUÊTES LONGUES !!

[64]: import sqlite3

conn = sqlite3.connect('houle.db') [65]: #curseur

c = conn.cursor()

(17)

9.1 Construction d’une base pour les tests [66]: rq="""

DROP TABLE if EXISTS Bouee;

CREATE TABLE IF NOT EXISTS Bouee (idBouee INT PRIMARY KEY,

nomSite TEXT NOT NULL, localisation TEXT NOT NULL, typeCapteur TEXT NOT NULL, frequence REAL NOT NULL );

"""

# Create table c.executescript(rq)

# Insert a row of data rq="""

INSERT INTO Bouee VALUES (831,'Porquerolles','Mediterranee','DTWND',2.00)

"""

c.execute(rq) rq="""

INSERT INTO Bouee VALUES (291,'Les pierres noires',"Mer d\'Iroise",'DTWD',1.28)

"""

c.execute(rq)

rq="""

INSERT INTO Bouee VALUES (456,'Saint-Pierre',"Ocean Indien",'DTND',2.35)

"""

c.execute(rq) conn.commit()

[67]: rq="select * from Bouee"

c.execute(rq) t=c.fetchall() for e in t:

print(e)

(831, 'Porquerolles', 'Mediterranee', 'DTWND', 2.0)

(291, 'Les pierres noires', "Mer d'Iroise", 'DTWD', 1.28) (456, 'Saint-Pierre', 'Ocean Indien', 'DTND', 2.35)

[68]: rq="""

DROP TABLE if EXISTS Campagne;

CREATE TABLE IF NOT EXISTS Campagne

(18)

(idCampagne INT PRIMARY KEY, idBouee INT NOT NULL,

debutCampagne TEXT NOT NULL, finCampagne TEXT NOT NULL,

FOREIGN KEY(idBouee) REFERENCES Bouee(idBouee) );

"""

# Create table c.executescript(rq)

# Insert a row of data rq="""

INSERT INTO Campagne VALUES (08301,831,'2010-01-01','2010-01-15')

"""

c.execute(rq) rq="""

INSERT INTO Campagne VALUES (02911,291,'2005-10-15','2005-10-18')

"""

c.execute(rq) conn.commit()

[100]: #une fonction d'affichage des résultats de requête def affiche(req):

c.execute(req) t=c.fetchall() for e in t:

print(e)

[101]: rq="select * from Campagne"

affiche(rq)

(8301, 831, '2010-01-01', '2010-01-15') (2911, 291, '2005-10-15', '2005-10-18') [102]: rq="""

DROP TABLE if EXISTS Tempete;

CREATE TABLE IF NOT EXISTS Tempete (idCampagne INT PRIMARY KEY,

idBouee INT NOT NULL,

debutTempete TEXT NOT NULL, finTempete TEXT NOT NULL, Hmax REAL NOT NULL,

FOREIGN KEY(idBouee) REFERENCES Bouee(idBouee) );

"""

(19)

# Create table c.executescript(rq)

# Insert a row of data rq="""

INSERT INTO Tempete VALUES (083010,831,'2010-01-07','2010-01-09',5.3)

"""

c.execute(rq) rq="""

INSERT INTO Tempete VALUES (029012,291,'2005-10-16','2005-10-18',8.5)

"""

c.execute(rq) rq="""

INSERT INTO Tempete VALUES (02989,831,'2010-09-16','2010-09-17',10.5)

"""

c.execute(rq) conn.commit()

[103]: rq="select * from Tempete"

affiche(rq)

(83010, 831, '2010-01-07', '2010-01-09', 5.3) (29012, 291, '2005-10-16', '2005-10-18', 8.5) (2989, 831, '2010-09-16', '2010-09-17', 10.5)

9.2 Q19

a) Quels sont le numéro d’identification et le nom de site des bouées localisées en Méditerrannée ?

SELECT idBouee, nomSite FROM Bouee WHERE localisation='Mediterranee'

[104]: #test Python/SQL

rq="""SELECT idBouee, nomSite FROM Bouee WHERE localisation='Mediterranee'

"""

affiche(rq)

(831, 'Porquerolles')

b) Quel est le numéro d’identification des bouées où il n’y a pas eu de tempêtes ? SELECT idBouee FROM Bouee WHERE idBouee

NOT IN (select idBouee from Tempete)

(20)

ou (valable en SQLite) : SELECT idBouee FROM Bouee EXCEPT

SELECT idBouee FROM Tempete [105]: #test Python/SQL

rq="""SELECT idBouee FROM Bouee WHERE idBouee NOT IN (select idBouee from Tempete)"""

affiche(rq) (456,)

[106]: #test Python/SQL

rq="""SELECT idBouee FROM Bouee EXCEPT

SELECT idBouee FROM Tempete"""

affiche(rq) (456,)

c) Pour chaque nom de site, quelle est la hauteur maximale enregistrée lors d’une tempête ?

Les motspour chaque site doivent faire penser à une aggrégation (Group BY) On fait une jointure naturelle (SQLite)

SELECT nomSite, MAX(Hmax) FROM Bouee NATURAL JOIN Tempete

GROUP BY nomSite

ou bien, si on ne dispose pas du NATURAL JOIN(MySQL):

SELECT nomSite, MAX(Hmax) FROM Bouee AS B JOIN Tempete AS T

ON T.idBouee = B.idBouee GROUP BY nomSite

[107]: #test Python/SQL

rq="""SELECT nomSite, MAX(Hmax) FROM BOUEE NATURAL JOIN Tempete

GROUP BY nomSite

"""

affiche(rq)

('Les pierres noires', 8.5) ('Porquerolles', 10.5) [109]: #test Python/SQL

rq="""SELECT nomSite, MAX(Hmax) FROM Bouee AS B JOIN Tempete AS T

(21)

ON T.idBouee = B.idBouee GROUP BY nomSite

"""

affiche(rq)

('Les pierres noires', 8.5) ('Porquerolles', 10.5)

d) déterminer les sites qui ont subi au moins deux tempêtes.

Il s’agit de compter les tempêtes PAR (doncGROUP BY) nom de site SELECT nomSite from Bouee

NATURAL JOIN Tempete GROUP BY idBouee HAVING COUNT(*)>1

LeNATURAL JOINenSQLITEme permet d’éviter d’écrire le critère de jointure suridBoueepuisqu’il est … naturel !

[110]: #test Python/SQL

rq="""SELECT nomSite from Bouee NATURAL JOIN Tempete

GROUP BY idBouee HAVING COUNT(*)>1

"""

affiche(rq) ('Porquerolles',)

e) Donner l’identiant et la durée de la campagne de mesure la plus courte [96]: #test Python/SQL

rq = """SELECT julianday('2010-01-15')-julianday('2009-12-30')"""

affiche (rq) (16.0,)

De façon inélégante, on calcule la différence entre la date de fin et de début et on ne sélectionne que les lignes dont cette différence est la plus petite :

SELECT idCampagne, julianday(finCampagne)-julianday(debutCampagne) AS D FROM Campagne

WHERE D = (SELECT MIN(julianday(finCampagne)-julianday(debutCampagne)) FROM Campagne) De façon plus concise, en utilisant finement la syntaxe SQL :

SELECT idCampagne, MIN(julianday(finCampagne)-julianday(debutCampagne)) FROM Campagne

[80]: #test Python/SQL rq = """

(22)

SELECT idCampagne, MIN(julianday(finCampagne)-julianday(debutCampagne)) FROM Campagne

"""

affiche(rq) (2911, 3.0) [81]: #test Python/SQL

rq = """

SELECT idCampagne, julianday(finCampagne)-julianday(debutCampagne) AS D FROM Campagne

WHERE D = (SELECT MIN(julianday(finCampagne)-julianday(debutCampagne)) FROM␣

,Campagne)

"""

affiche(rq) (2911, 3.0)

Dernière version qui ne tient pas compte du fait que, peut-être, il y a plusieurs campagnes de durées minimales :

[82]: #test Python/SQL rq = """

SELECT idCampagne, MIN(julianday(finCampagne)-julianday(debutCampagne)) AS D FROM Campagne GROUP BY idCampagne

ORDER BY D DESC LIMIT 1

"""

affiche(rq) (8301, 14.0)

10 Q20

Pour calculer une TFD de n éléments, on évalue deux TFD (P et I) de N/2 éléments. Puis on recombine les deux listes obtenues (listeP contenant lesPk, liste I contenant lesIk) pour calculer les N éléments de X.

Comme il faut :

• constituer les moitiés de listes contenant les éléments pairs et impairs,

• faire un nombre fixe d’opérations pour chaque indice entre 0 et N−1 pour constituerX, PosonsN = 2k. La complexité est majorée par un multiple de la suite(CN)définie par la récurrence CN = 2CN/2+N (déjà étudiée pour le tri fusion). Elle est enO(Nlog2N)comme vu dans le cours pour le tri fusion. Et ça suffit comme preuve.

(23)

Mais si on ne s’en souvient plus, alors calculons :

CN = 2CN/2+N = 2CN/2+ 1N

= 2(2CN/4+N/2) +N

= 22CN/22+ 2N

= . . .

= 2kC1+kN

= C1N +Nlog2N =O(Nlog2N)

11 Q21

En python, le nombre complexe de carré 1 usuellement notéi en mathématiques, est noté1j.

[83]: 1j**2, np.exp(2*1j*np.pi/3)

[83]: ((-1+0j), (-0.4999999999999998+0.8660254037844387j)) [84]: from numpy import pi, exp, zeros, sin, cos, linspace [85]: import numpy as np

[86]: def tfd(x):# V1 avec tableaux numpy N=len(x)

if N==1:

return x

pairs=x[::2]#les indices pairs impairs=x[1::2]#les indices impairs

X=zeros(N,dtype=complex)# le tableau résultat w, wk = exp(-2*pi*1j/N), 1 # omega, omega^0 P=tfd(pairs)#les p_k

I=tfd(impairs)#les i_k for k in range(N//2):

X[k]=P[k]+wk*I[k]

X[k+N//2]=P[k]-wk*I[k]

wk=wk*w # w**k return X

[87]: def tfd(x):# V2 avec des listes N=len(x)

if N==1:

return x

pairs=[x[i] for i in range(N) if i%2==0]#les indices pairs impairs=[x[i] for i in range(N) if i%2==1]#les indices impairs X=[0]*N

w,wk=exp(-2*pi*1j/N),1 P=tfd(pairs)#les p_k I=tfd(impairs)#les i_k

(24)

for k in range(N//2):

X[k]=P[k]+wk*I[k]

X[k+N//2]=P[k]-wk*I[k]

wk=wk*w return X [88]: 1j**2

[88]: (-1+0j)

[89]: f1,f2,f3=10,30,100

t=linspace(0,1,2**10)#longueur : puissance de de deux s1,s2,s3=sin(2*pi*f1*t),3*cos(2*pi*f2*t),-5*sin(2*pi*f3*t) x=s1+s2+s3

X=tfd(x) X[:6]

[89]: [3.0000000000001084,

(3.0034727638307794-0.04328773018535386j), (3.013973751095296-0.09277602840312374j), (3.0317652365262227-0.15604349691598984j), (3.0573401773777173-0.24411287163028234j), (3.0915459771711546-0.3755521335346603j)]

[90]: fig,ax=plt.subplots() plt.plot(t,x)

plt.xlabel("temps en seconde") plt.ylabel("signal")

plt.show()

(25)

[91]: X[-10:-5]

[91]: [(19.052426335646032+510.8365837251951j), (3.411819858233947+4.160726381048761j), (3.2726108834669594+1.7426157471852197j), (3.1934827939724304+0.9596729320971129j), (3.1358950070238882+0.5864043533696062j)]

[92]: np.abs(X[:6])

[92]: array([3. , 3.00378469, 3.01540133, 3.03577832, 3.06707027, 3.11427294])

On calcule le module de chaque élément du tableau retourné par TFD. On trace la courbe avec en abscisse, les indices des cases de la TFD, et en ordonné les modules calculés.

Les indices des cases correspondent à des fréquences. En effet, on a pris210 temps entre 0 et 1.

[93]: plt.plot(np.abs(X[:len(x)//2])) plt.xlabel("fréquneces en Hz") plt.ylabel("tfd")

plt.xlim(0,150) plt.show()

(26)

12 Tests Réponses étudiants

[116]: req = """SELECT localisation, Bouee.idBouee FROM Tempete, Bouee WHERE Bouee.idBouee = Tempete.idBouee

EXCEPT

SELECT DISTINCT localisation, Bouee.idBouee FROM Tempete, Bouee WHERE Bouee.idBouee = Tempete.idBouee

"""

affiche(req) [127]: 48*19200

[127]: 921600

[129]: #test Python/SQL

rq="""SELECT idBouee FROM Bouee NOT IN Tempete"""

affiche(rq)

,---

(27)

OperationalError Traceback (most recent call␣

,last)

<ipython-input-129-fb904259f3c8> in <module>

2 rq="""SELECT idBouee FROM Bouee 3 NOT IN Tempete"""

----> 4 affiche(rq)

<ipython-input-100-d8d41e949e5a> in affiche(req)

1 #une fonction d'affichage des résultats de requête 2 def affiche(req):

----> 3 c.execute(req) 4 t=c.fetchall() 5 for e in t:

OperationalError: near "IN": syntax error

[133]: 15*24 [133]: 360

[ ]:

Références

Documents relatifs

[r]

*Source : sondage Ifop réalisé en mai 2018 pour l’Agence française pour la

Pour éviter toute ambiguïté, nous allons supposer ici que nous ne représenterons jamais un nombre réel par une re- présentation base 10 qui se terminerait par une séquence infinie

Laisser chercher et émettre des hypothèses &gt;&gt;&gt; Jacques se cache Hypothèses de votre enfant:?. Page 18: Puis lire le texte à

Que la fête continue Debout devant le zinc Sur le coup de dix heures Un grand plombier zingueur.. Habillé en dimanche et pourtant c'est lundi Chante pour lui

8 Dans chaque phrase, souligne en rouge les verbes conjugués au passé composé et en vert ceux conjugués au plus-que-parfait.. Elles étaient déjà parties quand nous sommes

8 Dans chaque phrase, souligne en rouge les verbes conjugués au passé composé et en vert ceux conjugués au plus-que-parfait.. Elles étaient déjà parties quand nous sommes

Ainsi, les sols profonds et fertiles du Plateau suisse conviennent tout particulièrement à la produc- tion de denrées alimentaires ; toutefois, même si cette fonction doit