Les exercices d'entraînement sont des exercices conçus pour permettre aux apprenants de résoudre un problème quelconque, dans le but de mettre en pratique les concepts qu'ils ont appris jusqu'ici.
Tu veux ajouter ton premier exercice d'entraînement à un parcours ? Consulte la documentation sur l'ajout d'un exercice d'entraînement ou regarde notre vidéo explicative 👇
Tu peux rapidement générer la structure d'un nouvel exercice d'entraînement en exécutant les commandes suivantes depuis le répertoire racine du parcours :
bin/fetch-configlet
bin/configlet create --practice-exercise <slug>
Pour plus d'informations, consulte la documentation de configlet create
Les métadonnées d'un exercice d'entraînement sont définies dans la clé exercises.practice du fichier config.json. Elles définissent l'UUID et le slug de l'exercice, entre autres.
{
"exercises": {
"practice": [
{
"uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
"slug": "leap",
"name": "Leap",
"practices": ["if-statements", "numbers", "operator-precedence"],
"prerequisites": ["if-statements", "numbers"],
"difficulty": 1
}
]
}
}
practicesLa clé practices doit lister les slugs des concepts que cet exercice d'entraînement permet activement à un apprenant de travailler.
strings). Dans ce cas, nous te recommandons de choisir quelques bons exercices qui amènent à réfléchir à ces concepts de manière intéressante. Par exemple, des exercices qui nécessitent de l'UTF-8, de la concaténation de strings, du parcours de caractères, etc., sont tous de bons exemples.prerequisitesLa clé prerequisites liste les concepts qu'un apprenant doit avoir terminés pour accéder à cet exercice d'entraînement.
strings, optional-params, implicit-return.loops ou recursion), le mainteneur doit choisir l'approche avec laquelle il souhaite déverrouiller l'exercice, en tenant compte du cheminement de l'apprenant dans le parcours. Pour reprendre l'exemple des boucles et de la récursion, il peut juger que cet exercice est un bon entraînement précoce aux loops, ou préférer le garder pour plus tard afin d'enseigner la récursion. Il peut aussi s'appuyer sur un analyseur pour inviter l'apprenant à essayer une autre approche : « Beau travail, tu as résolu cet exercice avec des boucles. Tu peux aussi essayer de le résoudre avec de la récursion. »Chaque exercice d'entraînement a son propre répertoire dans le répertoire exercises/practice du parcours. Le nom du répertoire de l'exercice d'entraînement doit correspondre à la propriété slug de l'exercice, telle que définie dans le fichier config.json.
Un exercice d'entraînement comporte quatre types de fichiers :
Ces fichiers sont présentés à l'apprenant pour l'aider à comprendre l'exercice.
.docs/introduction.md : présente le cadre et le contexte de l'exercice (facultatif).docs/introduction.append.md : texte d'introduction supplémentaire à ajouter après l'introduction existante (facultatif).docs/instructions.md : fournit les instructions de l'exercice (obligatoire).docs/instructions.append.md : texte d'instructions supplémentaire à ajouter après les instructions existantes (facultatif).docs/hints.md : fournit des indices pour aider l'apprenant à se débloquer dans l'exercice (facultatif)Ces fichiers ne sont pas présentés à l'apprenant, mais servent à définir les métadonnées de l'exercice.
.meta/config.json : contient des méta-informations sur l'exercice (obligatoire).meta/design.md : décrit la conception de l'exercice (facultatif).meta/tests.toml : contient des informations sur les tests implémentés (facultatif)Ces fichiers décrivent les approches de l'exercice.
.approaches/introduction.md : introduction aux approches les plus courantes pour l'exercice (facultatif).approaches/config.json : métadonnées des approches (facultatif).approaches/<approach-slug>/content.md : description de l'approche (facultatif).approaches/<approach-slug>/snippet.txt : extrait illustrant l'approche (facultatif)Ces fichiers décrivent les articles de l'exercice.
.articles/config.json : métadonnées des articles (facultatif).articles/<article-slug>/content.md : description de l'article (facultatif).articles/<article-slug>/snippet.md : extrait illustrant l'article (facultatif)Les fichiers propres au langage, comme les fichiers d'implémentation et de test. Leurs noms dépendent du parcours.
exercises
└── practice
└── isogram
├── .approaches
| ├── for-loop
| | ├── content.md
| | └── snippet.txt
| ├── config.json
| └── introduction.md
├── .articles
| ├── performance
| | ├── content.md
| | └── snippet.md
| └── config.json
├── .docs
| ├── introduction.md
| ├── instructions.md
| └── hints.md
├── .meta
| ├── config.json
| ├── design.md
| ├── tests.toml
| └── Example.cs (implémentation d'exemple)
├── Isogram.cs (implémentation squelette)
└── IsogramTests.cs (tests)
.docs/introduction.md
Objectif : présenter à l'apprenant le cadre et le contexte de l'exercice.
Présence : obligatoire si l'exercice implémente un exercice de Problem Specifications avec un fichier introduction.md
Si l'exercice implémente un exercice de Problem Specifications, le contenu de ce fichier doit correspondre au fichier introduction.md de cet exercice de Problem Specifications. configlet dispose d'une fonctionnalité pour synchroniser automatiquement le contenu de ce fichier.
Si l'exercice n'est pas basé sur un exercice de Problem Specifications, tiens compte des points suivants :
Nous attachons une grande importance à ce que le contenu d'Exercism soit sûr pour tout le monde, et nous choisissons donc souvent la prudence lorsqu'il s'agit de décider si une histoire est appropriée ou non. Nous faisons attention à ce que nous fusionnons, mais nous savons qu'il est difficile d'avoir conscience de ce qui peut être perçu comme problématique ; c'est pourquoi nous partirons toujours du principe que tu agis de bonne foi et ferons de notre mieux pour repérer les problèmes lors de la relecture, de manière non conflictuelle. Si tu veux vérifier une histoire avec nous, mentionne @exercism/leadership et nous l'examinerons ensemble. Voici quelques points pour te guider :
# Introduction
Bob is a lackadaisical teenager. In conversation, his responses are very limited.
.docs/introduction.append.md
Objectif : texte d'introduction supplémentaire à ajouter après l'introduction existante.
Présence : facultative
Dans certains cas (rares), tu peux vouloir compléter le fichier introduction.md de l'exercice, par exemple lorsque l'exercice implémente des tests qui ne sont pas couverts par les instructions existantes.
Un parcours qui ne souhaite pas que Bob prenne en charge les messages non-ASCII pourra ajouter ce qui suit :
# Introduction append
## Note
As part of his teenage rebellion, Bob has decided to only communicate using ASCII.
Les fichiers append doivent commencer par un en-tête H1. Cet en-tête n'est pas affiché, mais doit tout de même être présent. L'en-tête H1 est souvent suivi d'un en-tête H2, ce qui aide à séparer le contenu générique du contenu propre au parcours.
.docs/instructions.md
Objectif : fournir les instructions de l'exercice.
Présence : obligatoire
Si l'exercice implémente un exercice de Problem Specifications, le contenu de ce fichier doit correspondre au fichier instructions.md de cet exercice de Problem Specifications (ou au fichier description.md s'il n'y a pas de fichier instructions.md). configlet dispose d'une fonctionnalité pour synchroniser automatiquement le contenu de ce fichier.
Si l'exercice n'est pas basé sur un exercice de Problem Specifications, tiens compte des points suivants :
Nous attachons une grande importance à ce que le contenu d'Exercism soit sûr pour tout le monde, et nous choisissons donc souvent la prudence lorsqu'il s'agit de décider si une histoire est appropriée ou non. Nous faisons attention à ce que nous fusionnons, mais nous savons qu'il est difficile d'avoir conscience de ce qui peut être perçu comme problématique ; c'est pourquoi nous partirons toujours du principe que tu agis de bonne foi et ferons de notre mieux pour repérer les problèmes lors de la relecture, de manière non conflictuelle. Si tu veux vérifier une histoire avec nous, mentionne @exercism/leadership et nous l'examinerons ensemble. Voici quelques points pour te guider :
# Instructions
Bob answers 'Sure.' if you ask him a question, such as "How are you?".
He answers 'Whoa, chill out!' if you YELL AT HIM (in all capitals).
He answers 'Calm down, I know what I'm doing!' if you yell a question at him.
He says 'Fine. Be that way!' if you address him without actually saying anything.
He answers 'Whatever.' to anything else.
.docs/instructions.append.md
Objectif : texte d'instructions supplémentaire à ajouter après les instructions existantes.
Présence : facultative
Dans certains cas (rares), tu peux vouloir compléter le fichier instructions.md de l'exercice, par exemple lorsque l'exercice implémente des tests qui ne sont pas couverts par les instructions existantes.
# Instructions append
## Note
Bob's conversational partner is a purist when it comes to written communication and always follows normal rules regarding sentence punctuation in English.
Les fichiers append doivent commencer par un en-tête H1. Cet en-tête n'est pas affiché, mais doit tout de même être présent. L'en-tête H1 est souvent suivi d'un en-tête H2, ce qui aide à séparer le contenu générique du contenu propre au parcours.
.docs/hints.md
Objectif : fournir des indices pour aider un apprenant à se débloquer dans un exercice.
Présence : facultative
## General.Consulter les indices ne sera pas un chemin « recommandé », et nous te découragerons (en douceur) d'y recourir à moins que l'apprenant ne puisse pas avancer sans eux. Il faut donc garder à l'esprit que l'apprenant qui les lit sera un peu perdu ou submergé, et peut-être frustré.
## General
- There are many [built-in methods][integers] to simplify working with integers.
[integers]: https://ruby-doc.org/core-2.7.0/Integer.html
Objectif : décrire la conception de l'exercice.
Présence : facultative
Ce fichier contient des informations sur la conception de l'exercice : son objectif, ses objectifs pédagogiques, ce qu'il ne faut pas enseigner, etc.
Il existe pour informer les futurs mainteneurs ou contributeurs de la portée et des limites d'un exercice, afin d'éviter la tendance naturelle à rendre les exercices plus complexes avec le temps.
# Design
## Goal
The goal of this exercise is help students practice how to work with strings.
## Notes
This exercise does not contain any error handling tests.
.meta/config.json
Objectif : contient des méta-informations sur l'exercice.
Présence : obligatoire
Ce fichier contient des méta-informations sur l'exercice :
authors : le ou les noms d'utilisateur GitHub du ou des auteurs de l'exercice (facultatif)
contributors : le ou les noms d'utilisateur GitHub du ou des contributeurs de l'exercice (facultatif)
files : les emplacements des fichiers utilisés dans cet exercice, relatifs au répertoire de l'exercice (obligatoire)
solution : le ou les fichiers d'implémentation squelette (obligatoire)test : le ou les fichiers de test (obligatoire)example : le ou les fichiers d'implémentation d'exemple (obligatoire)editor : fichiers supplémentaires affichés en lecture seule dans l'éditeur (facultatif)invalidator : fichiers dont la modification rend une solution obsolète (facultatif)language_versions : versions de langage requises (facultatif)blurb : une courte description de cet exercice. Sa longueur doit être <= 350. Le Markdown n'est pas pris en charge (obligatoire)source : la source sur laquelle cet exercice est basé (facultatif)source_url : l'URL de la source sur laquelle cet exercice est basé (facultatif)test_runner : indique si les solutions de cet exercice doivent être testées dans l'exécuteur de tests. Vaut true par défaut si non spécifié. (facultatif)representer : méta-informations liées à la façon dont le representer traite ce fichier (facultatif)
version : un entier représentant la version du representer à utiliser pour l'exercice (obligatoire si la clé parente est présente)icon : le slug de l'icône (voir la liste complète des icônes). S'il n'est pas spécifié, le slug de l'exercice sera utilisé (facultatif)custom : toute donnée non standard propre à l'exercice. Permet de personnaliser le comportement de l'outillage du parcours pour un exercice donné (facultatif)Si une personne est à la fois auteur et contributeur, ne la liste que comme auteur.
{
"authors": ["FSharpForever"],
"files": {
"solution": ["Bob.fs"],
"test": ["BobTests.fs"],
"example": [".meta/Example.fs"]
},
"blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited"
}
À noter :
language_versions est une string de forme libre que les parcours sont libres d'utiliser et d'interpréter comme ils le souhaitent.Objectif : contient des informations sur les tests implémentés.
Présence : facultative
Ce fichier contient des informations sur les tests implémentés, à condition que l'exercice ait des tests définis dans son fichier canonical-data.json au sein du dépôt problem-specifications.
Il existe pour aider les mainteneurs à suivre les tests implémentés et à documenter (facultativement) pourquoi un test donné n'est pas implémenté. Il peut aussi servir à détecter les tests non implémentés.
L'outil configlet gère la mise à jour et la synchronisation de ce fichier avec les données du dépôt problem-specifications via la commande configlet sync. Lors de la synchronisation, configlet demande, pour chaque test non implémenté, s'il faut l'inclure ou non.
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.
[3e5c30a8-87e2-4845-a815-a49671ade970]
description = "empty strand"
[a0ea42a6-06d9-4ac6-828c-7ccaccf98fec]
description = "can count one nucleotide in single-character input"
[eca0d565-ed8c-43e7-9033-6cefbf5115b5]
description = "strand with repeated nucleotide"
[40a45eac-c83f-4740-901a-20b22d15a39f]
description = "strand with multiple nucleotides"
[b4c47851-ee9e-4b0a-be70-a86e343bd851]
description = "strand with invalid nucleotides"
include = false
comment = "error handling omitted on purpose"
.approaches/introduction.md
Objectif : présenter les approches les plus courantes pour l'exercice
Présence : facultative
Ce fichier décrit les approches les plus courantes pour l'exercice. Consulte la documentation pour en savoir plus sur ce qu'il doit contenir.
# Introduction
The key to this exercise is to deal with C# strings being immutable, which means that a `string`'s value cannot be changed.
Therefore, to reverse a string you'll need to create a _new_ `string`.
## Using LINQ
```csharp
public static string Reverse(string input)
{
return new string(input.Reverse().ToArray());
}
```
For more information, check the [LINQ approach][approach-linq].
## Which approach to use?
If readability is your primary concern (and it usually should be), the LINQ-based approach is hard to beat.
.approaches/config.json
Objectif : métadonnées des approches
Présence : facultative (obligatoire lorsqu'une introduction d'approches ou une approche existe)
Ce fichier contient des méta-informations sur les approches de l'exercice :
introduction : le ou les noms d'utilisateur GitHub du ou des auteurs de l'introduction des approches de l'exercice (facultatif)
authors : le ou les noms d'utilisateur GitHub du ou des auteurs de l'introduction des approches de l'exercice (obligatoire)
contributors : le ou les noms d'utilisateur GitHub du ou des contributeurs de l'introduction des approches de l'exercice (facultatif)
approaches : un tableau listant les approches détaillées (facultatif)
uuid : un UUID v4 qui identifie l'approche de manière unique. L'UUID doit être unique au sein du parcours comme sur l'ensemble des parcours, et ne doit jamais changerslug : le slug de l'approche, une string en minuscules au format kebab-case. Le slug doit être unique parmi tous les slugs d'approches du parcours. Sa longueur doit être <= 255.title : le titre de l'approche. Sa longueur doit être <= 255.blurb : une courte description de cette approche. Sa longueur doit être <= 350. Le Markdown n'est pas pris en charge (obligatoire)authors : le ou les noms d'utilisateur GitHub du ou des auteurs de l'approche (obligatoire)
contributors : le ou les noms d'utilisateur GitHub du ou des contributeurs de l'approche (facultatif)
tags : précise les conditions dans lesquelles une soumission est liée à une approche. (facultatif)
all : un tableau de tags qui doivent tous être présents sur une soumission (facultatif, sauf si any n'a aucun élément)any : un tableau de tags dont au moins un doit être présent sur une soumission (facultatif, sauf si all n'a aucun élément)not : aucun des tags ne doit être présent sur une soumission (facultatif){
"introduction": {
"authors": ["erikschierboom"]
},
"approaches": [
{
"uuid": "448fb2b4-18ab-4e55-aa54-ad4ed6d5f7f6",
"slug": "span",
"title": "Use Span<T>",
"blurb": "Use Span<T> to efficiently reverse a string.",
"authors": ["erikschierboom"]
}
]
}
.approaches/<approach-slug>/content.md
Objectif : description détaillée de l'approche
Présence : facultative (obligatoire pour les approches)
Ce fichier contient une description détaillée de l'approche. Consulte la documentation pour en savoir plus sur ce qu'il doit contenir.
# Span
```csharp
Span<char> chars = stackalloc char[input.Length];
for (var i = 0; i < input.Length; i++)
{
chars[input.Length - 1 - i] = input[i];
}
return new string(chars);
```
This `Span<T>` approach uses a `for` loop.
.approaches/<approach-slug>/snippet.txt
Objectif : extrait illustrant l'approche
Présence : facultative (obligatoire pour les approches)
Ce fichier contient un petit extrait qui illustre l'approche. L'extrait est affiché sur la page « Creuse plus loin » d'un exercice.
Son nombre de lignes doit être <= 8.
Consulte la documentation pour en savoir plus sur ce qu'il doit contenir.
Span<char> chars = stackalloc char[input.Length];
for (var i = 0; i < input.Length; i++)
{
chars[input.Length - 1 - i] = input[i];
}
return new string(chars);
.article/config.json
Objectif : métadonnées des articles
Présence : facultative (obligatoire lorsqu'un article existe)
Ce fichier contient des méta-informations sur les articles de l'exercice :
articles : un tableau listant les articles détaillés (facultatif)
uuid : un UUID v4 qui identifie l'article de manière unique. L'UUID doit être unique au sein du parcours comme sur l'ensemble des parcours, et ne doit jamais changerslug : le slug de l'article, une string en minuscules au format kebab-case. Le slug doit être unique parmi tous les slugs d'articles du parcours. Sa longueur doit être <= 255.title : le titre de l'article. Sa longueur doit être <= 255.blurb : une courte description de cet article. Sa longueur doit être <= 350. Le Markdown n'est pas pris en charge (obligatoire)authors : le ou les noms d'utilisateur GitHub du ou des auteurs de l'article (obligatoire)
contributors : le ou les noms d'utilisateur GitHub du ou des contributeurs de l'article (facultatif)
{
"articles": [
{
"uuid": "6db71962-62d5-448b-a980-c20ae41013ed",
"slug": "performance",
"title": "Optimizing performance",
"blurb": "Explore how to most efficiently reverse a string and what the trade-offs are.",
"authors": ["erikschierboom"]
}
]
}
.articles/<article-slug>/content.md
Objectif : description détaillée de l'article
Présence : facultative (obligatoire pour les articles)
Ce fichier contient une description détaillée de l'article. Consulte la documentation pour en savoir plus sur ce qu'il doit contenir.
# Performance
In this document, we'll find out which approach is the most performant one.
## Benchmark results
| Method | Mean | Error | StdDev | Median | Allocated |
| -----: | --------: | --------: | --------: | --------: | --------: |
| Linq | 29.133 ns | 0.5865 ns | 0.5486 ns | 28.984 ns | 80 B |
| Array | 4.806 ns | 0.4999 ns | 1.4739 ns | 3.967 ns | - |
.articles/<article-slug>/snippet.txt
Objectif : extrait illustrant l'article
Présence : facultative (obligatoire pour les articles)
Ce fichier contient un petit extrait qui illustre l'article. L'extrait est affiché sur la page « Creuse plus loin » d'un exercice.
Son nombre de lignes doit être <= 8.
Consulte la documentation pour en savoir plus sur ce qu'il doit contenir.
| Method | Mean | Allocated |
| -----: | --------: | --------: |
| Linq | 29.133 ns | 80 B |
| Array | 4.806 ns | - |
Objectif : fournir un point de départ aux apprenants.
Présence : obligatoire
"files.solution" du fichier .meta/config.json.using System;
public static class Isogram
{
public static bool IsIsogram(string word)
{
throw new NotImplementedException("You need to implement this function.");
}
}
Objectif : vérifier la justesse d'une solution.
Présence : obligatoire
"files.test" du fichier .meta/config.json.using Xunit;
public class IsogramTest
{
[Fact]
public void Empty_string() =>
Assert.True(Isogram.IsIsogram(""));
[Fact(Skip = "Remove this Skip property to run this test")]
public void Isogram_with_only_lower_case_characters() =>
Assert.True(Isogram.IsIsogram("isogram"));
[Fact(Skip = "Remove this Skip property to run this test")]
public void Word_with_one_duplicated_character() =>
Assert.False(Isogram.IsIsogram("eleven"));
}
Objectif : fournir une implémentation d'exemple qui réussit tous les tests.
Présence : obligatoire
"files.example" du fichier .meta/config.json.using System.Linq;
public static class Isogram
{
public static bool IsIsogram(string word)
{
var lowerCaseLetters = word.ToLower().Where(char.IsLetter).ToList();
return lowerCaseLetters.Distinct().Count() == lowerCaseLetters.Count;
}
}
Objectif : fichiers de projet, de compilation ou de support supplémentaires, nécessaires pour que les tests puissent s'exécuter.
Présence : obligatoire si les fichiers par défaut ne suffisent pas à exécuter les tests
Certains langages nécessitent des fichiers supplémentaires pour que les tests s'exécutent. C'est le cas par exemple des fichiers de projet de C# et des fichiers package.json de Node, sans lesquels il est impossible de lancer les tests.
Certains fichiers ne sont pas propres à chaque exercice, mais s'appliquent à tous les exercices. Consulte la documentation pour en savoir plus.
La façon dont la documentation d'un exercice est présentée à l'apprenant diffère selon qu'il utilise l'éditeur en ligne ou la CLI. Consulte ce document pour en savoir plus.
Chaque exercice a une icône associée.
Par défaut, l'icône affichée est celle dont le nom correspond au slug de l'exercice.
Pour la remplacer, il suffit d'indiquer la propriété icon dans le fichier .meta/config.json de l'exercice.
Si tu implémentes un exercice à partir des métadonnées de problem-specifications, il existe probablement déjà une icône pour cet exercice. Sinon, ouvre une issue dans le dépôt website-icons.