config.json


Файл config.json описує конфігурацію треку. Він містить важливу інформацію, як-от вправи та концепції треку.

Метадані

Наведені нижче властивості верхнього рівня містять загальні метадані треку:

  • language: мова треку (наприклад, "C#"). Її довжина має бути <= 255. (обовʼязково)
  • slug: мова треку як рядок тексту (англ. string) у нижньому регістрі з дефісами (kebab-case) (наприклад, "csharp"). Його довжина має бути <= 255. (обовʼязково)
  • active: boolean-значення, яке вказує, чи активний трек (тобто чи можуть студенти приєднатися до треку на сайті) (обовʼязково)
  • blurb: короткий опис мови. Його довжина має бути <= 400. (обовʼязково)
  • version: версія файлу config.json (наразі фіксована на 3) (обовʼязково)
  • online_editor: обʼєкт, що описує налаштування, які використовує онлайн-редактор: (обовʼязково)
    • indent_style: або "space", або "tab" (обовʼязково)
    • indent_size: розмір відступу як ціле число (наприклад, 4) (обовʼязково)
    • highlightjs_language: ідентифікатор мови для Highlight.js (див. повний список ідентифікаторів) (необовʼязково)
  • status: обʼєкт, що описує, які можливості v3 слід увімкнути: (обовʼязково)
    • concept_exercises: boolean-значення, яке вказує, чи створено концептуальні вправи (обовʼязково). Коли true, інтерфейс сайту Exercism змінюється, показуючи, що для треку доступні концептуальні вправи.
    • test_runner: boolean-значення, яке вказує, чи реалізовано test runner (обовʼязково). Коли true, ми пропускаємо подані рішення через нашу інфраструктуру тестування й показуємо результати на сайті. Сайт також дає студентам змогу запустити тестування просто з онлайн-редактора.
    • representer: boolean-значення, яке вказує, чи реалізовано representer (обовʼязково)
    • analyzer: boolean-значення, яке вказує, чи реалізовано analyzer (обовʼязково)
  • files: шаблони розташування файлів, які використовуються у вправі, відносно каталогу вправи. (необовʼязково)
    • solution: шаблон файлів заготовки реалізації (необовʼязково)
    • test: шаблон файлів тестів (необовʼязково)
    • example: шаблон файлів прикладу реалізації (необовʼязково)
    • exemplar: шаблон файлів зразкової реалізації (необовʼязково)
    • editor: додаткові шаблони файлів редактора, доступних лише для читання (необовʼязково)
  • test_runner: обʼєкт, що описує test runner треку (якщо він є): (обовʼязково, якщо status.test_runner має значення true)
    • average_run_time: ціле number-значення, яке задає кількість секунд, що test runner у середньому витрачає на запуск (наприклад, 4) (обовʼязково, якщо status.test_runner має значення true)
  • approaches: обʼєкт із метаданими про підходи треку: (обовʼязково, якщо трек має якісь підходи)
    • snippet_extension: значення у вигляді рядка тексту, яке використовується як розширення файлу сніпета (наприклад, rb) (обовʼязково, якщо трек має якісь підходи)

Файли

Цей ключ використовується, щоб указати розташування файлів у межах усього треку. Замість того щоб мейнтейнери вручну задавали ключ files у файлах config.json вправ, configlet може автоматично заповнювати його за цими загальнотрековими шаблонами.

Шаблони файлів, визначені в обʼєкті files, підтримують такі заповнювачі:

  • %{kebab_slug}: slug вправи у kebab-case (наприклад, bit-manipulation)
  • %{snake_slug}: slug вправи у snake_case (наприклад, bit_manipulation)
  • %{camel_slug}: slug вправи у camelCase (наприклад, bitManipulation)
  • %{pascal_slug}: slug вправи у PascalCase (наприклад, BitManipulation)

Підтримку буде додано до configlet, щоб використовувати ці шаблони для заповнення ключа files у файлі .meta/config.json вправи.

Приклад

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  }
}

Вправи

Ключ exercises верхнього рівня є обʼєктом із трьома можливими ключами:

  • concept: це масив, що перелічує концептуальні вправи треку
  • practice: це масив, що перелічує практичні вправи треку
  • foregone: це масив, що перелічує slug вправ, які трек не впроваджуватиме

Концептуальні вправи

Кожна концептуальна вправа є елементом масиву exercises.concept. На сайті вправи впорядковано в тому самому порядку, у якому вони перелічені в цьому файлі, і він має відповідати типовому порядку їх розвʼязування. Концептуальну вправу складають такі поля:

  • uuid: UUID версії 4, який однозначно ідентифікує вправу. UUID має бути унікальним як у межах треку, так і в межах усіх треків, і ніколи не повинен змінюватися
  • slug: slug вправи, тобто рядок тексту в нижньому регістрі з дефісами. Slug має бути унікальним серед усіх slug концептуальних і практичних вправ у межах треку. Його довжина має бути <= 255.
  • name: назва вправи. Її довжина має бути <= 255.
  • concepts: масив slug концепцій, яких навчає ця концептуальна вправа
  • prerequisites: масив slug концепцій, які мають бути розблоковані, перш ніж студент зможе почати цю вправу
  • status (необовʼязково): статус вправи, один із "wip", "beta", "active" або "deprecated"; якщо його не вказано, типово "active"
    • wip: вправа в процесі роботи, ще не готова для загального використання. Вправи з цим тегом не показуватимуть студентам в інтерфейсі й не використовуватимуть у логіці розблокування. Їх можуть бачити мейнтейнери.
    • beta: позначає активні вправи, які є новими й щодо яких ми хотіли б отримати відгук. Для таких вправ ми показуємо на сайті мітку beta із закликом до дії «Будь ласка, дайте нам відгук».
    • active: звичайний стан активних вправ
    • deprecated: вправи, які більше не показують студентам, які їх не почали (на цьому етапі вони недоступні). Докладніше див. у розділі Застарілі вправи.

Приклад

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ]
      },
      ...
    ]
  }
}

Приклад вправи в процесі роботи

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      },
      ...
    ]
  }
}

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

Кожна практична вправа є елементом масиву exercises.practice. Практичну вправу складають такі поля:

  • uuid: UUID версії 4, який однозначно ідентифікує вправу. UUID має бути унікальним як у межах треку, так і в межах усіх треків, і ніколи не повинен змінюватися
  • slug: slug вправи, тобто рядок тексту в нижньому регістрі з дефісами. Slug має бути унікальним серед усіх slug концептуальних і практичних вправ у межах треку. Його довжина має бути <= 255.
  • name: назва вправи. Її довжина має бути <= 255.
  • practices: масив slug концепцій, які вправа допомагає студентам відпрацювати
  • prerequisites: масив slug концепцій, які мають бути розблоковані, перш ніж студент зможе почати вправу
  • difficulty: число, що вказує складність вправи. Число має бути в діапазоні від 1 (найлегша) до 10 (найскладніша). Сайт тлумачить складність так:
    • 1,2,3: легко
    • 4,5,6,7: середньо
    • 8,9,10: складно
  • status (необовʼязково): статус вправи, один із "wip", "beta", "active" або "deprecated"; якщо його не вказано, типово "active"
    • wip: вправа в процесі роботи, ще не готова для загального використання. Вправи з цим тегом не показуватимуть студентам в інтерфейсі й не використовуватимуть у логіці розблокування. Їх можуть бачити мейнтейнери.
    • beta: позначає активні вправи, які є новими й щодо яких ми хотіли б отримати відгук. Для таких вправ ми показуємо на сайті мітку beta із закликом до дії «Будь ласка, дайте нам відгук»
    • active: звичайний стан активних вправ
    • deprecated: вправи, які більше не показують студентам, які їх не почали (на цьому етапі вони недоступні).

«Рекомендований порядок» практичних вправ на сайті відповідає порядку вправ у масиві practice.

Приклад

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

Приклад бета-вправи

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

Відкинуті вправи

Якщо трек знає, що не хоче впроваджувати вправу, визначену в репозиторії Problem Specifications, slug цієї вправи можна додати до ключа exercises.foregone. configlet ігноруватиме відкинуті вправи, коли виводитиме невпроваджені вправи треку.

Причинами, чому трек може не хотіти впроваджувати вправу, можуть бути:

  • Вправу неможливо розумно реалізувати цією мовою. Наприклад, вправа lens-person вимагає, щоб мова підтримувала лінзи.
  • Тема вправи не пасує мові. Наприклад, для деяких високорівневих мов низькорівнева вправа з бітових операцій може не мати сенсу.

Приклад

{
  "exercises": {
    "foregone": [
      "lens-person"
    ]
  }
}

Концепції

Кожна концепція є елементом масиву concepts верхнього рівня. Концепцію складають такі поля:

  • uuid: UUID версії 4, який однозначно ідентифікує концепцію. UUID має бути унікальним як у межах треку, так і в межах усіх треків, і ніколи не повинен змінюватися
  • slug: slug концепції, тобто рядок тексту в нижньому регістрі з дефісами. Slug має бути унікальним серед усіх концепцій у межах треку. Його довжина має бути <= 255.
  • name: назва концепції. Її довжина має бути <= 255.
  • tags: укажіть умови, за яких рішення повʼязують із підходом. (необовʼязково)
    • all: масив тегів, які всі мають бути присутні в рішенні (необовʼязково, якщо any не містить елементів)
    • any: масив тегів, з яких принаймні один має бути присутній у рішенні (необовʼязково, якщо all не містить елементів)
    • not: жоден із тегів не має бути присутній у рішенні (необовʼязково)

Приклад

{
  "concepts": [
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers",
      "tags": {
        "all": [
          "concept:number"
        ]
      }
    }
  ]
}

Ключові можливості

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

Ключові можливості задають у полі key_features верхнього рівня, яке визначене як масив обʼєктів із такими полями:

  • title: стислий заголовок ключової можливості. Його довжина має бути <= 25. Markdown не підтримується.
  • content: опис ключової можливості. Його довжина має бути <= 100. Markdown не підтримується.
  • icon: іконка для показу цієї можливості. Можна вибрати іконку, яка видається доречною, незалежно від її назви. Можна використовувати такі іконки:
    • community
    • concurrency
    • cross-platform
    • documentation
    • dynamically-typed
    • easy
    • embeddable
    • evolving
    • expressive
    • extensible
    • fast
    • fun
    • functional
    • garbage-collected
    • general-purpose
    • homoiconic
    • immutable
    • interactive
    • interop
    • multi-paradigm
    • portable
    • powerful
    • productive
    • safe
    • scientific
    • small
    • stable
    • statically-typed
    • tooling
    • web
    • widely-used

Який вигляд мають ці іконки, можна подивитися в розділі з іконками ключових можливостей.

Потрібно вказати рівно 6 ключових можливостей.

Приклад

{
  "key_features": [
    {
      "title": "Fault-tolerant",
      "content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
      "icon": "safe"
    },
    ...
  ],
}

Теги

Треки можна позначати тегами, що дає змогу шукати треки з певною комбінацією тегів.

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

Теги задають у полі tags верхнього рівня, яке визначене як масив рядків тексту. Можна використовувати такі теги (згруповані за категоріями):

Парадигми

  • paradigm/array: мова є мовою масивного програмування
  • paradigm/declarative: мова підтримує декларативний стиль програмування
  • paradigm/functional: мова підтримує функціональний стиль програмування
  • paradigm/imperative: мова підтримує імперативний стиль програмування
  • paradigm/logic: мова підтримує логічний стиль програмування
  • paradigm/object_oriented: мова підтримує обʼєктно-орієнтований стиль програмування
  • paradigm/procedural: мова підтримує процедурний стиль програмування
  • paradigm/stack-oriented: мова підтримує стек-орієнтований стиль програмування

Типізація

  • typing/static: мова використовує статичну типізацію
  • typing/gradual: мова використовує поступову типізацію
  • typing/dynamic: мова використовує динамічну типізацію
  • typing/strong: мова використовує сильну типізацію
  • typing/weak: мова використовує слабку типізацію

Режим виконання

  • execution_mode/compiled: код спершу компілюється, а вже потім виконується
  • execution_mode/interpreted: код інтерпретується безпосередньо

Платформа

  • platform/windows: працює у Windows
  • platform/mac: працює на Mac
  • platform/linux: працює у Linux
  • platform/ios: працює на iOS
  • platform/android: працює на Android
  • platform/web: працює у браузері

Середовище виконання

  • runtime/standalone_executable: працює як окремий виконуваний файл
  • runtime/language_specific: працює на середовищі виконання, специфічному для мови
  • runtime/clr: працює на Common Language Runtime (.NET)
  • runtime/jvm: працює на JVM (Java)
  • runtime/beam: працює на BEAM (Erlang)
  • runtime/wasmtime: працює на Wasmtime (WebAssembly)

Для чого використовують

  • used_for/artificial_intelligence: штучний інтелект
  • used_for/backends: Backends
  • used_for/cross_platform_development: кросплатформна розробка
  • used_for/embedded_systems: вбудовані системи
  • used_for/financial_systems: фінансові системи
  • used_for/frontends: Frontends
  • used_for/games: ігри
  • used_for/guis: графічні інтерфейси користувача (GUI)
  • used_for/mobile: мобільні застосунки
  • used_for/robotics: робототехніка
  • used_for/scientific_calculations: наукові обчислення
  • used_for/scripts: скрипти
  • used_for/web_development: веброзробка

Зауважмо, що цілком нормально включати кілька тегів з однієї категорії.

Приклад

{
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}

Приклад

Ось приклад того, як може мати вигляд коректний файл config.json:

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  },
  "exercises": {
    "concept": [
      {
        "slug": "lucians-luscious-lasagna",
        "name": "Lucian's Luscious Lasagna",
        "uuid": "7d358894-4fbd-4c91-b49f-d68f1c5aa6bc",
        "concepts": [
          "basics"
        ],
        "prerequisites": []
      },
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      }
    ],
    "practice": [
      {
        "slug": "hello-world",
        "name": "Hello, World!",
        "uuid": "6c88f46b-5acb-4fae-a6ec-b48ae3f8168f",
        "practices": [
          "strings"
        ],
        "prerequisites": [
          "basics"
        ],
        "difficulty": 1
      },
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 2,
        "status": "beta"
      }
    ]
  },
  "concepts": [
    {
      "uuid": "2eb4a463-355f-46ef-ac55-a75ec5afdf86",
      "slug": "basics",
      "name": "Basics"
    },
    {
      "uuid": "4466e33e-dcd2-4b1f-9d9d-2c4315bf5188",
      "slug": "if-statements",
      "name": "If Statements"
    },
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers"
    },
    {
      "uuid": "7a86561d-173b-45c0-a53c-1ffd7b9ff259",
      "slug": "strings",
      "name": "Strings"
    }
  ],
  "key_features": [
    {
      "title": "Modern",
      "content": "C# is a modern, fast-evolving language.",
      "icon": "expressive"
    },
    {
      "title": "Cross-platform",
      "content": "C# runs on almost any platform and chipset.",
      "icon": "cross-platform"
    },
    {
      "title": "Multi-paradigm",
      "content": "C# is primarily an object-oriented language, but also has lots of functional features.",
      "icon": "multi-paradigm"
    },
    {
      "title": "General purpose",
      "content": "C# can be used for a wide variety of workloads, like websites, console applications, and even games.",
      "icon": "general-purpose"
    },
    {
      "title": "Tooling",
      "content": "C# has excellent tooling, with linting and advanced refactoring options built-in.",
      "icon": "tooling"
    },
    {
      "title": "Documentation",
      "content": "Documentation is excellent and exhaustive, making it easy to get started with C#.",
      "icon": "documentation"
    }
  ],
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}