Travaux Pratiques #2
Algo & Prog avec R
Table des matières
1. Travail au CRIPS (Petit Valrose)
Vous allez travailler sur des ordinateurs sous le système d’exploitation Windows (2ème étage) ou Linux (3ème étage). Peut-être utilisez-vous un ordinateur MacOS-X (basé sur UNIX comme Linux) ? Aucune importance puisque les logiciels qui nous serviront à programmer en R fonctionnent sur tous ces systèmes quasiment à l’identique. Nous supposons que vous savez utiliser votre ordinateur pour copier/déplacer des fichiers et lancer un logiciel ou un navigateur Web (Firefox, Chrome, etc).
Vous êtes donc devant votre machine. Vos notes de cours sont à portée de main et vos neurones commencent leurs échanges électro-chimiques, bravo !
En principe la machine est allumée, et en veille. En pressant une touche, elle devrait se réveiller et l’écran s’allumer. Appelez votre enseignant si ce n’est pas le cas, ou regardez comment font vos voisins … Vous arrivez sur une petite « fenêtre de dialogue » qui vous demande un nom d’utilisateur et un mot de passe (le vôtre).
Le bureau de Windows sert à abriter (le temps d’une séance de TP seulement) les fichiers des étudiants. Le bureau de Linux est sauvegardé d’une session à l’autre.
Nous vous demandons d’acheter une « clé USB » ou d’apprendre à utiliser un espace de stockage dans les nuages.
- Votre clef USB est un disque amovible : travaillez directement sur votre clé USB qui sera votre disque dur et espace de travail durant tous les TP.
- Votre espace de stockage est accessible grâce à votre navigateur : télécharger votre code source depuis cet espace au début de chaque séance et n’oubliez pas de le télécharger dans cet espace à la fin.
Passons dans l’éditeur
À partir de maintenant, le travail se fait dans l’éditeur, et non plus dans le top level comme au premier TP.
Lorsque l’on vous demandera de sauver le contenu de votre éditeur, vous opterez pour un fichier avec un nom explicite, par exemple tp01.R.
N.B. Vous prendrez l’habitude de n’utiliser des caractères accentués français ou d’espacement qu’à l’intérieur des chaînes de caractères, et jamais dans les noms de fonctions ou de variables ou de fichiers. Vous risquez sinon, d’avoir de désagréables surprises …
2. Maximum d’une somme
Calcul du résultat par une fonction
Définissez la fonction Somme2Max(x,y,z)
prenant trois entiers x, y, z et retournant la somme des deux plus grands.
- Écrivez une première version en emboîtant des
if
, - Écrivez une seconde version utilisant les fonctions prédéfinies
max
oumin
.
À chaque fois, testez votre fonction grâce aux appels ci-dessous.
## Ordres totaux Somme2Max(1, 2, 3) Somme2Max(1, 3, 2) Somme2Max(2, 1, 3) Somme2Max(2, 3, 1) Somme2Max(3, 1, 2) Somme2Max(3, 2, 1) ## Ordres partiels Somme2Max(3, 2, 2) Somme2Max(2, 3, 2) Somme2Max(2, 2, 3) Somme2Max(2.5, 2.5, 2.5)
Affichage du résultat à l’écran
Définissez la fonction PrintSomme2Max(x,y,z)
faisant afficher la somme des deux plus grands des entiers x
, y
, z
. Cette fonction n’aura aucun résultat (ne confondez pas l’effet et le résultat d’une fonction !).
PrintSomme2Max(3,5,7)
Le résultat de l'appel de fonction Somme2Max(3, 5, 7) est 12
3. Génération aléatoire d’un nombre KEY
Nous allons utiliser une fonction sample
tirant au hasard des éléments dans une collection, on dit aussi aléatoires. Voici 3 manières équivalentes de tirer un dé à 6 face, afficher un entier aléatoire entre [1,6]. Tapez les instructions ci-dessous.
sample(6, size=1) sample(1:6, size=1) sample(c(1, 2, 3, 4, 5, 6), size=1)
Faites afficher un entier aléatoire de [100,200] avec un appel à sample
.
Entier pair
La fonction RandPair(n)
ci-dessous prend un entier n ≥ 0 et retourne un entier pair aléatoire de [0,n].
RandPair <- function(n) { return(2*sample(n%/%2, size = 1)) }
Malheureusement, cette fonction est buggée : elle ne respecte sa spécification. Votre tâche consiste à corriger cette fonction. Faites suivre la définition de votre fonction d’une instruction pour la tester.
Dans un ensemble
- Définissez une fonction
MonteCarlo()
sans argument retournant au hasard 2, 3 ou 5. Testez-la plusieurs fois. Indice : utilisez la fonctionc
. - Définissez une fonction
LasVegas()
retournant 2, 3 ou 5 mais de manière truquée : 2 avec 1 chance sur 6, ou bien 3 avec 1 chance sur 3, ou bien 5 avec 1 chance sur 2. Testez-la une dizaine de fois… Les résultats sont-ils conformes à ce que l’on attend ? - Testez la commande
table(replicate(1000, LasVegas()))
? À quoi sert-elle ?
Lisez la documentation help(sample)
avant d’essayer de répondre aux questions.
Avec un nombre de chiffres fixé
Définissez une fonction RandChiffres(n)
prenant un entier n ≥ 1 et retournant un entier aléatoire non nul contenant exactement n
chiffres. Testez-la plusieurs fois …
4. Circuit électrique
Dans le cours d’électricité du lycée, vous avez sans doute vu que :
- la résistance équivalente de deux résistors R_1 et R_2 en série vaut R = R_1 + R_2,
- tandis que si les résistors sont placés en parallèle, leur résistance globale vérifie 1/R=1/R_1+1/R_2.
Un électronicien travaille avec la portion de circuit suivante contenant trois résistors. Programmez la fonction Circuit1(r1,r2,r3)
retournant la résistance équivalente de ce circuit.
A.N. Pour r1=5 Ω, r2=100 Ω et r3=25 Ω, le résultat est 25 Ω.
+----------+ +----------+ +------+ R1 +-------+-------+ R2 +------+---+ +----------+ | +----------+ | | | | +----------+ | +-------+ R3 +------+ +----------+
Maintenant, programmez la fonction Circuit2(R1,R2,R3)
retournant la résistance équivalente de ce circuit.
+----------+ +----------+ -+-------+ R1 +------+---+-+-------+ R2 +------+---+ | +----------+ | | +----------+ | | | | | | +----------+ | | +----------+ | +-------+ R2 +------+ +-------+ R3 +------+ | +----------+ | +----------+ | | | +----------+ | +-------+ R3 +------+ +----------+
Indice : définir une fonction auxiliaire Serie(r1, r2)
(respectivement Parallele(r1, r2)
) qui calcule la résistance globale de deux résistors en série (respectivement en parallèle).
5. Conversion du temps
Programmez une fonction hconv(n)
prenant un entier n
> 0 représentant un nombre de secondes. L’effet de cette fonction est l’affichage d’une ligne exprimant la conversion de n
secondes en heures-minutes-secondes.
hconv(4567) hconv(3601) hconv(123456789)
4567 -> 01:16:07 3601 -> 01:00:01 123456789 -> 34293:33:09
6. Impôt sur le revenu UCANCODE
Supposons que l’impôt sur le revenu annuel soit calculé par tranches de la manière suivante.
- Un salarié ne paye rien pour les 8000 premiers euros qu’il gagne.
- Il paye 10% sur chaque euro gagné entre 8000 € et 25000 €,
- et enfin 20% sur chaque euro gagné au-dessus de 25000 €.
- Définissez la fonction
Tranche(s,b,h,p)
retournant l’impôt dû pour un salaire annuels
dans la tranche[b,h]
dont le pourcentage estp
%. - Définissez la fonction
Impot(s)
retournant l’impôt total dû pour un salaire annuels
. - Modifiez la fonction
Impot(s)
pour arrondir le montant de l’impôt au centime inférieur. - Testez plus finement votre fonction grâce à l’exercice UCAnCODE.
Tranche(1500,2000,3000,10) Tranche(2500,2000,3000,10) Tranche(4000,2000,3000,10) Tranche(5000,3000,3000,10) Impot(40000)
[1] 0 [1] 50 [1] 100 [1] 0 [1] 4700
7. Calcul de l’hypoténuse
- Calculez l’hypoténuse d’un triangle connaissant les deux côtés de l’angle droit (
a
etb
). - Demander à l’utilisateur de saisir les valeurs
a
etb
à l’aide de la fonctionscan()
- Afficher et formatter le résultat avec les fonctions
cat
.
8. Évaluation des arguments d’une fonction HOME
Il y a deux sortes de fonctions en R.
Les opérateurs sont des fonctions.
En R, même les opérateurs sont des fonctions ! Par exemple, + est un opérateur, mais c’est aussi une fonction.
2 + 2 '+'(2,2) 2 == 3 '=='(2,3) 0 || 1 '||'(0,1)
Évaluation paresseuse des arguments d’une fonction
Par exemple, si f
est une fonction, au moment du calcul de f(a,b)
, l’évaluation des paramètres a
et b
de la fonction ne se fait pas avant que les résultats de cette évaluation ne soient réellement nécessaires. Ce mécanisme s’appelle l’évaluation paresseuse.
Si je définis f sous la forme :
foo <- function(x,y) {x}
quelle sera le résultat de foo(0, Sys.sleep(5))
? foo(Sys.sleep(5), 0)
? Comment R va-t-il obtenir ce résultat, vite ou lentement ?
Une fonction n’évalue ses arguments qu’en cas de besoin quand elle exécute son corps. foo(0,Sys.sleep(5))
ne dort pas inutilement pendant 5 secondes en R. Par contre, cela serait le cas en Python.
Par ailleurs, remarquez que la procédure Sys.sleep
renvoie une valeur spéciale : Invisible NULL
.
Utilisation d’arguments par défaut
Un autre avantage de l’évaluation paresseuse est que vous pouvez définir des arguments par défaut mutuellement récursif ce qui permet d’implémenter des interfaces adaptatives. Par exemple, voici une fonction (voir ici) qui calcule la représentation d’un point en coordonnées polaires et cartésiennes. Vous pouvez spécifier le point dans l’un ou l’autre des systèmes de coordonnées.
polar <- function(x = r * cos(theta), y = r * sin(theta), r = sqrt(x*x + y*y), theta = atan2(y, x)) return(c(x, y, r, theta)) ## Calcule la paire (x,y) polar(1,1) ## Calcule la paire (r, theta) polar(r=sqrt(2), theta=pi/4) ## Attention, l'appel déclenche une erreur si le calcul des coordonnées est impossible. polar(r=1)
[1] 1.0000000 1.0000000 1.4142136 0.7853982 [1] 1.0000000 1.0000000 1.4142136 0.7853982 Error in atan2(y, x) : la promesse est déjà en cours d'évaluation : référence récursive d'argument par défaut ou problème antérieur ?
C’est donc un mécanisme puissant, mais dont il faut se méfier. En pratique, la définition des arguments par défaut doit rester simple.
9. Fonction « Lambda » HARD HOME
- Définissez en R la fonction \(f(x)=\frac{sin(x)}{\sqrt{x^4+1}}\).
- Calculez une valeur approchée de la dérivée seconde \(f^{\prime\prime}(\sqrt{2})\). Réponse : approximativement 0.036…
Si cet exercice vous passe par-dessus la tete, ce n’est pas si grave que cela. Vous y reviendrez plus tard ! simple question de maturité…