Valid XHTML     Valid CSS2    

Listing du fichier td2.php

 

00001     <?php
00002     
# # (gH) -_- td2.php ; TimeStamp (unix) : 24 Juin 2018 vers 20:37
00003     
error_reporting(E_ALL | E_NOTICE | E_STRICT ) ;
00004     
header
('Content-Type "text/html; charset=iso-8859-1"') ;
00005     
ini_set
( 'default_charset', 'ISO-8859-1' );
00006     include(
"decra-inc.php") ;
00007     
00008     
$numSerie
= 2 ;
00009     
debutTDi
($numSerie,"Structuration, instructions vectorielles, boucles et optimisation") ;
00010     
ghAtAngers() ;
00011     
00012     
$R
= ghRouge("R") ;
00013     
$XML
= ghRouge("XML") ;
00014     
$Awk
= ghRouge("AWK") ;
00015     
$Php
= ghVert("PHP") ;
00016     
$Python
= ghVert("Python") ;
00017     
$APL
= ghBleu("APL") ;
00018     
00019     
## -------------------------------------------------------------------------------------------
00020     
00021     
sdl
(3) ; echo cmt(' pour afficher toutes les solutions : td2.php?solutions=1') ; sdl(3) ;
00022     
00023     
## -------------------------------------------------------------------------------------------
00024     
00025     
p
("texte") ;
00026     echo
"" ;
00027     
finp() ;
00028     
debutSection() ;
00029     
00030     
$tableauDesRubriques = array() ;
00031     
$idr
= 0 ;
00032     
$idr
++; $tableauDesRubriques[$idr] = "Structuration dans le développement Web" ;
00033     
$idr
++; $tableauDesRubriques[$idr] = "Instructions vectorielles et fonctionnelles (1)" ;
00034     
$idr
++; $tableauDesRubriques[$idr] = "Instructions vectorielles et fonctionnelles (2)" ;
00035     
$idr
++; $tableauDesRubriques[$idr] = "Boucles et optimisation (1)" ;
00036     
$idr
++; $tableauDesRubriques[$idr] = "Boucles et optimisation (2)" ;
00037     
$idr
++; $tableauDesRubriques[$idr] = "Optimisation dans le développement Web" ;
00038     
$tdmCRLM
= new tdm($tableauDesRubriques) ;
00039     
$tdmCRLM
->titre() ;
00040     
$tdmCRLM
->menu("oui","oui","nou") ;
00041     
00042     
direAfficherSolutionsTD
($numSerie) ;
00043     
00044     
finSection() ;
00045     
00046     
$numExo
= 0 ;
00047     
00048     
## -------------------------------------------------------------------------------------------
00049     
00050     
$tdmCRLM
->afficheRubrique("oui") ; $numExo++ ; # Structuration dans le développement Web
00051     
00052     ## -------------------------------------------------------------------------------------------
00053     
00054     
blockquote
() ; # td
00055     
00056     
blockquote
() ; # énoncé
00057     
00058     
p
("texte") ;
00059     echo
" Comment fait-on pour structurer une page Web ou un site Web en PHP&nbsp;?" ;
00060     echo
" Comment fait-on pour structurer un programme en général&nbsp;?" ;
00061     
finp() ;
00062     
00063     
p
("texte") ;
00064     echo
" Faut-il passer à des sites Web non écrits en PHP&nbsp;?" ;
00065     echo
" Que signifie le terme "
.b("full stack")."&nbsp;?" ;
00066     
finp() ;
00067     
00068     
finblockquote
() ; # énoncé
00069     
00070     
solutionTD
($numExo,$numSerie) ;
00071     
00072     
p
("texte") ;
00073     echo
" Il n'y a pas de solution générale à la structuration, que ce soit " ;
00074     echo
" une page Web, un site Web ou un programme en général, " ;
00075     echo
" m&ecirc;me si la plupart des langages de programmation fournissent des moyens d'inclure des " ;
00076     echo
" fichiers. Rien n'indique en effet comment découper le code ou quelles fonctions mettre " ;
00077     echo
" dans quels fichiers. " ;
00078     
finp() ;
00079     
00080     
p
("texte") ;
00081     echo
" Structurer une page Web consiste en général à "
.b("externaliser")." le code CSS et le code Javascript, " ;
00082     echo
" et sans à doute définir des sous-programmes d'affichage. En fonction de l'importance de la page, " ;
00083     echo
" on viendra donc inclure ou plusieurs fichiers PHP, on utilisera des bibliothèques Javascript " ;
00084     echo
" pour le "
.href("https://en.wikipedia.org/wiki/Front_and_back_ends","front end") ;
00085     
$url
= "https://www.alticreation.com/difference-developpeur-front-end-et-developpeur-back-end/" ;
00086     echo
" et le "
.href($url,"back end")."." ;
00087     
finp() ;
00088     
00089     
p
("texte") ;
00090     echo
" Comment structurer un site page Web est un problème compliqué. " ;
00091     echo
" La tendance actuelle (2018) consiste plut&ocirc;t, pour un blog ou un site de moyenne importance, " ;
00092     echo
" à passer par un générateur de sites " ;
00093     echo
" nommé dans ce contexte " ;
00094     echo
href
("https://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_contenu","CMS") ;
00095     echo
" comme par exemple " ;
00096     echo
href
("https://fr.wikipedia.org/wiki/WordPress","WordPress").". " ;
00097     echo
" Pour des sites plus complets, ou si on préfère plus de controle sur le site, il est conseillé " ;
00098     echo
" de passer par un framework de développement comme " ;
00099     echo
href
("https://fr.wikipedia.org/wiki/Laravel","Laravel").", ";
00100     echo
href
("https://fr.wikipedia.org/wiki/CakePHP","CakePHP").", ";
00101     echo
href
("https://fr.wikipedia.org/wiki/Symfony","Symfony").", ";
00102     echo
href
("https://fr.wikipedia.org/wiki/CodeIgniter","CodeIgniter")." ou ";
00103     echo
href
("https://fr.wikipedia.org/wiki/Joomla!","Joomla").". ";
00104     echo
" La plupart des sites ainsi générés sont alors structurés selon une architecture proche de " ;
00105     echo
href
("https://fr.wikipedia.org/wiki/Mod%C3%A8le-vue-contr%C3%B4leur","MVC") ;
00106     echo
" plut&ocirc;t que d'une architecture " ;
00107     echo
href
("https://fr.wikipedia.org/wiki/Architecture_trois_tiers","trois tiers")."." ;
00108     
finp() ;
00109     
00110     
p
("texte") ;
00111     echo
" La question de savoir s'il faut développer en PHP, en Java ou autre langage n'est pas un problème simple. " ;
00112     echo
" La popularité de " ;
00113     echo
href
("https://fr.wikipedia.org/wiki/Django_(framework)","Django").", " ;
00114     echo
href
("https://fr.wikipedia.org/wiki/Ruby_on_Rails","Ruby on Rails")." et " ;
00115     echo
href
("https://fr.wikipedia.org/wiki/Node.js","NodeJs") ;
00116     echo
" montre que PHP et Java ne sont pas les seuls langages possibles pour développer des sites Web. " ;
00117     echo
" Les langages utilisés, respectivement Python, Ruby et Javascript, " ;
00118     echo
" ont suffisamment d'avantages pour qu'on se pose la question de leur utilisation." ;
00119     
finp() ;
00120     
00121     
p
("texte") ;
00122     echo
" Le terme "
.b("fullstack")." fait référence à des compétences de développement Web " ;
00123     echo
" qui couvrent tous les aspects du développement. On pourra consulter la page Web de " ;
00124     echo
href
(" https://fr.wikipedia.org/wiki/D%C3%A9veloppeur_full_stack","wikipedia") ;
00125     echo
" sur le sujet." ;
00126     
finp() ;
00127     
00128     
p() ;
00129     
nbsp
(5) ;
00130     
$img
= "backendfrontend.jpg" ;
00131      echo
href
($img,img($img,"",500)) ;
00132     
finp() ;
00133     
00134     
finsolution
() ; # contient un blockquote
00135     
00136     
finblockquote
() ; # td
00137     
00138     ## -------------------------------------------------------------------------------------------
00139     
00140     
$tdmCRLM
->afficheRubrique("oui") ; $numExo++ ; # Instructions vectorielles (1)
00141     
00142     ## -------------------------------------------------------------------------------------------
00143     
00144     
blockquote
() ; # td
00145     
00146     
blockquote
() ; # énoncé
00147     
00148     
p
("texte doubleInterligne") ;
00149     echo
" La programmation vectorielle met en jeu des instructions basées, soit en entrée, soit en sortie, sur des structures de type tableau mais nommées " ;
00150     echo
' vecteurs par analogie avec les vecteurs mathématiques de '
.ghBleu('$\mathbf{\Bbb{R}^n}$').'. ' ;
00151     echo
' On notera pour cet exercice $V_i$ la i-ème composante du vecteur $V$, équivalente à V[i] ou V[i-1] pour l\'informatique. ' ;
00152     echo
" Les calculs usuels s'étendent naturellement aux vecteurs, comme en mathématiques, dès lors que les contraintes de longueur sont respectées. " ;
00153     echo
' En particulier, pour un vecteur $V$ et un nombre $a$, le vecteur $aV$ a pour i-ème composante la valeur $aV_i$. ' ;
00154     echo
' Pour deux vecteurs $V$ et $W$ de m&ecirc;me longueur, $V+W$ est le vecteur dont la i-ème composante est $V_i+W_i$, ' ;
00155     echo
' et $V\times{}W$ est le vecteur dont la i-ème composante est $V_i\times{}W_i$ (&laquo;produit scalaire&raquo;). ' ;
00156     
finp() ;
00157     
00158     
p
("texte") ;
00159     echo
" On admettra pour ce qui suit qu'on dispose des fonctions vectorielles suivantes&nbsp;:" ;
00160     
finp() ;
00161     
00162     
ul() ;
00163     
00164     
debutli
() ; p() ;
00165      echo
b
("indices(n)").' qui renvoie, pour un entier $n$, le vecteur de longueur $n$ dont la i-ème composante est $i$&nbsp;' ;
00166     
finp
() ; finli() ;
00167     
00168     
debutli
() ; p() ;
00169      echo
b
("longueur(V)")." qui renvoie le nombre d'éléments du vecteur V&nbsp;;" ;
00170     
finp
() ; finli() ;
00171     
00172     
debutli
() ; p() ;
00173      echo
b
("somme(V)")." qui renvoie la somme des éléments du vecteur V&nbsp;;" ;
00174     
finp
() ; finli() ;
00175     
00176     
debutli
() ; p() ;
00177      echo
b
("produit(V)")." qui renvoie le produit des éléments du vecteur V&nbsp;;" ;
00178     
finp
() ; finli() ;
00179     
00180     
debutli
() ; p() ;
00181      echo
b
("cumul(V)")." qui renvoie le vecteur des sommes cumulées de V&nbsp;;" ;
00182     
finp
() ; finli() ;
00183     
00184     
finul() ;
00185     
00186     
p
("texte") ;
00187     echo
"Donner les instructions vectorielles qui permettent de calculer&nbsp;:" ;
00188     
finp() ;
00189     
00190     
ul
("class='tirets'") ;
00191     
00192     
debutli
() ; p() ;
00193      echo
'- le vecteur $I$ des $n$ premiers entiers&nbsp;;' ;
00194     
finp
() ; finli() ;
00195     
00196     
debutli
() ; p() ;
00197      echo
'- la somme $S = \sum i$ des $n$ premiers entiers&nbsp;;' ;
00198     
finp
() ; finli() ;
00199     
00200     
debutli
() ; p() ;
00201      echo
'- la somme $C = \sum i^2$ des n premiers carrés d\'entiers&nbsp;;' ;
00202     
finp
() ; finli() ;
00203     
00204     
debutli
() ; p() ;
00205      echo
'- la valeur $F = n!$ ("factorielle n")&nbsp;;' ;
00206     
finp
() ; finli() ;
00207     
00208     
debutli
() ; p() ;
00209      echo
'- la moyenne $M$ et la variance (empirique) $V$ d\'un vecteur $W$ numérique&nbsp;;' ;
00210     
finp
() ; finli() ;
00211     
00212     
debutli
() ; p() ;
00213      echo
'- le vecteur $P$ des fréquences cumulées d\'un vecteur $W$ d\'effectifs (positifs ou nuls) de somme non nulle.' ;
00214     
finp
() ; finli() ;
00215     
00216     
finul() ;
00217     
00218     
p
("texte") ;
00219     echo
' On pourra imaginer que $n$ vaut 5 pour vérifier les calculs à la main, et que $W$ est le vecteur (1,5,3,1). ' ;
00220     
finp() ;
00221     
00222     
p
("texte") ;
00223     echo
"Quels langages implémentent de tels calculs&nbsp;?" ;
00224     echo
" Quelle est alors la syntaxe exacte à utiliser&nbsp;?" ;
00225     
finp() ;
00226     
00227     
finblockquote
() ; # énoncé
00228     
00229     
solutionTD
($numExo,$numSerie) ; # contient un blockquote
00230     
00231     
p
("texte") ;
00232     echo
"Les langages
$R et $APL implémentent ces calculs de façon native. $Python les implémente via le package " ;
00233     echo
href
("https://numpy.org/",b("NumPy")).". " ;
00234     echo
" Sans rien installer, pour
$APL, on peut utiliser le site " ;
00235     echo
href
("https://tryapl.org","tryapl.org")." à cause des caractères spéciaux. " ;
00236     echo
" Pour
$R et $Python, là encore sans rien installer, on peut utiliser en ligne, le site " ;
00237     echo
href
("https://repl.it")." ou les ".b("jupyter notebook")." à l'adresse " ;
00238     echo
href
("http://jupyter.org/try","try jupyter").". " ;
00239     
finp() ;
00240     
00241     
p
("texte") ;
00242     echo
" Pour
$Python, on a \"importé\" les fonctions array, arange et shape de numpy. " ;
00243     echo
" Certaines solutions avec la syntaxe objet ont un équivalent traditionnel, comme par exemple " ;
00244     echo
b
("sum(I)")." au lieu de ".b("I.sum()")."." ;
00245     
finp() ;
00246     
00247     
# vérification avec td2vect1.r et td2vect1.py et td2vect1bis.py
00248     
00249     
blockquote
() ; # tableau
00250     
table
(1,15,"collapse") ;
00251     
entetesTableau
("Algorithmique Langage__R Langage__APL Langage__Python Résultat") ;
00252     
00253     
tr() ;
00254     
td
() ; echo tt(" I <-- indices(n)") ; fintd() ;
00255     
td
() ; echo tt(" I <- 1:n") ; fintd() ;
00256     
td
() ; echo tt(" I &#8592; &iota;n") ; fintd() ;
00257     
td
() ; echo tt(" I = arange(1,n+1)") ; fintd() ;
00258     
td
() ; echo tt("(1,2,3,4,5)") ; fintd() ;
00259     
fintr() ;
00260     
00261     
tr() ;
00262     
td
() ; echo tt(" S <-- somme(I)") ; fintd() ;
00263     
td
() ; echo tt(" S <- sum(I)") ; fintd() ;
00264     
td
() ; echo tt(" S &#8592; +/I") ; fintd() ;
00265     
td
() ; echo tt(" S = I.sum()") ; fintd() ;
00266     
td
("R") ; echo tt("15") ; fintd() ;
00267     
fintr() ;
00268     
00269     
tr() ;
00270     
td
() ; echo tt(" C <-- somme(I&times;I)") ; fintd() ;
00271     
td
() ; echo tt(" C <- sum(I*I)") ; fintd() ;
00272     
td
() ; echo tt(" C &#8592; +/I&times;I") ; fintd() ;
00273     
td
() ; echo tt(" C = (I*I).sum()") ; fintd() ;
00274     
td
("R") ; echo tt("55") ; fintd() ;
00275     
fintr() ;
00276     
00277     
tr() ;
00278     
td
() ; echo tt(" F <-- produit(I)") ; fintd() ;
00279     
td
() ; echo tt(" F <- prod(I)") ; fintd() ;
00280     
td
() ; echo tt(" F &#8592; &times;/I") ; fintd() ;
00281     
td
() ; echo tt(" F = I.prod()") ; fintd() ;
00282     
td
("R") ; echo tt("120") ; fintd() ;
00283     
fintr() ;
00284     
00285     
tr() ;
00286     
td
() ; echo tt(" M <-- somme(W) / longueur(W)") ; fintd() ;
00287     
td
() ; echo tt(" M <- sum(W) / length(W)") ; fintd() ;
00288     
td
() ; echo tt(" M &#8592; (+/W) &divide; &rho;W") ; fintd() ;
00289     
td
() ; echo tt(" M = W.sum()/shape(W)") ; fintd() ;
00290     
td
("R") ; echo tt("2.5") ; fintd() ;
00291     
fintr() ;
00292     
00293     
tr() ;
00294     
td
() ; echo tt(" V <-- somme( (W-M)^2 ) / longueur(W)") ; fintd() ;
00295     
td
() ; echo tt(" V <- sum((W-M)**2) / length(W)") ; fintd() ;
00296     
td
() ; echo tt(" V &#8592; (+/(W-M)*2)) &divide; &rho;W") ; fintd() ;
00297     
td
() ; echo tt(" sum((W-M)**2)/shape(W)") ; fintd() ;
00298     
td
("R") ; echo tt("2.75") ; fintd() ;
00299     
fintr() ;
00300     
00301     
tr() ;
00302     
td
() ; echo tt(" P <-- cumul(W) / somme(W)") ; fintd() ;
00303     
td
() ; echo tt(" P <- cumsum(W) / sum(W)") ; fintd() ;
00304     
td
() ; echo tt(" P &#8592; (+\\W) &divide; +/W") ; fintd() ;
00305     
td
() ; echo tt(" P = W.cumsum()/W.sum()") ; fintd() ;
00306     
td
() ; echo tt("(0.1,0.6,0.9,1.0)") ; fintd() ;
00307     
fintr() ;
00308     
00309     
fintable() ;
00310     
finblockquote
() ; # tableau
00311     
00312     # https://eric.univ-lyon2.fr/~ricco/cours/slides/PG%20-%20vecteurs%20avec%20numpy.pdf
00313     # import numpy as np OUI
00314     # np.sum(W) OUI mais W.sum() mieux W.shape pas W.shape() W.flags et W.size plutot que shape
00315     # from numpy import * surtout pas
00316     # W = np.array([1,5,3,1]) et W.cumsum()/W.sum()
00317     # http://math.mad.free.fr/depot/numpy/base.html
00318     # http://www.python-simple.com/python-numpy-scipy/statistics-numpy.php
00319     
00320     
p
("texte") ;
00321     echo
b
("Remarques&nbsp;:") ;
00322     echo
"
$APL a une fonction spécialisée pour calculer factorielle n. Et l'opération de réduction via ".b("/") ;
00323     echo
" peut s'appliquer à n'importe quel opérateur. " ;
00324     echo
"
$R a des fonctions spécialisées pour calculer factorielle n, la moyenne et la variance, " ;
00325     echo
" sachant qu'en statistiques, il y a plusieurs variances " ;
00326     echo
" (dont celle de l'échantillon, celle de la population sous-jacente)." ;
00327     echo
"
$Python, via NumPy notamment, dispose aussi de fonctions spécialisées pour réaliser de tels calculs." ;
00328     
finp() ;
00329     
00330     
p
("texte") ;
00331     echo
ghRouge
("Attention")." à l'écriture \"propre\" des appels de fonctions dans ces langages. " ;
00332     echo
" Ainsi en
$R, ".b("sum(I)*I")." et ".b("sum(I*I)")." sont tous deux des calculs valides mais qui ne fournissent pas le m&ecirc;me résultat. " ;
00333     echo
" En
$Python aussi, avec ".b("I*I.sum()")." et ".b("(I*I).sum()").". " ;
00334     echo
" Il est donc important de vérifier que le code produit bien ce qu'on veut." ;
00335     
finp() ;
00336     
00337     
finsolution
() ; # contient un blockquote
00338     
00339     
finblockquote
() ; # td
00340     
00341     ## -------------------------------------------------------------------------------------------
00342     
00343     
$tdmCRLM
->afficheRubrique("oui") ; $numExo++ ; # Instructions vectorielles (2)
00344     
00345     ## -------------------------------------------------------------------------------------------
00346     
00347     
blockquote
() ; # td
00348     
00349     
blockquote
() ; # énoncé
00350     
00351     
p
("texte doubleInterligne") ;
00352     echo
" On suppose désormais que les comparaisons logiques usuelles sont aussi des opérations vectorielles qui renvoient, indice par indice, " ;
00353     echo
' 0 lorsque le résultat du test est faux et 1 lorsque le résultat du test est vrai. ' ;
00354     echo
' Ainsi, pour le vecteur $V=(5,8,2,1,9)$, la comparaison $V>3$ renvoie $(1,1,0,0,1)$.' ;
00355     
finp() ;
00356     
00357     
p
("texte") ;
00358     echo
' Détailler ce que réalisent les calculs suivants écrits en '
.$APL.', sachant que &Gamma; correspond à la fonction '.b("max()").'. ' ;
00359     echo
' On pourra essayer d\'inventer la syntaxe algorithmique correspondante et on se posera la question de savoir comment ' ;
00360     echo
' écrire cela en '
.$R.' puis en '.$Python.', sans doute là encore à l\'aide de NumPy.' ;
00361     
finp() ;
00362     
00363     
00364     
p
("texte") ;
00365     echo
b
("Atttention")."&nbsp;: " ;
00366     echo
$APL
.' interprète les opérations à partir de la droite afin de minimiser le nombre de parenthèses à écrire. ' ;
00367     echo
' Ainsi 2 &times; 3 +5 correspond à 2 &times; (3 +5) soit 16.' ;
00368     
finp() ;
00369     
00370     
blockquote
() ; # tableau
00371     
table
(1,15,"collapse") ;
00372     
entetesTableau
("Numéro Instruction__APL Remarque") ;
00373     
00374     
tr() ;
00375     
td
("R") ; echo tt(1)."&nbsp;&nbsp;" ; fintd() ;
00376     
td
() ; echo "&nbsp;&nbsp;".tt("V=W") ; fintd() ;
00377     
td
() ; echo "V et W sont des vecteurs numériques ou caractères" ; fintd() ;
00378     
fintr() ;
00379     
00380     
tr() ;
00381     
td
("R") ; echo tt(2)."&nbsp;&nbsp;" ; fintd() ;
00382     
td
() ; echo "&nbsp;&nbsp;".tt("+/V=W") ; fintd() ;
00383     
td
() ; echo "V et W sont des vecteurs numériques ou caractères" ; fintd() ;
00384     
fintr() ;
00385     
00386     
tr() ;
00387     
td
("R") ; echo tt(3)."&nbsp;&nbsp;" ; fintd() ;
00388     
td
() ; echo "&nbsp;&nbsp;".tt("+/V>0") ; fintd() ;
00389     
td
() ; echo "V est un vecteur numérique" ; fintd() ;
00390     
fintr() ;
00391     
00392     
tr() ;
00393     
td
("R") ; echo tt(4)."&nbsp;&nbsp;" ; fintd() ;
00394     
td
() ; echo "&nbsp;&nbsp;".tt("+/&Gamma;/V=V") ; fintd() ;
00395     
td
() ; echo "V est un vecteur numérique" ; fintd() ;
00396     
fintr() ;
00397     
00398     
tr() ;
00399     
td
("R") ; echo tt(5)."&nbsp;&nbsp;" ; fintd() ;
00400     
td
() ; echo "&nbsp;&nbsp;".tt("+/V=&Gamma;/V") ; fintd() ;
00401     
td
() ; echo "V est un vecteur numérique" ; fintd() ;
00402     
fintr() ;
00403     
00404     
tr() ;
00405     
td
("R") ; echo tt(6)."&nbsp;&nbsp;" ; fintd() ;
00406     
td
() ; echo "&nbsp;&nbsp;".tt('+/V$\times$W') ; fintd() ;
00407     
td
() ; echo "V est un vecteur numérique" ; fintd() ;
00408     
fintr() ;
00409     
00410     
tr() ;
00411     
td
("R") ; echo tt(7)."&nbsp;&nbsp;" ; fintd() ;
00412     
td
() ; echo "&nbsp;&nbsp;".tt('+/V$\times$V') ; fintd() ;
00413     
td
() ; echo "V est un vecteur numérique" ; fintd() ;
00414     
fintr() ;
00415     
00416     
fintable() ;
00417     
finblockquote
() ; # tableau
00418     
00419     
p
("texte") ;
00420      echo
" On commencera par donner le vecteur résultat correspondand à chaque instruction " ;
00421      echo
' pour les vecteurs $V=(5,8,-2,1,8)$ ' ;
00422      echo
' et $W=(5,8,2,1,9)$. ' ;
00423     
finp() ;
00424     
00425     
finblockquote
() ; # énoncé
00426     
00427     
solutionTD
($numExo,$numSerie) ; # contient un blockquote
00428     
00429     
p
("texte") ;
00430      echo
'Voici les résultats pour les vecteurs $V$ et $W$ fournis&nbsp;:' ;
00431     
finp() ;
00432     
00433     
blockquote
() ; # tableau
00434     
table
(1,15,"collapse") ;
00435     
entetesTableau
("Numéro Instruction__APL Résultat Remarque(s)") ;
00436     
00437     
tr() ;
00438     
td
("R") ; echo tt(1)."&nbsp;&nbsp;" ; fintd() ;
00439     
td
() ; echo tt("V=W") ; fintd() ;
00440     
td
() ; echo '($1,1,0,1,0)$' ; fintd() ;
00441     
td
() ; echo " Les différences sont aux indices 3 et 5." ; fintd() ;
00442     
fintr() ;
00443     
00444     
tr() ;
00445     
td
("R") ; echo tt(2)."&nbsp;&nbsp;" ; fintd() ;
00446     
td
() ; echo tt("+/V=W") ; fintd() ;
00447     
td
() ; echo "3" ; fintd() ;
00448     
td
() ; echo "C'est la somme du vecteur précédent." ; fintd() ;
00449     
fintr() ;
00450     
00451     
tr() ;
00452     
td
("R") ; echo tt(3)."&nbsp;&nbsp;" ; fintd() ;
00453     
td
() ; echo tt("+/V>0") ; fintd() ;
00454     
td
() ; echo "4" ; fintd() ;
00455     
td
() ; echo 'Il y a 4 valeurs strictement positives dans $V$.' ; fintd() ;
00456     
fintr() ;
00457     
00458     
tr() ;
00459     
td
("R") ; echo tt(4)."&nbsp;&nbsp;" ; fintd() ;
00460     
td
() ; echo tt("+/&Gamma;/V=V") ; fintd() ;
00461     
td
() ; echo "1" ; fintd() ;
00462     
td
() ; echo '$V=V$ renvoie $(1,1,1,1,1)$. ($&Gamma;/V=V$) est donc 1 et $+/1$ renvoie 1.' ; fintd() ;
00463     
fintr() ;
00464     
00465     
tr() ;
00466     
td
("R") ; echo tt(5)."&nbsp;&nbsp;" ; fintd() ;
00467     
td
() ; echo tt("+/V=&Gamma;/V") ; fintd() ;
00468     
td
() ; echo "2" ; fintd() ;
00469     
td
() ; echo '&Gamma;/V est 8. $V=&Gamma;/V$ est $(0,1,0,0,1)$. Sa somme est 2.' ; fintd() ;
00470     
fintr() ;
00471     
00472     
tr() ;
00473     
td
("R") ; echo tt(6)."&nbsp;&nbsp;" ; fintd() ;
00474     
td
() ; echo "&nbsp;&nbsp;".tt('+/V$\times$W') ; fintd() ;
00475     
td
() ; echo "158" ; fintd() ;
00476     
td
() ; echo 'V$\times$W est (25,64,-4,1,72). Sa somme est 158.' ; fintd() ;
00477     
fintr() ;
00478     
00479     
tr() ;
00480     
td
("R") ; echo tt(7)."&nbsp;&nbsp;" ; fintd() ;
00481     
td
() ; echo "&nbsp;&nbsp;".tt('+/V$\times$V') ; fintd() ;
00482     
td
() ; echo "158 (aussi !)" ; fintd() ;
00483     
td
() ; echo 'V$\times$V est (25,64,4,1,64). Sa somme est 158.' ; fintd() ;
00484     
fintr() ;
00485     
00486     
fintable() ;
00487     
finblockquote
() ; # tableau
00488     
p
("texte") ;
00489     echo
"La première instruction renvoie le vecteur des comparaisons terme à terme des vecteurs V et W. " ;
00490     
finp() ;
00491     
00492     
p
("texte") ;
00493     echo
" La deuxième instruction renvoie le nombre "
.b("egal(V,W)")." de valeurs égales dans V et W à la m&ecirc;me position. " ;
00494     echo
" Un calcul lié à cette instruction est le nombre "
.b("diff(V,W)")." de valeurs différentes entre V et W. " ;
00495     
finp() ;
00496     
00497     
p
("texte") ;
00498     echo
" La fonction "
.b('(V,W)&nbsp;$\mapsto$&nbsp;diff(V,W)')." est nommée " ;
00499     echo
href
("https://fr.wikipedia.org/wiki/Distance_de_Hamming","distance de Hamming").". " ;
00500     echo
" Cette distance est très utilisée en bioinformatique et en informatique textuelle." ;
00501     
finp() ;
00502     
00503     
p
("texte") ;
00504     echo
" La troisième instruction renvoie le nombre de valeurs strictement positives dans le vecteur V. " ;
00505     
finp() ;
00506     
00507     
p
("texte") ;
00508     echo
" La quatrième instruction correspond sans doute à une erreur de frappe. " ;
00509     echo
" Elle renvoie 1 systématiquement." ;
00510     
finp() ;
00511     
00512     
p
("texte") ;
00513     echo
" La cinquième instruction renvoie le nombre de valeurs dans le vecteur V " ;
00514     echo
" égales au maximum de V. C'est sans doute la bonne version de l'instruction 4." ;
00515     
finp() ;
00516     
00517     
p
("texte") ;
00518     echo
" La sixième instruction renvoie la somme des produits terme à terme des vecteurs V et W." ;
00519     echo
" C'est donc ce qu'en algèbre (linéaire) on nomme le "
.b("produit scalaire")." de ces vecteurs." ;
00520     
finp() ;
00521     
00522     
p
("texte") ;
00523     echo
" La septième instruction renvoie le produit scalaire d'un vecteur avec lui-m&ecirc;me." ;
00524     echo
" C'est donc ce qu'en algèbre on nomme le "
.b("carré de la norme")." de ce vecteur." ;
00525     
finp() ;
00526     
00527     
p
("texte") ;
00528     echo
b
("Code $R correspondant&nbsp;:") ;
00529     
finp() ;
00530     
00531     
pre_fichier
("td2vect2.r","cadrejaune") ;
00532     
00533     
p
("texte") ;
00534     echo
b
("Résultats&nbsp;:") ;
00535     
finp() ;
00536     
00537     
pre_fichier
("td2vect2r.txt","cadre") ;
00538     
00539     
p
("texte") ;
00540     echo
b
("Code $Python correspondant&nbsp;:") ;
00541     
finp() ;
00542     
00543     
pre_fichier
("td2vect2.py","cadrejaune") ;
00544     
00545     
p
("texte") ;
00546     echo
b
("Résultats&nbsp;:") ;
00547     
finp() ;
00548     
00549     
pre_fichier
("td2vect2py.txt","cadre") ;
00550     
00551     
finsolution
() ; # contient un blockquote
00552     
00553     
finblockquote
() ; # td
00554     
00555     ## -------------------------------------------------------------------------------------------
00556     
00557     
$tdmCRLM
->afficheRubrique("oui") ; $numExo++ ; # Boucles et optimisation (1)
00558     
00559     ## -------------------------------------------------------------------------------------------
00560     
00561     
blockquote
() ; # td
00562     
00563     
blockquote
() ; # énoncé
00564     
00565     
p
("texte") ;
00566     echo
' On se donne deux valeurs numériques $a$ et $b$ et un entier $n$. Ecrire un algorithme qui calcule les valeurs ' ;
00567     echo
' des $n$ points équidistants $x_i$, $i$ de 1 à $n$ avec $a=x_1$ et $b=x_n$. ' ;
00568     echo
' On commencera par trouver la formule qui sépare deux points sucessifs. ' ;
00569     echo
' On discutera s\'il faut utiliser une boucle '
.b("pour").', ' ;
00570     echo
' une boucle '
.b("tant que").', ou se passer de boucle et on viendra optimiser le nombre d\'opérations. ' ;
00571     
finp() ;
00572     
00573     
p
("texte") ;
00574     echo
' Au passage, que sont les $x_i$ pour $n=10$ avec $a=1$ et $b=10$&nbsp;?' ;
00575     echo
' Et pour $n=11$ avec $a=0$ et $b=1$&nbsp;?' ;
00576     
finp() ;
00577     
00578     
p
("texte") ;
00579     echo
' Trouver ensuite une solution vectorielle. ' ;
00580     
#echo ' Quelles solutions sont proposées par '.$R.', '.$APL.' et '.$Python.'&nbsp;?' ;
00581     
echo
' Quelles solutions sont proposées par '.$R.' et '.$Python.'&nbsp;?' ;
00582     
finp() ;
00583     
00584     
finblockquote
() ; # énoncé
00585     
00586     
solutionTD
($numExo,$numSerie) ; # contient un blockquote
00587     
00588     
p
("texte") ;
00589     echo
" La formule mathématique pour calculer les "
.'$x_i$'." est bien s&ucirc;r :";
00590     
finp() ;
00591     
00592     
p
("texte plusgros") ;
00593     
nbsp
(7) ;
00594     echo
'$x_i = a + (i-1)\times \displaystyle\frac{(b-a)}{(n-1)}$' ;
00595     
finp() ;
00596     
00597     
p
("texte") ;
00598     echo
' Pour $n=10$, avec $a=1$ et $b=10$, les $x_i$ sont les nombres de 1 à 10.' ;
00599     
finp() ;
00600     
00601     
p
("texte") ;
00602     echo
' Pour $n=11$, avec $a=0$ et $b=1$, les valeurs sont 0 0.1 0.2... 1.0.' ;
00603     
finp() ;
00604     
00605     
p
("texte") ;
00606     echo
" La programmation na&iuml;ve de la formule ne pose aucun problème&nbsp;:" ;
00607     
finp() ;
00608     
00609     
pre_fichier
("xi01.alg","cadrebleu") ;
00610     
00611     
p
("texte") ;
00612     echo
" Une première optimisation de la boucle consiste à sortir les &laquo;constantes&raquo; de la boucle " ;
00613     echo
" et à initialiser le vecteur de sortie, soit le code&nbsp;:" ;
00614     
finp() ;
00615     
00616     
pre_fichier
("xi02.alg","cadrebleu") ;
00617     
00618     
p
("texte") ;
00619     echo
' Une deuxième optimisation consiste à remarquer que les $x_i$ sont en progression arithmétique, ' ;
00620     echo
' donc il suffit de rajouter le pas $h$ de la progression pour passer d\'un point à l\'autre&nbsp;:' ;
00621     
finp() ;
00622     
00623     
pre_fichier
("xi03.alg","cadrebleu") ;
00624     
00625     
p
("texte") ;
00626     echo
" Bien s&ucirc;r le calcul vectoriel permet de se passer de boucle&nbsp;:" ;
00627     
finp() ;
00628     
00629     
pre_fichier
("xi04.alg","cadrebleu") ;
00630     
00631     
p
("texte") ;
00632     echo
" Voici à titre d'exemple les versions 1 et 4 en
$R&nbsp;:" ;
00633     
finp() ;
00634     
00635     
pre_fichier
("xi01et4.r","cadrejaune") ;
00636     
00637     
p
("texte") ;
00638     echo
" Et leur équivalent en
$Python&nbsp;:" ;
00639     
finp() ;
00640     
00641     
pre_fichier
("xi01et4.py","cadrejaune") ;
00642     
00643     
p
("texte") ;
00644     echo
"La \"vraie\" solution se nomme "
.b("seq()")." en $R et ".b("linspace()")." en $Python".ghvert(" / NumPy")." avec les syntaxes suivantes&nbsp;:" ;
00645     
finp() ;
00646     
00647     
pre_fichier
("xi01et4.sol","cadrebleu") ;
00648     
00649     
finsolution
() ; # contient un blockquote
00650     
00651     
finblockquote
() ; # td
00652     
00653     ## -------------------------------------------------------------------------------------------
00654     
00655     
$tdmCRLM
->afficheRubrique("oui") ; $numExo++ ; # Boucles et optimisation (2)
00656     
00657     ## -------------------------------------------------------------------------------------------
00658     
00659     
blockquote
() ; # td
00660     
00661     
blockquote
() ; # énoncé
00662     
00663     
p
("texte") ;
00664     echo
' Comment calculer de façon optimisée le maximum, le nombre d\'occurrences de ce maximum et sa première position pour un vecteur $V$&nbsp;?' ;
00665     
finp() ;
00666     
00667     
p
("texte") ;
00668     echo
' Est-ce qu\'une solution vectorielle pour ce problème est forcément optimisée&nbsp;? ' ;
00669     
finp() ;
00670     
00671     
p
("texte") ;
00672     echo
'Quelles solutions sont proposées par '
.$R.', '.$APL.' et '.$Python.'&nbsp;?' ;
00673     
finp() ;
00674     
00675     
p
("texte") ;
00676     echo
"Le code proposé est-il valide pour des vecteurs de chaines de caractères plut&ocirc;t que pour des vecteurs de nombres&nbsp;?" ;
00677     
finp() ;
00678     
00679     
finblockquote
() ; # énoncé
00680     
00681     
solutionTD
($numExo,$numSerie) ; # contient un blockquote
00682     
00683     
p
("texte") ;
00684     echo
" Un algorithme qui passe en revue chaque élément et décide si c'est le nouveau maximum (donc une seule occurrence) " ;
00685     echo
" ou le maximum local (c'est-à-dire le maximum trouvé jusque-là, donc une occurrence de plus) est certainement un " ;
00686     echo
" algorithme optimisé qui peut s'écrire en une seule boucle POUR, comme ci-dessous&nbsp;:" ;
00687     
finp() ;
00688     
00689     
pre_fichier
("maxocc1.alg","cadre") ;
00690     
00691     
p
("texte") ;
00692     echo
" Une solution vectorielle pour compter le nombre d'occurrences du maximum " ;
00693     echo
" par exemple avec le code "
.b("somme(&nbsp;V=max(V)&nbsp;)")." est certes courte à écrire mais effectue deux parcours du vecteur. " ;
00694     echo
" Cela s'écrit " ;
00695     echo
b
(s_span(tt("+/V=&Gamma;/V"),"plusgros"))." en $APL, " ;
00696     echo
b
(s_span(tt("sum(&nbsp;V==max(V)&nbsp;)"),"plusgros"))." en $R et " ;
00697     echo
b
(s_span(tt("(V==max(V)).sum()"),"plusgros"))." en $Python. " ;
00698     
finp() ;
00699     
00700     
p
("texte") ;
00701     echo
" Une telle écriture est sans doute suffisante car le code sous-jacent est très rapide, m&ecirc;me pour des millions d'éléments. " ;
00702     echo
" Il faudrait vraiment avoir des milliers de chaines d'ADN humain complètes (3 milliards de caractères) à comparer pour que ce code vectoriel soit moins efficace que notre algorithme." ;
00703     
finp() ;
00704     
00705     
p
("texte") ;
00706     echo
"Nous ne donnons pas ici, volontairement, les solutions vectorielles en
$R, $APL et $Python pour trouver la première position du maximum. " ;
00707     echo
" Symboliquement, ce pourrait &ecirc;tre "
.b("premier(&nbsp;V=max(V)&nbsp;)")." mais il faudrait alors \"sortir\" le vecteur ".b("V=max(V)") ;
00708     echo
" de ce calcul pour éviter de le recalculer deux fois afin de résoudre le problème complet posé. " ;
00709     echo
" Les solutions algorithmiques correspondantes sont indiquées ci-dessous." ;
00710     
finp() ;
00711     
00712     
p() ;
00713     echo
b
("Version vectorielle non optimisée") ;
00714     
finp() ;
00715     
00716     
pre_fichier
("maxocc2.alg","cadre") ;
00717     
00718     
p() ;
00719     echo
b
("Version vectorielle optimisée") ;
00720     
finp() ;
00721     
00722     
pre_fichier
("maxocc3.alg","cadre") ;
00723     
00724     
finsolution
() ; # contient un blockquote
00725     
00726     
finblockquote
() ; # td
00727     
00728     ## -------------------------------------------------------------------------------------------
00729     
00730     
$tdmCRLM
->afficheRubrique("oui") ; $numExo++ ; # Optimisation dans le développement Web
00731     
00732     ## -------------------------------------------------------------------------------------------
00733     
00734     
00735     
blockquote
() ; # td
00736     
00737     
blockquote
() ; # énoncé
00738     
00739     
p
("texte") ;
00740     echo
" Ce qu'on a vu précédemment montre que dans de nombreux cas, des calculs simples comme le maximum, les valeurs " ;
00741     echo
" d'une suite arithmétique sont déjà programmés. Peut-on penser que dans l'utilisation de bases de données, on trouve " ;
00742     echo
" le m&ecirc;me genre de solutions pré-programmées&nbsp;?" ;
00743     echo
" Et dans le cas du développement Web&nbsp;?" ;
00744     
finp() ;
00745     
00746     
p
("texte") ;
00747     echo
"Comment garantir par exemple qu'une requ&ecirc;te "
.ghBleu("MySQL")." est optimisée&nbsp;?" ;
00748     
finp() ;
00749     
00750     
p
("texte") ;
00751     echo
"Comment tester la vitesse d'exécution de code en
$R et en $Python&nbsp;?" ;
00752     
finp() ;
00753     
00754     
finblockquote
() ; # énoncé
00755     
00756     
solutionTD
($numExo,$numSerie) ; # contient un blockquote
00757     
00758     
p
("texte") ;
00759     echo
" Oui, bien s&ucirc;r, des solutions pré-programmées existent déjà pour les bases de donnnées. " ;
00760     echo
" Par exemple en SQL, pour calculer le maximum ou la moyenne, il existe des " ;
00761     echo
" fonctions nommées " ;
00762     echo
href
("https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html","fonctions d'agrégation.")." " ;
00763     echo
" comme min, max, avg et "
.b("les")." variances." ;
00764     
finp() ;
00765     
00766     
p
("texte") ;
00767     echo
" Savoir si une requ&ecirc;te est optimisée, par contre, est loin d'&ecirc;tre évident. " ;
00768     echo
" Par exemple, comment savoir si la requ&ecirc;te ci-dessous est optimisée&nbsp;?" ;
00769     
finp() ;
00770     
00771     
pre_fichier
("reqSql-long.txt","cadrebleu") ;
00772     
00773     
p
("texte") ;
00774     echo
" Ou comment décider si la requ&ecirc;te 1 ci-dessous " ;
00775     
finp() ;
00776     
00777     
pre_fichier
("req1mini.txt","cadrejaune") ;
00778     
00779     
p
("texte") ;
00780     echo
" s'exécute plus rapidement que la requ&ecirc;te 2 suivante " ;
00781     
finp() ;
00782     
00783     
pre_fichier
("req2mini.txt","cadrejaune") ;
00784     
00785     
p
("texte") ;
00786     echo
" M&ecirc;me si MySQL, par exemple, dispose d'un " ;
00787     echo
href
("https://dev.mysql.com/doc/refman/8.0/en/show-profile.html","mécanisme de profilage") ;
00788     echo
" dont le modèle est reproduit dans le texte qui suit " ;
00789     
finp() ;
00790     
00791     
pre_fichier
("profilingSql.txt","cadre") ;
00792     
00793     
p
("texte") ;
00794     echo
" il n'en demeure pas moins qu'exécuter une seule fois la requ&ecirc;te et son profilage " ;
00795     echo
" n'est certainement pas suffisant, sauf dans de très rares cas (à cause de l'encombrement " ;
00796     echo
" mémoire, de la mise en cache des données, etc.). " ;
00797     echo
" Donc on peut essayer d'estimer si une requ&ecirc;te est optimisée, mais sans pouvoir vraiment " ;
00798     echo
" le prouver." ;
00799     
finp() ;
00800     
00801     
pre_fichier
("req1et2.txt","cadrebleu") ;
00802     
00803     
p
("texte") ;
00804     echo
" Pour tester du code,
$R et $Python fournissent aussi des instructions, respectivement " ;
00805     echo
" la fonction " ;
00806     echo
href
("https://cran.r-project.org/web/packages/microbenchmark/index.html","microbenchmark") ;
00807     echo
" du package "
.em("eponyme")." et la fonction ".em("magique")." " ;
00808     echo
href
("https://ipython.org/ipython-doc/dev/interactive/magics.html#magic-timeit","%timeit")."." ;
00809     
#echo href("https://docs.python.org/3/library/timeit.html","timeit")."." ;
00810     
finp() ;
00811     
00812     
p
("texte") ;
00813     echo
"En voici des exemples d'utilisation&nbsp;:" ;
00814     
finp() ;
00815     
00816     
pre_fichier
("microbench.txt","cadrebleu") ;
00817     
00818     
pre_fichier
("timeit.txt","cadrejaune") ;
00819     
00820     
00821     
p
("texte") ;
00822     echo
" Ce qu'on doit retenir de tout cela, c'est principalement deux choses&nbsp;:" ;
00823     
finp() ;
00824     
00825     
blockquote() ;
00826     
ul() ;
00827     
00828     
debutli
() ; p("texte") ;
00829      echo
" de nombreuses solutions à des problèmes classiques sont déjà pré-programmées, disponibles et " ;
00830      echo
" il vaut mieux les utiliser plut&ocirc;t que de vouloir réinventer la roue et l'eau chaude " ;
00831      echo
" parce que ces solutions sont "
.b("robustes")."&nbsp;;" ;
00832     
finp
() ; finli() ;
00833     
00834     
debutli
() ; p("texte") ;
00835      echo
" exécuter une fois le code pour avoir une idée de sa vitesse et de sa durée d'exécution " ;
00836      echo
" n'est pas suffisant (il peut y avoir de la mise en cache des données, d'autres processus en mémoire...) " ;
00837      echo
" et il vaut mieux utiliser des outils pour évaluer la performance&nbsp;;" ;
00838     
finp
() ; finli() ;
00839     
00840     
debutli
() ; p("texte") ;
00841      echo
" il faut penser à se se poser la question de l'optimisation dès que la taille des données " ;
00842      echo
" est importante ou dès que le problème risque d'exploser combinatoirement. " ;
00843     
finp
() ; finli() ;
00844     
00845     
finul() ;
00846     
finblockquote() ;
00847     
00848     
00849     
p
("texte") ;
00850     echo
"Code et graphiques (cliquables) non expliqués&nbsp;:" ;
00851     
finp() ;
00852     
00853     
pre_fichier
("microbench.r","cadrebleu") ;
00854     
00855     
p() ;
00856     
nbsp
(5) ;
00857     
$img
= "boxplot-mb.png" ;
00858      echo
href
($img,img($img,"",600)) ;
00859     
finp() ;
00860     
00861     
p() ;
00862     
nbsp
(5) ;
00863     
$img
= "autoplot-mb.png" ;
00864      echo
href
($img,img($img,"",600)) ;
00865     
finp() ;
00866     
00867     
finsolution
() ; # contient un blockquote
00868     
00869     
finblockquote
() ; # td
00870     
00871     #############################################################################
00872     
00873     
finTDi
($numSerie) ;
00874     
?>

Pour ne pas voir les numéros de ligne, ajoutez &nl=non à la suite du nom du fichier.

 

 

retour gH    Retour à la page principale de   (gH)