Практичні вправи


Практичні вправи призначені для того, щоб студенти розвʼязували довільну задачу й застосовували концепції, які вже вивчили.

Якщо ми хочемо додати свою першу практичну вправу до треку, варто зазирнути до документації про додавання практичної вправи або подивитися наш відеоогляд 👇

Note

Можна швидко створити заготовку нової практичної вправи, виконавши такі команди в кореневій директорії треку:

bin/fetch-configlet
bin/configlet create --practice-exercise <slug>

Дізнатися більше можна в документації про configlet create

Метадані

Метадані практичної вправи задаються в ключі exercises.practice у файлі config.json. Ці метадані визначають UUID вправи, її slug та багато іншого.

Приклад

{
  "exercises": {
    "practice": [
      {
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "slug": "leap",
        "name": "Leap",
        "practices": ["if-statements", "numbers", "operator-precedence"],
        "prerequisites": ["if-statements", "numbers"],
        "difficulty": 1
      }
    ]
  }
}

practices

Ключ practices має містити перелік slug-ів концепцій, які ця практична вправа дає студентові змогу активно практикувати.

  • Вони показуються в інтерфейсі як «Практикуйте цю концепцію у: TwoFer, Leap тощо»
  • Намагаймося обирати від 3 до 8 вправ, які практикують кожну концепцію.
  • Намагаймося обирати принаймні дві вправи, які дають змогу попрактикувати основи концепції.
  • Деякі концепції дуже поширені (наприклад, strings). У таких випадках радимо обирати кілька вдалих вправ, які змушують студентів думати про ці концепції в цікавий спосіб. Наприклад, добре підійдуть вправи, які вимагають роботи з UTF-8, конкатенації рядків тексту (англ. string), перебору символів тощо.

prerequisites

Ключ prerequisites перелічує концепції, які студент має опанувати, щоб отримати доступ до цієї практичної вправи.

  • Вони показуються в інтерфейсі як «Вивчіть рядки тексту, щоб відкрити TwoFer»
  • Він має охоплювати всі концепції, які студент має пройти, щоб виконати вправу принаймні одним ідіоматичним способом. Наприклад, для вправи TwoFer у Ruby передумовами можуть бути strings, optional-params, implicit-return.
  • Для вправ, які можна виконати з використанням альтернативних концепцій (наприклад, вправа, яку можна розвʼязати через loops або recursion), мейнтейнер має обрати той єдиний підхід, яким вправу буде відкрито, з огляду на подорож студента треком. Наприклад, у випадку з циклами й рекурсією мейнтейнер може вважати цю вправу хорошою ранньою практикою loops або вирішити залишити її на пізніше, щоб навчити рекурсії. Також можна скористатися аналізатором, щоб підказати студентові спробувати альтернативний підхід: «Гарна робота з розвʼязанням через цикли. Спробуйте також розвʼязати це за допомогою рекурсії.»

Файли

Кожна практична вправа має власну директорію всередині директорії exercises/practice треку. Назва директорії практичної вправи має збігатися з властивістю slug цієї вправи, визначеною у файлі config.json.

Практична вправа містить чотири типи файлів:

Файли документації

Ці файли показуються студентові, щоб допомогти пояснити вправу.

  • .docs/introduction.md: описує контекст і передісторію вправи (необовʼязковий)
  • .docs/introduction.append.md: додатковий вступний текст, який дописується після наявного вступу (необовʼязковий)
  • .docs/instructions.md: містить вказівки до вправи (обовʼязковий)
  • .docs/instructions.append.md: додатковий вступний текст, який дописується після наявних вказівок (необовʼязковий)
  • .docs/hints.md: містить підказки, які допомагають студентові вибратися із глухого кута у вправі (необовʼязковий)

Файли метаданих

Ці файли не показуються студентові, а використовуються для задання метаданих вправи.

  • .meta/config.json: містить метаінформацію про вправу (обовʼязковий)
  • .meta/design.md: описує задум вправи (необовʼязковий)
  • .meta/tests.toml: містить інформацію про те, які тести реалізовано (необовʼязковий)

Файли підходів

Ці файли описують підходи до вправи.

  • .approaches/introduction.md: вступ до найпоширеніших підходів до вправи (необовʼязковий)
  • .approaches/config.json: метадані підходів (необовʼязковий)
  • .approaches/<approach-slug>/content.md: опис підходу (необовʼязковий)
  • .approaches/<approach-slug>/snippet.txt: фрагмент, який демонструє підхід (необовʼязковий)

Файли статей

Ці файли описують статті до вправи.

  • .articles/config.json: метадані статей (необовʼязковий)
  • .articles/<article-slug>/content.md: опис статті (необовʼязковий)
  • .articles/<article-slug>/snippet.md: фрагмент, який демонструє статтю (необовʼязковий)

Файли вправи

Файли, специфічні для мови: реалізація, тести тощо. Назви цих файлів залежать від треку.

  • Набір тестів: перевіряє правильність рішення.
  • Заглушка реалізації: дає студентові відправну точку.
  • Приклад реалізації: показує приклад реалізації, яка проходить усі тести.
  • Додаткові файли: забезпечують можливість запуску тестів.

Приклад

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 (example implementation)
        ├── Isogram.cs (stub implementation)
        └── IsogramTests.cs (tests)

Файл: .docs/introduction.md

Призначення: описати студентові контекст і передісторію вправи.

Наявність: обовʼязковий, якщо вправа є реалізацією вправи з Problem Specifications і містить файл introduction.md

Якщо вправа реалізує вправу з Problem Specifications, вміст цього файлу має збігатися з файлом introduction.md цієї вправи з Problem Specifications. У configlet є можливість автоматично синхронізувати вміст цього файлу.

Якщо вправа не ґрунтується на вправі з Problem Specifications, варто зважити на таке:

Ми дуже цінуємо безпечність контенту Exercism для всіх, тому в питанні доречності історій часто обираємо обережніший шлях. Ми уважно ставимося до того, що додаємо, і розуміємо, що помітити потенційно проблемні речі буває складно, тож завжди припускаємо добрі наміри й намагаємося виявити будь-які проблеми під час ревʼю без конфронтації. Якщо хочеться перевірити історію разом із нами, варто згадати @exercism/leadership, і ми розглянемо її разом. Ось кілька орієнтирів:

  • Намагаймося, щоб історія була привітною і зрозумілою для всіх. Якщо в історії є жарти «для своїх» або місцевий сленг, варто пошукати інші формулювання.
  • Намагаймося писати приклади, які враховують усіх. Наприклад, варто використовувати імена з різних культур і різних гендерів.
  • Подумаймо, чи знаємо ми особисто когось, кого ця історія могла б образити. Якщо так, варто її змінити, щоб цього уникнути.

Приклад

# Introduction

Bob is a lackadaisical teenager. In conversation, his responses are very limited.

Файл: .docs/introduction.append.md

Призначення: додатковий вступний текст, який дописується після наявного вступу.

Наявність: необовʼязковий

У деяких (рідкісних) випадках може виникнути потреба доповнити файл introduction.md вправи, наприклад коли у вправі реалізовано тести, не охоплені наявними вказівками.

Трек, який не хоче, щоб Bob підтримував не-ASCII повідомлення, може додати таке:

# Introduction append

## Note

As part of his teenage rebellion, Bob has decided to only communicate using ASCII.

Файли-доповнення мають починатися із заголовка H1. Цей заголовок не відображається, але все одно має бути присутнім. Після заголовка H1 часто йде заголовок H2, який допомагає відокремити загальний вміст від вмісту, специфічного для треку.

Файл: .docs/instructions.md

Призначення: надати вказівки до вправи.

Наявність: обовʼязковий

Якщо вправа реалізує вправу з Problem Specifications, вміст цього файлу має збігатися з файлом instructions.md цієї вправи з Problem Specifications (або з файлом description.md, якщо файлу instructions.md немає). У configlet є можливість автоматично синхронізувати вміст цього файлу.

Якщо вправа не ґрунтується на вправі з Problem Specifications, варто зважити на таке:

Ми дуже цінуємо безпечність контенту Exercism для всіх, тому в питанні доречності історій часто обираємо обережніший шлях. Ми уважно ставимося до того, що додаємо, і розуміємо, що помітити потенційно проблемні речі буває складно, тож завжди припускаємо добрі наміри й намагаємося виявити будь-які проблеми під час ревʼю без конфронтації. Якщо хочеться перевірити історію разом із нами, варто згадати @exercism/leadership, і ми розглянемо її разом. Ось кілька орієнтирів:

  • Намагаймося, щоб історія була привітною і зрозумілою для всіх. Якщо в історії є жарти «для своїх» або місцевий сленг, варто пошукати інші формулювання.
  • Намагаймося писати приклади, які враховують усіх. Наприклад, варто використовувати імена з різних культур і різних гендерів.
  • Подумаймо, чи знаємо ми особисто когось, кого ця історія могла б образити. Якщо так, варто її змінити, щоб цього уникнути.

Приклад

# 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

Призначення: додатковий текст вказівок, який дописується після наявних вказівок.

Наявність: необовʼязковий

У деяких (рідкісних) випадках може виникнути потреба доповнити файл instructions.md вправи, наприклад коли у вправі реалізовано тести, не охоплені наявними вказівками.

# 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.

Файли-доповнення мають починатися із заголовка H1. Цей заголовок не відображається, але все одно має бути присутнім. Після заголовка H1 часто йде заголовок H2, який допомагає відокремити загальний вміст від вмісту, специфічного для треку.

Файл: .docs/hints.md

Призначення: надати студентові підказки, які допоможуть вибратися із глухого кута у вправі.

Наявність: необовʼязковий

  • Якщо студент застряг, ми даємо йому змогу натиснути кнопку, щоб попросити підказку, і тоді покажеться відповідна частина файлу.
  • Підказки мають бути списком під заголовками.
  • Підказок має вистачати, щоб розблокувати майже будь-якого студента.
  • Підказки не мають розкривати рішення, а натомість вказувати на ресурс, який його описує (наприклад, посилання на документацію потрібної функції).
  • Підказки можуть використовувати приклади коду, щоб пояснити концепції, але не для того, щоб окреслити рішення. Наприклад, у вправі на масиви вони можуть показати фрагмент того, як працює та чи інша функція для масиву, але не так, щоб його можна було напряму скопіювати в рішення.
  • Підказки мають бути у вигляді списку Markdown під заголовком ## General.
  • Якщо підказок немає, заголовок слід пропустити.

Перегляд підказок не вважатиметься «рекомендованим» шляхом, і ми (мʼяко) відмовляємо від нього, якщо без нього студент не може рухатися далі. Тож варто зважати, що студент, який їх читає, буде трохи розгублений чи перевантажений, а може, й засмучений.

Приклад

## General

- There are many [built-in methods][integers] to simplify working with integers.

[integers]: https://ruby-doc.org/core-2.7.0/Integer.html

Файл: .meta/design.md

Призначення: описати задум вправи.

Наявність: необовʼязковий

Цей файл містить інформацію про задум вправи: її мету, навчальні цілі, те, чого не варто навчати, тощо.

Він існує, щоб майбутні мейнтейнери та контрибʼютори знали про обсяг і обмеження вправи й не піддавалися природній тенденції робити вправи з часом дедалі складнішими.

Приклад

# 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

Призначення: містить метаінформацію про вправу.

Наявність: обовʼязковий

Цей файл містить метаінформацію про вправу:

  • authors: імʼя (імена) користувачів GitHub, які є авторами вправи (необовʼязковий)
    • Зокрема рецензентів, якщо їхні відгуки суттєво змінюють вправу (настільки, що здається, ніби до цього дійшли разом)
  • contributors: імʼя (імена) користувачів GitHub, які є контрибʼюторами вправи (необовʼязковий)
    • Зокрема рецензентів, якщо їхні відгуки були змістовними, конструктивними або врахованими.
  • files: розташування файлів, які використовуються у цій вправі, відносно директорії вправи (обовʼязковий)
  • language_versions вимоги до версії мови (необовʼязковий)
  • blurb: короткий опис цієї вправи. Довжина має бути <= 350. Markdown не підтримується (обовʼязковий)
  • source: джерело, на якому ґрунтується ця вправа (необовʼязковий)
  • source_url: URL джерела, на якому ґрунтується ця вправа (необовʼязковий)
  • test_runner: указує, чи мають рішення цієї вправи тестуватися в тест-раннері. Якщо не вказано, типовим є true. (необовʼязковий)
  • representer: метаінформація про те, як репрезентер обробляє цей файл (необовʼязковий)
    • version: ціле число, яке задає версію репрезентера для цієї вправи (обовʼязковий, якщо присутній батьківський ключ)
  • icon: slug іконки (див. повний список іконок). Якщо не вказано, буде використано slug вправи (необовʼязковий)
  • custom: будь-які нестандартні дані, специфічні для вправи. Можна використовувати, щоб налаштувати поведінку інструментарію треку для конкретної вправи (необовʼязковий)

Якщо людина є і автором, і контрибʼютором, укажіть її лише як автора.

Приклад

{
  "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"
}

Варто зауважити:

  • Порядок авторів і контрибʼюторів не має значення і ні на що не впливає.
  • language_versions: це рядок тексту довільної форми, який треки можуть використовувати й тлумачити як завгодно.

Файл: .meta/tests.toml

Призначення: містить інформацію про те, які тести реалізовано.

Наявність: необовʼязковий

Цей файл містить інформацію про те, які тести реалізовано, за умови що у вправи є тести, визначені у файлі canonical-data.json у репозиторії problem-specifications.

Він існує, щоб допомагати мейнтейнерам відстежувати, які тести реалізовано, і (за бажанням) документувати, чому певний тест не реалізовано. Його також можна використовувати для виявлення нереалізованих тестів.

Інструмент configlet оновлює та синхронізує цей файл із даними в репозиторії problem-specifications за допомогою команди configlet sync. Під час синхронізації configlet для кожного нереалізованого тесту запитує, чи включати цей тест.

Приклад

# 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

Призначення: вступ до найпоширеніших підходів до вправи

Наявність: необовʼязковий

Цей файл описує найпоширеніші підходи до вправи. Що саме має бути в цьому файлі, описано в документації.

Приклад

# 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

Призначення: метадані підходів

Наявність: необовʼязковий (обовʼязковий, якщо існує вступ до підходів або сам підхід)

Цей файл містить метаінформацію про підходи до вправи:

  • introduction: імʼя (імена) користувачів GitHub, які є авторами вступу до підходів вправи (необовʼязковий)

    • authors: імʼя (імена) користувачів GitHub, які є авторами вступу до підходів вправи (обовʼязковий)
      • Зокрема рецензентів, якщо їхні відгуки суттєво змінюють вступ до підходів вправи (настільки, що здається, ніби до цього дійшли разом)
    • contributors: імʼя (імена) користувачів GitHub, які є контрибʼюторами вступу до підходів вправи (необовʼязковий)
      • Зокрема рецензентів, якщо їхні відгуки були змістовними, конструктивними або врахованими.
  • approaches: масив, який перелічує докладні підходи (необовʼязковий)

    • uuid: UUID версії V4, який однозначно ідентифікує підхід. UUID має бути унікальним як у межах треку, так і серед усіх треків, і ніколи не має змінюватися
    • slug: slug підходу, тобто рядок тексту в нижньому регістрі у kebab-case. Slug має бути унікальним серед усіх slug-ів підходів у межах треку. Його довжина має бути <= 255.
    • title: назва підходу. Її довжина має бути <= 255.
    • blurb: короткий опис цього підходу. Довжина має бути <= 350. Markdown не підтримується (обовʼязковий)
    • authors: імʼя (імена) користувачів GitHub, які є авторами підходу до вправи (обовʼязковий)
      • Зокрема рецензентів, якщо їхні відгуки суттєво змінюють підхід до вправи (настільки, що здається, ніби до цього дійшли разом)
    • contributors: імʼя (імена) користувачів GitHub, які є контрибʼюторами підходу до вправи (необовʼязковий)
      • Зокрема рецензентів, якщо їхні відгуки були змістовними, конструктивними або врахованими.
    • tags: задають умови, за яких надіслане рішення повʼязується з підходом. (необовʼязковий)
      • all: масив тегів, які всі мають бути присутні в надісланому рішенні (необовʼязковий, якщо в any немає елементів)
      • any: масив тегів, з яких принаймні один має бути присутній у надісланому рішенні (необовʼязковий, якщо в all немає елементів)
      • not: жоден із тегів не має бути присутній у надісланому рішенні (необовʼязковий)

Приклад

{
  "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

Призначення: докладний опис підходу

Наявність: необовʼязковий (обовʼязковий для підходів)

Цей файл містить докладний опис підходу. Що саме має бути в цьому файлі, описано в документації.

Приклад

# 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

Призначення: фрагмент, який демонструє підхід

Наявність: необовʼязковий (обовʼязковий для підходів)

Цей файл містить невеликий фрагмент, який демонструє підхід. Фрагмент показується на сторінці «Dig Deeper» вправи.

Кількість рядків у ньому має бути <= 8.

Що саме має бути в цьому файлі, описано в документації.

Приклад

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

Призначення: метадані статей

Наявність: необовʼязковий (обовʼязковий, якщо існує стаття)

Цей файл містить метаінформацію про статті до вправи:

  • articles: масив, який перелічує докладні статті (необовʼязковий)
    • uuid: UUID версії V4, який однозначно ідентифікує статтю. UUID має бути унікальним як у межах треку, так і серед усіх треків, і ніколи не має змінюватися
    • slug: slug статті, тобто рядок тексту в нижньому регістрі у kebab-case. Slug має бути унікальним серед усіх slug-ів статей у межах треку. Його довжина має бути <= 255.
    • title: назва статті. Її довжина має бути <= 255.
    • blurb: короткий опис цієї статті. Довжина має бути <= 350. Markdown не підтримується (обовʼязковий)
    • authors: імʼя (імена) користувачів GitHub, які є авторами статті до вправи (обовʼязковий)
      • Зокрема рецензентів, якщо їхні відгуки суттєво змінюють статтю до вправи (настільки, що здається, ніби до цього дійшли разом)
    • contributors: імʼя (імена) користувачів GitHub, які є контрибʼюторами статті до вправи (необовʼязковий)
      • Зокрема рецензентів, якщо їхні відгуки були змістовними, конструктивними або врахованими.

Приклад

{
  "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

Призначення: докладний опис підходу

Наявність: необовʼязковий (обовʼязковий для підходів)

Цей файл містить докладний опис підходу. Що саме має бути в цьому файлі, описано в документації.

Приклад

# 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

Призначення: фрагмент, який демонструє підхід

Наявність: необовʼязковий (обовʼязковий для статей)

Цей файл містить невеликий фрагмент, який демонструє статтю. Фрагмент показується на сторінці «Dig Deeper» вправи.

Кількість рядків у ньому має бути <= 8.

Що саме має бути в цьому файлі, описано в документації.

Приклад

| Method |      Mean | Allocated |
| -----: | --------: | --------: |
|   Linq | 29.133 ns |      80 B |
|  Array |  4.806 ns |         - |

Файл: заглушка реалізації

Призначення: дати студентові відправну точку.

Наявність: обовʼязковий

  • Заглушку варто спроєктувати так, щоб студент розумів, де додавати код.
  • Для компільованих мов варто подбати про те, щоб код компілювався, адже повідомлення компілятора іноді важко зрозуміти студентам, які щойно почали вивчати мову.
  • Код має бути якомога простішим.
  • Слід використовувати лише ті можливості мови, які вводяться передумовами (та їхніми передумовами, і так далі).
  • Файл-заглушка показується студентові під час роботи в редакторі в браузері та завантажується до файлової системи студента під час використання CLI.
  • Відносні шляхи до файлів заглушки реалізації мають бути вказані в ключі "files.solution" файлу .meta/config.json.

Приклад

using System;

public static class Isogram
{
    public static bool IsIsogram(string word)
    {
        throw new NotImplementedException("You need to implement this function.");
    }
}

Файл: тести

Призначення: перевірити правильність рішення.

Наявність: обовʼязковий

  • Код має бути якомога простішим.
  • Слід використовувати лише ті можливості мови, які вводяться передумовами вправи (та їхніми передумовами, і так далі).
  • Файл тестів показується студентові під час роботи в редакторі в браузері та завантажується до файлової системи студента під час використання CLI.
  • Exercism віддає перевагу тому, щоб практичні вправи виконувалися за принципом розробки через тестування. Щоб це забезпечити, є два варіанти:
    • тест-раннер має запускати тести в порядку, визначеному у файлі, І набір тестів має зупинятися на першій невдачі; або
    • у типовому стані всі тести, крім першого, мають бути пропущені.
  • Відносні шляхи до файлів тестів мають бути вказані в ключі "files.test" файлу .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"));
}

Файл: приклад реалізації

Призначення: надати приклад реалізації, яка проходить усі тести.

Наявність: обовʼязковий

  • Ця реалізація використовується, щоб переконатися, що існує реалізація, яка проходить тести. Вона навмисно не є тим кодом, до якого має прагнути студент.
  • Кожен трек має перевіряти, що приклад реалізації проходить тести у своєму налаштуванні безперервної інтеграції.
  • Наставникам цей код не показується.
  • Файл прикладу не показується студентові під час роботи в редакторі в браузері й не завантажується до файлової системи студента під час використання CLI.
  • Відносні шляхи до файлів прикладу реалізації мають бути вказані в ключі "files.example" файлу .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;
    }
}

Файл: додаткові файли

Призначення: додаткові файли проєкту, збірки чи допоміжні файли, потрібні для запуску тестів.

Наявність: обовʼязковий, якщо типових файлів не вистачає для запуску тестів

Деякі мови потребують додаткових файлів, щоб тести могли запускатися. Приклади: файли проєктів у C# та файли package.json у Node, без яких запустити тести неможливо.

Спільні файли

Деякі файли не належать окремим вправам, а стосуються всіх вправ. Додаткову інформацію шукайте в документації.

Презентація

Те, як документація вправи показується студентові, відрізняється під час використання редактора в браузері та CLI. Додаткову інформацію див. у цьому документі.

Іконка

Кожна вправа має супровідну іконку. Типово показується та іконка, назва якої збігається зі slug вправи. Це можна перевизначити, указавши властивість icon у файлі .meta/config.json вправи.

Якщо ми реалізуємо вправу на основі метаданих problem-specifications, для неї, найімовірніше, уже є іконка. Якщо ні, варто відкрити issue в репозиторії website-icons.