# Як працювати над завданнями з кодом

Наша мета — розробити веселе та зрозуміле інтерактивне навчання.

Розробити інтерактивні завдання для програмування — важко. Було б набагато простіше написати довге пояснення чи створити відеоурок. Але для нашої основної навчальної програми ми використовуємо те, що найкраще працює для більшості людей — інтерактив, схожий на відеогру.

Ми хочемо, щоб кемпери досягли стану потоку. Ми хочемо, щоб вони наростили темп та пройшли навчальну програму з мінімальною кількістю помилок. Ми хочемо, щоб вони впевнено виконували проєкти та ознайомились з багатьма поняттями програмування.

Зауважте, що для версії 7.0 навчальної програми freeCodeCamp ми переходимо до [проєктноорієнтованої моделі з багатьма повтореннями](https://www.freecodecamp.org/news/python-curriculum-is-live/).

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

І як завжди, не соромтесь ставити запитання [на форумі у категорії «Contributors»](https://forum.freecodecamp.org/c/contributors) або [у чаті](https://discord.gg/PRyKn3Vbay).

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

Вміст кожного завдання зберігається у відповідному файлі markdown. Потім, щоб створити інтерактивну вебсторінку, цей файл конвертується у HTML за допомогою наших інструментів.

Ви можете знайти весь навчальний матеріал freeCodeCamp.org у каталозі [`/curriculum/challenges`](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/curriculum/challenges).

## Налаштування інструментів для навчальної програми

Перш ніж працювати над навчальною програмою, потрібно налаштувати деякі інструменти, які допоможуть перевіряти ваші зміни. Ви можете використовувати будь-який варіант нижче:

- Ви можете [налаштувати freeCodeCamp локально](how-to-setup-freecodecamp-locally.md). Це **рекомендовано** для регулярних/повторних внесків. Це налаштування дозволяє працювати над змінами та перевіряти їх.
- Використовуйте безоплатне онлайн середовище Gitpod. Натисніть на кнопку нижче, щоб запустити готове середовище розробки для freeCodeCamp у своєму браузері. Це займе лише кілька хвилин.

  [![Відкрити у Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/freeCodeCamp/freeCodeCamp)

- Редагуйте файли на GitHub, натиснувши на значок олівця для відповідного файлу. Хоча це найшвидший спосіб, він **нерекомендований**, оскільки ви не можете перевірити свої зміни на GitHub. Якщо технічна підтримка вирішить, що ваші зміни потрібно перевірити локально, вам потрібно буде дотримуватись методів, описаних вище.

### Як працювати над практичними проєктами

Практичні проєкти мають деякі додаткові інструменти, які допомагають створити нові проєкти та кроки. Щоб дізнатися більше, див. [документацію](how-to-work-on-practice-projects.md).

## Шаблон завдання

````md
---
id: Unique identifier (alphanumerical, MongoDB_id)
title: 'Challenge Title'
challengeType: Integer, defined in `client/utils/challenge-types.js`
videoUrl: 'url of video explanation'
forumTopicId: 12345
---

# --description--

Challenge description text, in markdown

```html
<div>example code</div>
````

# --instructions--

Текст інструкції тестів у markdown

# --hints--

Тести для запуску коду користувача в поєднанні з текстом markdown та тестовим блоком коду.

```js
Код для першого тесту
```

Якщо вам потрібен динамічний вивід на основі коду користувача, --fcc-expected-- та --fcc-actual-- будуть змінені на очікувані та фактичні значення тестового припущення. Будьте обережними, якщо у вас є декілька припущень, оскільки перше невдале припущення визначить значення --fcc-expected-- та --fcc-actual--.

```js
assert.equal(
  'this will replace --fcc-actual--',
  'this will replace --fcc-expected--'
);
```

# --notes--

Додаткова інформація щодо завдання у markdown

# --seed--

## --before-user-code--

```lang
Код, перевірений перед кодом користувача.
```

## --after-user-code--

```lang
Код, перевірений після коду користувача і перед тестами.
```

## --seed-contents--

Шаблонний код для відображення у редакторі. Цей розділ повинен містити код лише у зворотних лапках:

```html
<body>
  <p class="main-text">Hello world!</p>
</body>
```

```css
body {
  margin: 0;
  background-color: #3a3240;
}

.main-text {
  color: #aea8d3;
}
```

```js
console.log('freeCodeCamp is awesome!');
```

# --solutions--

Розв’язки використовуються для тестів CI, щоб переконатись, що зміни до підказок працюватимуть як потрібно

```js
// перший розв’язок - мова має відповідати джерелу.
```

---

```js
// другий розв’язок - тобто, якщо джерело написане на HTML...
```

---

```js
// третій розв’язок і т. д. - ваш розв’язок має бути на HTML.
```

# --question--

Наразі ці поля використовуються для завдань з Python з декількома варіантами відповіді.

## --text--

Текст запитання знаходиться тут.

## --answers--

Відповідь 1

---

Відповідь 2

---

Інші відповіді

## --video-solution--

Номер правильної відповіді знаходиться тут.
````

> [!NOTE]
>
> 1. Прикладами `lang` у прикладах вище є:
>
> - `html` - HTML/CSS
> - `js` - JavaScript
> - `jsx` - JSX

## Нумерація завдань

Кожне завдання вимагає `id`. Якщо ви не вкажете його, то MongoDB створить випадкове id, коли зберігатиме дані. Нам цього непотрібно, оскільки id завдань повинні бути послідовними у всіх середовищах (проміжному, робочому, розробницькому тощо).

Щоб згенерувати id в оболонці (припускаючи, що MongoDB запущене окремо):

1. Запустіть команду `mongo`.
2. Запустіть команду `ObjectId()`.

Наприклад:

```bash
$ mongo
MongoDB shell version v3.6.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
...
$ ObjectId()
ObjectId("5a474d78df58bafeb3535d34")
````

Результатом є новий id (наприклад, `5a474d78df58bafeb3535d34` вище).

Як тільки ви отримали id, розмістіть його у файлі markdown як поле `id` зверху, тобто

```yml
---
id: 5a474d78df58bafeb3535d34
title: Challenge Title
```

## Найменування завдань

Давати назву — важко. Проте ми полегшили цей процес, впровадивши деякі обмеження.

Усі назви завдань повинні бути чіткими та дотримуватись цього шаблону:

\[дієслово\]\[підрядна частина\]

Нижче подано декілька прикладів назв завдань:

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

## Опис/інструкції завдань

Речення повинні бути зрозумілими і стислими, з мінімальною кількістю жаргону. Якщо жаргон все-таки був використаний, то його потрібно пояснити звичайною мовою.

Надавайте перевагу коротким абзацам (1-4 речення). Найімовірніше, люди прочитають декілька коротких абзаців, а не суцільний текст.

У тексті завдання потрібно використовувати 2-гу особу множини («ви»). У такий спосіб текст та інструкції будуть звернені напряму до учня, який виконує завдання. Намагайтеся уникати звертань у 1-й особі, як-от «я», «ми», «нам».

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

В разі потреби можна додати діаграми.

Не використовуйте емоджі в завданнях. freeCodeCamp — глобальна спільнота, а значення емоджі може відрізнятись в різних частинах світу. Крім цього, емоджі можуть по-різному зображатися у різних системах.

Власні іменники потрібно писати з великої літери, коли це можливо. Нижче поданий список, у якому показано, як повинні писатись слова в завданнях.

- JavaScript (великі літери «J» і «S», без скорочень)
- Node.js
- Іноді потрібно вживати деякі неточні форми, як-от «back end» і «front end» без дефіса, оскільки таке вживання більш поширене.

### Правило двох хвилин

Кожне завдання повинне бути вирішене протягом 120 секунд носієм англійської мови, який виконав попередні завдання. У цей час входять прочитання вказівок/інструкцій для розуміння початкового коду, написання власного коду і проходження всіх тестів.

Якщо виконання завдання займає більше двох хвилин, у вас є два шляхи:

- Спростіть завдання, або
- Розділіть завдання на два кроки.

Завдяки правилу двох хвилин ви зробите лаконічні вказівки, зрозумілий початковий код та прості тести.

Ми відстежуємо скільки часу займає розв’язок завдань та використовуємо цю інформацію, щоб виявити завдання, які потрібно спростити чи розділити.

### Модульність

Кожне завдання повинне навчати лише одному поняттю, і це поняття повинне бути очевидним з назви завдання.

Ми можемо закріпити раніше вивчені поняття за допомогою повторення та варіацій. Наприклад, ознайомити користувача з елементами h1 в одному завданні, а пізніше з елементами h3.

Наша мета — розробити тисячі двохвилинних завдань. Вони можуть йти нарівні, а також нагадувати про раніше вивчені поняття.

### Форматування тексту завдання

Тут подано конкретні рекомендації щодо форматування тексту завдання та приклади:

- Ключові слова мови знаходяться у зворотних лапках `` \` ``. Наприклад, назви тегів HTML чи назви властивостей CSS.
- Посилання на частини коду (тобто назви функцій, методів чи змінних) потрібно брати у зворотні лапки ``  \ ` ``. Розгляньте приклад нижче:

```md
Використовуйте `parseInt`, щоб перетворити змінну `realNumber` в ціле число.
```

- Посилання на назви файлів чи шляхи директорій (тобто `package.json`, `src/components`) потрібно брати у зворотні лапки `` \` ``.
- Перед блоками багаторядкового коду **має бути порожній рядок**. Наступний рядок повинен починатись з трьох зворотних лапок, після яких йде одна з [підтримуваних мов](https://prismjs.com/#supported-languages). Щоб закінчити блок коду, потрібно почати новий рядок, який має лише три зворотні лапки та **ще один порожній рядок**. Розгляньте приклад нижче:
- Пробіл має значення у markdown, тому ми рекомендуємо зробити його видимим у редакторі.

**Примітка:** якщо ви збираєтесь використовувати код прикладу в YAML, використовуйте `yaml` замість `yml` для мови справа від зворотних лапок.

Нижче поданий приклад коду:

````md
```{language}

[ТУТ МІСЦЕ ДЛЯ ВАШОГО КОДУ]

````
````

- Додаткова інформація у нотатках повинна бути оточена порожніми рядками та відформатована: `**Примітка:** Решта тексту примітки...`
- Якщо потрібно написати декілька приміток, перерахуйте всі примітки в окремих реченнях, використовуючи такий формат: `**Примітки:** Текст першої примітки. Текст другої примітки.`
- Використовуйте одинарні лапки там, де потрібно

**Примітка:** Еквівалент _Markdown_ потрібно використовувати на місці тегів _HTML_.

## Написання тестів

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

Наша мета — пояснити поняття, описане в завданні, та перевірити, що його зрозуміли.

Тести завдань можуть використовувати бібліотеки Node.js та Chai.js. Якщо необхідно, у змінній `code` можна отримати доступ до коду, створеного користувачами. Крім того, об’єкт `__helpers` надає декілька функцій, які полегшують процес написання тестів. Доступні функції визначені у _client/src/utils/curriculum-helpers.ts_.

## Форматування вихідного коду

Ось вказівки для форматування вихідного коду завдань:

- Використовуйте два пробіли для відступу
- Інструкції JavaScript закінчуються крапкою з комою
- Використовуйте подвійні лапки там, де потрібно

### Коментарі вихідного коду

У нас є [словник з коментарями](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/curriculum/dictionaries/english/comments.json), який містить лише ті коментарі, які можна використовувати у вихідному коді. Використовуйте той самий регістр та інтервал, що в словнику коментарів. Не доповнюйте словник коментарів, не обговоривши з командою розробників.

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

Приклад дійсного однорядкового коментаря JavaScript:

```js
// Змініть код під цим рядком
````

Приклад дійсного коментаря CSS:

```css
/* Only change code above this line */
```

Якщо завдання має лише одне місце, де потрібно змінити код, будь ласка, використайте коментарі з наступного прикладу, щоб проінформувати користувача, де потрібно внести зміни.

```js
var a = 3;
var b = 17;
var c = 12;

// Only change code below this line
a = a + 12;
b = 9 + b;
c = c + 7;
```

Якщо завдання має декілька місць, де користувач повинен змінити код (наприклад, завдання з React)

```jsx
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: 'Hello'
    };
    // Змініть код під цим рядком

    // Змініть код над цим рядком
  }
  handleClick() {
    this.setState({
      text: 'You clicked!'
    });
  }
  render() {
    return (
      <div>
        {/* Змініть код під цим рядком */}
        <button>Click Me</button>
        {/* змініть код над цим рядком */}
        <h1>{this.state.text}</h1>
      </div>
    );
  }
}
```

### Переклад коментарів початкового коду

Існують окремі словники з коментарями для кожної мови. [Англійська версія словника з коментарями](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/curriculum/dictionaries/english/comments.json) є основою для перекладів іншомовних версій файлів. Китайська версія словника з коментарями буде розташована на `/curriculum/dictionaries/chinese/comments.json`. Кожен словник складається з масиву об’єктів з унікальною властивістю `id` та властивістю `text`. Щоб охопити переклад англійського коментаря, потрібно змінювати лише `text`.

Деякі коментарі можуть містити слова чи фрази, які не потрібно перекладати. Наприклад, назви змінних або власні назви бібліотек (як-от «React») не потрібно перекладати. Розгляньте приклад нижче. Слово `myGlobal` не потрібно перекладати.

```text
Оголосіть змінну myGlobal під цим рядком
```

> [!NOTE]
> 
> Ми працюємо над інтеграцією, щоб дозволити працювати над словником коментарів для i18n.

## Підказки та розв’язки

Кожне завдання має кнопку `Get a Hint` для того, щоб користувач отримав доступ до будь-яких підказок/розв’язків, які були створені для цього завдання. Підказки та розв’язки навчальної програми розташовані на [нашому форумі](https://forum.freecodecamp.org/c/guide) у категорії `Guide`.

Якщо ви виявили помилку в наявних підказках чи розв’язках, повідомте про це на форумі [у розділі «Contributors»](https://forum.freecodecamp.org/c/contributors). Модератори й користувачі з 3-м рівнем довіри розглянуть коментарі та приймуть рішення щодо наданих вами змін.

### Додавання нових тем для підказок чи розв’язків завдань

Виконайте наступні кроки, щоб додати нову тему для підказок чи розв’язків завдань.

1. Розпочніть з тих самих кроків для створення нової теми, але зверніть увагу на наступні щодо заголовка.
2. Заголовок теми повинен починатись з `freeCodeCamp Challenge Guide:`, з’єднаного з назвою завдання навчальної програми. Наприклад, якщо завдання має назву `Chunky Monkey`, заголовком теми буде `freeCodeCamp Challenge Guide: Chunky Monkey`.
3. `camperbot` повинен бути власником цих тем/дописів, тому попросіть адміністратора змінити власника головного допису на `camperbot`.
4. Після створення нової теми створюється id теми форуму. Він розташований в кінці URL-адреси теми форуму. Цей id потрібно додати до передмови файлу завдання за допомогою звичайного запиту на злиття, щоб кнопка `Get a Hint` посилалась на тему.

### Вказівки щодо змісту тем підказок і розв’язків

Пропонуючи розв’язок до теми завдання навчальної програми, потрібно додати повний код. Сюди входить весь вихідний код та будь-які зміни, необхідні для проходження тестів. Використовуйте цей шаблон для створення нових тем підказок/розв’язків:

````md
# Тут назва завдання

---

## Пояснення проблеми

Тут узагальнюється те, що потрібно зробити (без повторення опису та/або інструкцій). Це додатковий розділ

#### Релевантні посилання

- [Текст посилання](link_url_goes_here)
- [Текст посилання](link_url_goes_here)

---

## Підказки

### Підказка 1

Тут підказка

### Підказка 2

Тут підказка

---

## Розв’язок

<details><summary>Solution 1 (Click to Show/Hide)</summary>

```js
function myFunc() {
  console.log('Hello World!');
}
````

#### Пояснення коду

- Тут пояснення коду
- Тут пояснення коду

#### Релевантні посилання

- [Текст посилання](link_url_goes_here)
- [Текст посилання](link_url_goes_here)

</details>
````

## Тестування завдань

Перш ніж [створити запит на злиття](how-to-open-a-pull-request.md) для своїх змін, вам потрібно переконатись, що зроблені зміни не призводять до проблем у завданні.

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

````
pnpm run test:curriculum
```

2. Ви можете перевірити блок або суперблок завдань за допомогою цих команд

```
FCC_BLOCK='Basic HTML and HTML5' pnpm run test:curriculum
```

```
FCC_SUPERBLOCK='responsive-web-design' pnpm run test:curriculum
```

Ви також можете перевірити окремо одне завдання, виконавши наступні дії:

1. Перейдіть до каталогу `curriculum`:

   ```
   cd curriculum
   ```

2. Виконайте цю команду для кожного файлу завдання, до якого ви внесли зміни (замінивши `challenge-title-goes-here` на повну назву завдання):

   ```
   pnpm run test -- -g challenge-title-goes-here
   ```

> [!TIP]
> Ви можете встановити змінну середовища `LOCALE` у `.env` на мову завдань, які потрібно протестувати.
>
> Наразі прийнятними значеннями є `english` та `chinese` (`english` за замовчуванням).

## Відкриття запиту на злиття (PR)

Як тільки ви затвердили свої зміни, див. [як відкрити запит на злиття](how-to-open-a-pull-request.md).

## Корисні посилання

Створення та редагування завдань:

1. [Види завдань](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/client/utils/challenge-types.js#L1-L13) — що означають числові значення завдань (перелік).

2. [Внесок до FreeCodeCamp: написання тестів до завдань ES6](https://www.youtube.com/watch?v=iOdD84OSfAE#t=2h49m55s) — відео [Ітана Арровуда](https://twitter.com/ArrowoodTech) про його внесок до старої версії навчальної програми.

## Допоміжні скрипти

> [!NOTE]
> Якщо ви працюєте над покроковими завданнями, див. розділ щодо [роботи над практичними проєктами](how-to-work-on-practice-projects.md).

Існує декілька допоміжних скриптів, які можна використовувати для завдань у блоці. Зверніть увагу, що ці команди потрібно виконувати у каталозі блоків. Наприклад:

```bash
cd curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting
```

### Додати нове завдання

Щоб додати нове завдання в кінці блоку, викличте скрипт:

```bash
pnpm run create-next-challenge
```

Це допоможе отримати інформацію про завдання та створити файл з завданням, оновивши файл `meta.json` новою інформацією про завдання.

### Видалити завдання

Щоб видалити завдання, викличте скрипт:

```bash
pnpm run delete-challenge
```

Це допоможе обрати потрібне завдання, видалити файл та оновити файл `meta.json`, щоб видалити завдання з порядку.

### Вставити завдання

Щоб вставити завдання перед наявним завданням, викличте скрипт:

```bash
pnpm run insert-challenge
```

Це допоможе отримати інформацію про нове завдання, а також про наявне завдання. Наприклад, якщо варіанти такі:

```bash
a
b
c
```

Ви обираєте `b`, а новим порядком буде:

```bash
a
new challenge
b
c
```

### Оновити порядок завдань

Якщо вам потрібно змінити порядок завдань вручну, викличте скрипт:

```bash
pnpm run update-challenge-order
```

Він проведе вас через інтерактивний процес, який допоможе впорядкувати завдання.
