Ce document est à utiliser comme une table de référence, qui peut être consultée ponctuellement ou servir de support à des révisions.
Généralités
Opérateurs
+ |
Addition |
1+1 |
- |
Soustraction |
1-1 |
/ |
Division |
1/1 |
* |
Multiplication |
1*1 |
^ |
Puissance |
10^2 |
Symboles
<- |
Assignation à une variable |
animaux <- c("chien", "chat") |
() |
Éxécution d’une fonction. Contient souvent des arguments |
c(1, 2, 3) |
[] |
Sélection d’un sous-ensemble dans une variable |
animaux[1] |
$ |
Sélection d’une variable dans un data.frame |
bdd$genre |
# |
Commentaire : ignorer ce qui suit |
# Test |
= |
Assignation d’un argument dans une fonction |
mean(x, na.rm = TRUE) |
Exemples :
# Cette ligne n'est pas interprétée par R
c("chien", "chat") # Fonction
[1] "chien" "chat"
animaux <- c("chien", "chat") # Assignation dans la variable animaux
animaux[1] # Sélection du premier élément
[1] "chien"
# En revanche :
animaux(1)
Erreur : impossible de trouver la fonction "animaux"
Raccourcis clavier essentiels
Ctrl+Entrée |
Exécuter la ligne où se trouve le curseur |
Ctrl+Entrée |
Exécuter les lignes sélectionnées |
Ctrl+L |
Effacer la console |
Shift |
Obtenir les suggesions de complétion |
Ctrl+S |
Sauvegarder le fichier |
R est sensible à la casse
Attention aux appels de fonction :
factor(c("chien", "chat"))
[1] chien chat
Levels: chat chien
# Mais...
Factor(c("chien", "chat"))
Erreur : impossible de trouver la fonction "Factor"
Et aux appels de variable :
animaux <- c("chien", "chat")
animaux
[1] "chien" "chat"
# Mais...
Animaux
Erreur : objet 'Animaux' introuvable
Structures de données
Types de données
Pour identifier un type de données, on peut utiliser la fonction typeof().
1234 |
Un nombre (“double”) |
1 |
"" ou '' |
Chaîne de caractères |
"animaux" |
NA |
Absence de données |
NA |
Résultats de la fonction typeof() :
typeof(1)
[1] "double"
typeof("1")
[1] "character"
typeof(NA)
[1] "logical"
Le type de données doit être bien compris sous peine d’erreurs !
1+1
[1] 2
# Mais...
1+"1"
Error in 1 + "1" : argument non numérique pour un opérateur binaire
Structures de données
Pour identifier une structure de données, on peut utiliser la fonction str().
| vector |
c() |
Variable |
| factor |
factor() |
Variable qualitative |
| data.frame |
data.frame() |
Base de données |
Vecteur
| vector |
Variable |
| Suite de données de même type |
Série de données homogènes |
c(1,2,3,4) # Équivalent à une variable quantitative
[1] 1 2 3 4
str(c(1,2,3,4))
num [1:4] 1 2 3 4
c("homme", "femme", "homme") # Série de données textuelles
[1] "homme" "femme" "homme"
str(c("homme", "femme", "homme"))
chr [1:3] "homme" "femme" "homme"
Manipulation des vecteurs :
genre <- c("homme", "femme", "homme")
genre[1]
[1] "homme"
genre[1:2]
[1] "homme" "femme"
genre[c(1, 3)]
[1] "homme" "homme"
Facteur
Les facteurs sont un type particulier de vecteurs dans R, de la même façon que les variables qualitatives sont un type de variable particulier dans R.
| vector |
Variable qualitative |
| levels |
Modalités de la variable |
genre <- c("homme", "femme", "homme")
# Transformation en facteur
genre.f <- factor(genre)
str(genre.f)
Factor w/ 2 levels "femme","homme": 2 1 2
genre.f
[1] homme femme homme
Levels: femme homme
Pour voir les modalités (levels) :
levels(genre.f)
Data.frame
C’est l’équivalent d’une base de données en statistiques : une série de variables sur les mêmes individus.
Pour sélectionner une variable en particulier :
bdd$variable1
Les fonctions
Les fonctions sont un concept central des langages de programmation… et donc de R !
Anatomie d’une fonction
Toujours sous la forme :
nomDeLaFonction(arguments)
nomDeLaFonction : nom de la fonction à appeler
() : les parenthèses signifient qu’on demande à R d’éxécuter la fonction.
arguments : une liste d’arguments séparés par des virgules et une espace. Le nombre d’arguments dépend des fonctions.
Les arguments
Fonction qui n’a besoin d’aucun argument :
getwd()
La fonction c() accepte un nombre illimité d’arguments :
c(1, 2, 3, 4)
Certaines fonctions ont des arguments obligatoires :
mean()
Mais :
notes <- c(10, 20)
mean(notes)
Certaines fonctions prennent des arguments falcutatifs, qui peuvent être nommés. Dans ce cas, le nom de l’argument est suivi d’un signe = puis de sa valeur.
notes <- c(10, 20, NA)
mean(notes, na.rm = TRUE)
Fonctions imbriquées
Il est bien sûr possible d’imbriquer nos fonctions :
mean(c(c(10, 20), NA), na.rm = TRUE)
Ce qui est identique à :
notes <- c(10, 20)
notes2 <- c(notes, NA)
mean(notes2, na.rm = TRUE)
Pour comprendre les fonctions imbriquées, il faut donc procéder par étapes, en partant de l’intérieur des parenthèses pour aller vers l’extérieur.
Les variables
Dans un langage de programmation, les variables permettent d’atteindre un niveau d’abstraction supplémentaire, en attribuant un nom à un objet pour le réutiliser par la suite. Elles améliorent également la lisibilité du programme.
variable <- "coucou"
variable
[1] "coucou"
Attention aux erreurs de notation !
variable
[1] "coucou"
# Mais...
"variable"
[1] "variable"
LS0tCnRpdGxlOiAiUiBDaGVhdHNoZWV0IHBvdXIgZMOpYnV0YW50cyIKZGF0ZTogIkTDqWNlbWJyZSAyMDE2IgphdXRob3I6ICJHYWJyaWVsIEFsY2FyYXMiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazogCiAgICB0b2M6IHllcwotLS0KCkNlIGRvY3VtZW50IGVzdCDDoCB1dGlsaXNlciBjb21tZSB1bmUgdGFibGUgZGUgcsOpZsOpcmVuY2UsIHF1aSBwZXV0IMOqdHJlIGNvbnN1bHTDqWUgcG9uY3R1ZWxsZW1lbnQgb3Ugc2VydmlyIGRlIHN1cHBvcnQgw6AgZGVzIHLDqXZpc2lvbnMuCgojIEfDqW7DqXJhbGl0w6lzCgojIyBPcMOpcmF0ZXVycwoKfCBPcMOpcmF0ZXVyIHwgUsO0bGUgfCBFeGVtcGxlIHwKfCAtLS0gfCAtLS0gfCAtLS0gCnwgYCtgIHwgQWRkaXRpb24gfCBgMSsxYCB8CnwgYC1gIHwgU291c3RyYWN0aW9uIHwgYDEtMWAgfAp8IGAvYCB8IERpdmlzaW9uIHwgYDEvMWAgfAp8IGAqYCB8IE11bHRpcGxpY2F0aW9uIHwgYDEqMWAgfAp8IGBeYCB8IFB1aXNzYW5jZSB8IGAxMF4yYCB8CgojIyBTeW1ib2xlcwoKfCBTeW1ib2xlIHwgUsO0bGUgfCBFeGVtcGxlIHwKfCAtLS0gfCAtLS0gfCAtLS0gCnwgYDwtYCB8IEFzc2lnbmF0aW9uIMOgIHVuZSB2YXJpYWJsZSB8IGBhbmltYXV4IDwtIGMoImNoaWVuIiwgImNoYXQiKWAgfAp8IGAoKWAgfCDDiXjDqWN1dGlvbiBkJ3VuZSBmb25jdGlvbi4gQ29udGllbnQgc291dmVudCBkZXMgYXJndW1lbnRzIHwgYGMoMSwgMiwgMylgIHwKfCBgW11gIHwgU8OpbGVjdGlvbiBkJ3VuIHNvdXMtZW5zZW1ibGUgZGFucyB1bmUgdmFyaWFibGUgfCBgYW5pbWF1eFsxXWAgfAp8IGAkYCB8IFPDqWxlY3Rpb24gZCd1bmUgdmFyaWFibGUgZGFucyB1biBkYXRhLmZyYW1lIHwgYGJkZCRnZW5yZWAgfAp8IGAjYCB8IENvbW1lbnRhaXJlIDogaWdub3JlciBjZSBxdWkgc3VpdCB8IGAjIFRlc3RgIHwKfCBgPWAgfCBBc3NpZ25hdGlvbiBkJ3VuIGFyZ3VtZW50IGRhbnMgdW5lIGZvbmN0aW9uIHwgYG1lYW4oeCwgbmEucm0gPSBUUlVFKWAgfAoKCioqRXhlbXBsZXMgOioqCgpgYGB7cn0KIyBDZXR0ZSBsaWduZSBuJ2VzdCBwYXMgaW50ZXJwcsOpdMOpZSBwYXIgUgpjKCJjaGllbiIsICJjaGF0IikgIyBGb25jdGlvbgphbmltYXV4IDwtIGMoImNoaWVuIiwgImNoYXQiKSAjIEFzc2lnbmF0aW9uIGRhbnMgbGEgdmFyaWFibGUgYW5pbWF1eAphbmltYXV4WzFdICMgU8OpbGVjdGlvbiBkdSBwcmVtaWVyIMOpbMOpbWVudAoKIyBFbiByZXZhbmNoZSA6CmFuaW1hdXgoMSkKYGBgCgojIyBSYWNjb3VyY2lzIGNsYXZpZXIgZXNzZW50aWVscwoKfCBUb3VjaGVzIHwgRm9uY3Rpb24gfAp8IC0tLS0gfCAtLS0tIHwKfCBgQ3RybCtFbnRyw6llYCB8IEV4w6ljdXRlciBsYSBsaWduZSBvw7kgc2UgdHJvdXZlIGxlIGN1cnNldXIgfAp8IGBDdHJsK0VudHLDqWVgIHwgRXjDqWN1dGVyIGxlcyBsaWduZXMgc8OpbGVjdGlvbm7DqWVzIHwKfCBgQ3RybCtMYCB8IEVmZmFjZXIgbGEgY29uc29sZSB8CnwgYFNoaWZ0YCB8IE9idGVuaXIgbGVzIHN1Z2dlc2lvbnMgZGUgY29tcGzDqXRpb24gfAp8IGBDdHJsK1NgIHwgU2F1dmVnYXJkZXIgbGUgZmljaGllciB8CgojIyBSIGVzdCBzZW5zaWJsZSDDoCBsYSBjYXNzZQoKQXR0ZW50aW9uIGF1eCBhcHBlbHMgZGUgZm9uY3Rpb24gOgoKYGBge3J9CmZhY3RvcihjKCJjaGllbiIsICJjaGF0IikpCgojIE1haXMuLi4KRmFjdG9yKGMoImNoaWVuIiwgImNoYXQiKSkKYGBgCgpFdCBhdXggYXBwZWxzIGRlIHZhcmlhYmxlIDoKCmBgYHtyfQphbmltYXV4IDwtIGMoImNoaWVuIiwgImNoYXQiKQphbmltYXV4CgojIE1haXMuLi4KQW5pbWF1eApgYGAKCiMgU3RydWN0dXJlcyBkZSBkb25uw6llcwoKIyMgVHlwZXMgZGUgZG9ubsOpZXMKClBvdXIgaWRlbnRpZmllciB1biB0eXBlIGRlIGRvbm7DqWVzLCBvbiBwZXV0IHV0aWxpc2VyIGxhIGZvbmN0aW9uIGB0eXBlb2YoKWAuCgp8IE5vdGF0aW9uIHwgUsO0bGUgfCBFeGVtcGxlIHwKfCAtLS0gfCAtLS0gfCAtLS0gCnwgYDEyMzRgIHwgVW4gbm9tYnJlICgiZG91YmxlIikgfCBgMWAgfAp8IGAiImAgb3UgYCcnYCB8IENoYcOubmUgZGUgY2FyYWN0w6hyZXMgfCBgImFuaW1hdXgiYCB8CnwgYE5BYCB8IEFic2VuY2UgZGUgZG9ubsOpZXMgfCBgTkFgIHwKClLDqXN1bHRhdHMgZGUgbGEgZm9uY3Rpb24gYHR5cGVvZigpYCA6CgpgYGB7cn0KdHlwZW9mKDEpCnR5cGVvZigiMSIpCnR5cGVvZihOQSkKYGBgCgoqKkxlIHR5cGUgZGUgZG9ubsOpZXMgZG9pdCDDqnRyZSBiaWVuIGNvbXByaXMgc291cyBwZWluZSBkJ2VycmV1cnMgISoqCgpgYGB7cn0KMSsxCiMgTWFpcy4uLgoxKyIxIgpgYGAKCiMjIFN0cnVjdHVyZXMgZGUgZG9ubsOpZXMKClBvdXIgaWRlbnRpZmllciB1bmUgc3RydWN0dXJlIGRlIGRvbm7DqWVzLCBvbiBwZXV0IHV0aWxpc2VyIGxhIGZvbmN0aW9uIGBzdHIoKWAuCgp8IE5vbSB8IEZvbmN0aW9uIHwgQ29uY2VwdCDDqXF1aXZhbGVudCBlbiBzdGF0aXN0aXF1ZXMgfAp8IC0tLSB8IC0tLSB8IC0tLSAKfCB2ZWN0b3IgfCBgYygpYCB8IFZhcmlhYmxlIHwKfCBmYWN0b3IgfCBgZmFjdG9yKClgIHwgVmFyaWFibGUgcXVhbGl0YXRpdmUgfAp8IGRhdGEuZnJhbWUgfCBgZGF0YS5mcmFtZSgpYCB8IEJhc2UgZGUgZG9ubsOpZXMgfAoKIyMjIFZlY3RldXIKCnwgRGFucyBSIHwgRW4gc3RhdGlzdGlxdWVzIHwKfCAtLS0gfCAtLS0gfAp8IHZlY3RvciB8IFZhcmlhYmxlIHwKfCBTdWl0ZSBkZSBkb25uw6llcyBkZSBtw6ptZSB0eXBlIHwgU8OpcmllIGRlIGRvbm7DqWVzIGhvbW9nw6huZXMgfAoKYGBge3J9CmMoMSwyLDMsNCkgIyDDiXF1aXZhbGVudCDDoCB1bmUgdmFyaWFibGUgcXVhbnRpdGF0aXZlCnN0cihjKDEsMiwzLDQpKQpjKCJob21tZSIsICJmZW1tZSIsICJob21tZSIpICMgU8OpcmllIGRlIGRvbm7DqWVzIHRleHR1ZWxsZXMKc3RyKGMoImhvbW1lIiwgImZlbW1lIiwgImhvbW1lIikpCmBgYAoKKipNYW5pcHVsYXRpb24gZGVzIHZlY3RldXJzIDoqKgoKYGBge3J9CmdlbnJlIDwtIGMoImhvbW1lIiwgImZlbW1lIiwgImhvbW1lIikKZ2VucmVbMV0KZ2VucmVbMToyXQpnZW5yZVtjKDEsIDMpXQpgYGAKCiMjIyBGYWN0ZXVyCgpMZXMgZmFjdGV1cnMgc29udCB1biB0eXBlIHBhcnRpY3VsaWVyIGRlIHZlY3RldXJzIGRhbnMgUiwgZGUgbGEgbcOqbWUgZmHDp29uIHF1ZSBsZXMgdmFyaWFibGVzIHF1YWxpdGF0aXZlcyBzb250IHVuIHR5cGUgZGUgdmFyaWFibGUgcGFydGljdWxpZXIgZGFucyBSLgoKfCBEYW5zIFIgfCBFbiBzdGF0aXN0aXF1ZXMgfAp8IC0tLSB8IC0tLSB8CnwgdmVjdG9yIHwgVmFyaWFibGUgcXVhbGl0YXRpdmUgfAp8IGxldmVscyB8IE1vZGFsaXTDqXMgZGUgbGEgdmFyaWFibGUgfAoKYGBge3J9CmdlbnJlIDwtIGMoImhvbW1lIiwgImZlbW1lIiwgImhvbW1lIikKCiMgVHJhbnNmb3JtYXRpb24gZW4gZmFjdGV1cgpnZW5yZS5mIDwtIGZhY3RvcihnZW5yZSkKc3RyKGdlbnJlLmYpCmdlbnJlLmYKYGBgCgpQb3VyIHZvaXIgbGVzIG1vZGFsaXTDqXMgKGBsZXZlbHNgKSA6CgpgYGB7cn0KbGV2ZWxzKGdlbnJlLmYpCmBgYAoKIyMjIERhdGEuZnJhbWUKCkMnZXN0IGwnw6lxdWl2YWxlbnQgZCd1bmUgYmFzZSBkZSBkb25uw6llcyBlbiBzdGF0aXN0aXF1ZXMgOiB1bmUgc8OpcmllIGRlIHZhcmlhYmxlcyBzdXIgbGVzIG3Dqm1lcyBpbmRpdmlkdXMuCgpQb3VyIHPDqWxlY3Rpb25uZXIgdW5lIHZhcmlhYmxlIGVuIHBhcnRpY3VsaWVyIDoKCmBgYHtyLCBldmFsPUZBTFNFfQpiZGQkdmFyaWFibGUxCmBgYAoKIyBMZXMgZm9uY3Rpb25zCgpMZXMgZm9uY3Rpb25zIHNvbnQgdW4gY29uY2VwdCBjZW50cmFsIGRlcyBsYW5nYWdlcyBkZSBwcm9ncmFtbWF0aW9uLi4uIGV0IGRvbmMgZGUgUiAhCgojIyBBbmF0b21pZSBkJ3VuZSBmb25jdGlvbgoKVG91am91cnMgc291cyBsYSBmb3JtZSA6CgpgYGAKbm9tRGVMYUZvbmN0aW9uKGFyZ3VtZW50cykKYGBgCgorIGBub21EZUxhRm9uY3Rpb25gIDogKipub20gZGUgbGEgZm9uY3Rpb24gw6AgYXBwZWxlcioqCisgYCgpYCA6IGxlcyBwYXJlbnRow6hzZXMgc2lnbmlmaWVudCBxdScqKm9uIGRlbWFuZGUgw6AgUiBkJ8OpeMOpY3V0ZXIgbGEgZm9uY3Rpb24qKi4KKyBgYXJndW1lbnRzYCA6IHVuZSBsaXN0ZSBkJ2FyZ3VtZW50cyBzw6lwYXLDqXMgcGFyIGRlcyB2aXJndWxlcyBldCB1bmUgZXNwYWNlLiBMZSBub21icmUgZCdhcmd1bWVudHMgZMOpcGVuZCBkZXMgZm9uY3Rpb25zLgoKIyMjIExlcyBhcmd1bWVudHMKCkZvbmN0aW9uIHF1aSBuJ2EgYmVzb2luIGQnYXVjdW4gYXJndW1lbnQgOgoKYGBge3J9CmdldHdkKCkKYGBgCgpMYSBmb25jdGlvbiBgYygpYCBhY2NlcHRlIHVuIG5vbWJyZSBpbGxpbWl0w6kgZCdhcmd1bWVudHMgOgoKYGBge3J9CmMoMSwgMiwgMywgNCkKYGBgCgpDZXJ0YWluZXMgZm9uY3Rpb25zIG9udCBkZXMgYXJndW1lbnRzIG9ibGlnYXRvaXJlcyA6CgpgYGB7cn0KbWVhbigpCmBgYAoKTWFpcyA6CgpgYGB7cn0Kbm90ZXMgPC0gYygxMCwgMjApCm1lYW4obm90ZXMpCmBgYAoKQ2VydGFpbmVzIGZvbmN0aW9ucyBwcmVubmVudCBkZXMgYXJndW1lbnRzIGZhbGN1dGF0aWZzLCBxdWkgcGV1dmVudCDDqnRyZSBub21tw6lzLiBEYW5zIGNlIGNhcywgbGUgbm9tIGRlIGwnYXJndW1lbnQgZXN0IHN1aXZpIGQndW4gc2lnbmUgYD1gIHB1aXMgZGUgc2EgdmFsZXVyLgoKYGBge3J9Cm5vdGVzIDwtIGMoMTAsIDIwLCBOQSkKbWVhbihub3RlcywgbmEucm0gPSBUUlVFKQpgYGAKCiMjIEZvbmN0aW9ucyBpbWJyaXF1w6llcwoKSWwgZXN0IGJpZW4gc8O7ciBwb3NzaWJsZSBkJ2ltYnJpcXVlciBub3MgZm9uY3Rpb25zIDoKCmBgYHtyfQptZWFuKGMoYygxMCwgMjApLCBOQSksIG5hLnJtID0gVFJVRSkKYGBgCgpDZSBxdWkgZXN0IGlkZW50aXF1ZSDDoCA6IAoKYGBge3J9Cm5vdGVzIDwtIGMoMTAsIDIwKQpub3RlczIgPC0gYyhub3RlcywgTkEpCm1lYW4obm90ZXMyLCBuYS5ybSA9IFRSVUUpCmBgYAoKUG91ciBjb21wcmVuZHJlIGxlcyBmb25jdGlvbnMgaW1icmlxdcOpZXMsIGlsIGZhdXQgZG9uYyBwcm9jw6lkZXIgcGFyIMOpdGFwZXMsIGVuIHBhcnRhbnQgZGUgbCdpbnTDqXJpZXVyIGRlcyBwYXJlbnRow6hzZXMgcG91ciBhbGxlciB2ZXJzIGwnZXh0w6lyaWV1ci4KCiMgTGVzIHZhcmlhYmxlcwoKRGFucyB1biBsYW5nYWdlIGRlIHByb2dyYW1tYXRpb24sIGxlcyB2YXJpYWJsZXMgcGVybWV0dGVudCBkJ2F0dGVpbmRyZSB1biBuaXZlYXUgZCdhYnN0cmFjdGlvbiBzdXBwbMOpbWVudGFpcmUsIGVuIGF0dHJpYnVhbnQgdW4gbm9tIMOgIHVuIG9iamV0IHBvdXIgbGUgcsOpdXRpbGlzZXIgcGFyIGxhIHN1aXRlLiBFbGxlcyBhbcOpbGlvcmVudCDDqWdhbGVtZW50IGxhIGxpc2liaWxpdMOpIGR1IHByb2dyYW1tZS4KCmBgYHtyfQp2YXJpYWJsZSA8LSAiY291Y291Igp2YXJpYWJsZQpgYGAKCkF0dGVudGlvbiBhdXggZXJyZXVycyBkZSBub3RhdGlvbiAhCgpgYGB7cn0KdmFyaWFibGUKIyBNYWlzLi4uCiJ2YXJpYWJsZSIKYGBgCgojIyBWYXJpYWJsZSBpbmZvcm1hdGlxdWUgLyB2YXJpYWJsZSBzdGF0aXN0aXF1ZQoKKipBdHRlbnRpb24gOioqIGxlIGNvbmNlcHQgZGUgdmFyaWFibGUgKmluZm9ybWF0aXF1ZSogZXN0IHRyw6hzIGRpZmbDqXJlbnQgZGUgdmFyaWFibGUgKnN0YXRpc3RpcXVlKi4gRW4gZWZmZXQsIHVuZSB2YXJpYWJsZSBpbmZvcm1hdGlxdWUgcGV1dCBzdG9ja2VyIG4naW1wb3J0ZSBxdWVsIHR5cGUgZGUgZG9ubsOpZXMsIGFsb3JzIHF1J3VuZSB2YXJpYWJsZSBzdGF0aXN0aXF1ZSBjb3JyZXNwb25kIMOgIHVuZSBzw6lyaWUgZGUgZG9ubsOpZXMgaG9tb2fDqG5lcyBjb2xsZWN0w6llcyBzdXIgZGVzIGluZGl2aWR1cy4KCkxlcyBkZXV4IGNvbmNlcHRzIHNlIHJlY291cGVudCBwYXJmb2lzIDoKCmBgYHtyfQpub3RlcyA8LSBjKDEwLCAyMCwgMTYpCmBgYAoKSWNpLCBsYSB2YXJpYWJsZSBgbm90ZXNgIHBldXQgY29ycmVzcG9uZHJlIMOgIHVuZSB2YXJpYWJsZSBzdGF0aXN0aXF1ZS4KCkVuIHJldmFuY2hlIDoKCmBgYHtyfQp0ZXN0IDwtIG1lYW4obm90ZXMpCmBgYAoKRGFucyBjZSBjYXMsIGxhIHZhcmlhYmxlIGluZm9ybWF0aXF1ZSBgdGVzdGAgY29udGllbnQgbGEgbW95ZW5uZSBkZXMgbm90ZXMsIGNlIHF1aSBuJ2VzdCBwYXMgw6lxdWl2YWxlbnQgw6AgdW5lIHZhcmlhYmxlIGF1IHNlbnMgc3RhdGlzdGlxdWUu