Parcours
/
Go
Go
/
Exercices
/
Des logs, des logs, des logs !
Des logs, des logs, des logs !

Des logs, des logs, des logs !

Exercice d'apprentissage

Introduction

Le type rune en Go est un alias de int32. Étant donné ce type int32 sous-jacent, le type rune contient une valeur entière signée sur 32 bits. Cependant, contrairement à un type int32, la valeur entière stockée dans un type rune représente un seul caractère Unicode.

Unicode et points de code Unicode

Unicode est un sur-ensemble d'ASCII qui représente les caractères en attribuant un nombre unique à chaque caractère. Ce nombre unique s'appelle un point de code Unicode. Unicode vise à représenter tous les caractères du monde, notamment les différents alphabets, les chiffres, les symboles et même les emoji, sous forme de points de code Unicode.

En Go, le type rune représente un seul point de code Unicode.

Le tableau suivant contient des exemples de caractères Unicode, avec leur point de code Unicode et leur valeur décimale :

Caractère Unicode Point de code Unicode Valeur décimale
0 U+0030 48
A U+0041 65
a U+0061 97
¿ U+00BF 191
π U+03C0 960
🧠 U+1F9E0 129504

UTF-8

UTF-8 est un encodage de caractères à largeur variable, utilisé pour encoder chaque point de code Unicode sur 1, 2, 3 ou 4 octets. Comme un point de code Unicode peut être encodé sur 4 octets au maximum, le type rune doit pouvoir contenir jusqu'à 4 octets de données. C'est pourquoi le type rune est un alias de int32 : un type int32 est capable de contenir jusqu'à 4 octets de données.

Les fichiers de code source Go sont encodés en UTF-8.

Utilise les runes

Les variables de type rune se déclarent en plaçant un caractère entre guillemets simples :

myRune := '¿'

Comme rune n'est qu'un alias de int32, afficher le type d'une rune donne int32 :

myRune := '¿'
fmt.Printf("myRune type: %T\n", myRune)
// Output: myRune type: int32

De même, afficher la valeur d'une rune donne sa valeur entière (décimale) :

myRune := '¿'
fmt.Printf("myRune value: %v\n", myRune)
// Output: myRune value: 191

Pour afficher le caractère Unicode représenté par la rune, utilise le verbe de formatage %c :

myRune := '¿'
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿

Pour afficher le point de code Unicode représenté par la rune, utilise le verbe de formatage %U :

myRune := '¿'
fmt.Printf("myRune Unicode code point: %U\n", myRune)
// Output: myRune Unicode code point: U+00BF

Runes et strings

En Go, les strings sont encodées en UTF-8, ce qui signifie qu'elles contiennent des caractères Unicode. Les caractères d'une string sont stockés et encodés sur 1, 2, 3 ou 4 octets, selon le caractère Unicode qu'ils représentent.

En Go, on utilise des slices pour représenter des séquences, et on peut parcourir ces slices avec range. Quand on parcourt une string, Go la convertit en une série de runes, dont chacune fait 4 octets (pour rappel, le type rune est un alias d'int32 !)

Même si une string n'est qu'une slice d'octets, le mot-clé range parcourt les runes d'une string, et non ses octets.

Dans cet exemple, la variable index représente l'indice de départ de la séquence d'octets de la rune courante, et la variable char représente la rune courante :

myString := "❗hello"
for index, char := range myString {
  fmt.Printf("Index: %d\tCharacter: %c\t\tCode Point: %U\n", index, char, char)
}
// Output:
// Index: 0	Character: ❗		Code Point: U+2757
// Index: 3	Character: h		Code Point: U+0068
// Index: 4	Character: e		Code Point: U+0065
// Index: 5	Character: l		Code Point: U+006C
// Index: 6	Character: l		Code Point: U+006C
// Index: 7	Character: o		Code Point: U+006F

Comme les runes peuvent être stockées sur 1, 2, 3 ou 4 octets, la longueur d'une string n'est pas toujours égale au nombre de caractères qu'elle contient. Utilise la fonction prédéfinie len pour obtenir la longueur d'une string en octets, et la fonction utf8.RuneCountInString pour obtenir le nombre de runes d'une string :

import "unicode/utf8"

myString := "❗hello"
stringLength := len(myString)
numberOfRunes := utf8.RuneCountInString(myString)

fmt.Printf("myString - Length: %d - Runes: %d\n", stringLength, numberOfRunes)
// Output: myString - Length: 8 - Runes: 6

Instructions

Tu as pour mission de créer une bibliothèque de logs pour t'aider à gérer les logs de ton organisation. Cette bibliothèque permettra aux utilisateurs d'identifier l'application qui a émis un log donné, de corriger des logs corrompus, et de déterminer si une ligne de log donnée respecte une certaine limite de caractères.

1. Identifie l'application qui a émis un log

Les logs proviennent de plusieurs applications qui utilisent chacune leur propre format de log propriétaire. Il faut identifier l'application qui émet un log avant de pouvoir le stocker dans un système d'agrégation de logs.

Implémente la fonction Application qui prend une ligne de log et renvoie l'application qui a émis cette ligne de log.

Pour identifier l'application qui a émis une ligne de log donnée, recherche dans la ligne de log un caractère précisé dans le tableau suivant :

Application Caractère Point de code Unicode
recommendation ❗ U+2757
search 🔍 U+1F50D
weather ☀ U+2600

Si une ligne de log ne contient aucun des caractères du tableau ci-dessus, renvoie default à l'appelant. Si une ligne de log contient plusieurs caractères du tableau ci-dessus, renvoie l'application correspondant au premier caractère trouvé dans la ligne de log, en partant de la gauche vers la droite.

Application("❗ recommended search product 🔍")
// => recommendation

2. Corrige les logs corrompus

À cause d'un bug rare mais persistant dans l'infrastructure de journalisation, certains caractères des logs peuvent se retrouver corrompus. Après avoir passé du temps à identifier les caractères corrompus et leur valeur d'origine, tu décides de mettre à jour la bibliothèque de logs pour faciliter la correction des logs corrompus.

Implémente la fonction Replace qui prend une ligne de log, un caractère corrompu et la valeur d'origine, et qui renvoie une ligne de log modifiée dans laquelle toutes les occurrences du caractère corrompu sont remplacées par la valeur d'origine.

log := "please replace '👎' with '👍'"

Replace(log, '👎', '👍')
// => please replace '👍' with '👍'"

3. Détermine si un log peut être affiché

Les systèmes chargés d'afficher les logs imposent une limite au nombre de caractères pouvant être affichés par ligne de log. C'est pourquoi les utilisateurs demandent que cette bibliothèque inclue une fonction utilitaire pour déterminer si une ligne de log respecte ou non une limite de caractères donnée.

Implémente la fonction WithinLimit qui prend une ligne de log et une limite de caractères, et qui indique si la ligne de log respecte ou non cette limite.

WithinLimit("hello❗", 6)
// => true
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Go Exercism

Prêt à commencer Des logs, des logs, des logs ! ?

Inscris-toi sur Exercism pour apprendre et maîtriser Go avec 34 concepts165 exercices, et un vrai mentorat humain, le tout gratuitement.