تمرینهای مفهومی تمرینهایی هستند که برای آموزش مفاهیم مشخص (برنامهنویسی) طراحی شدهاند. مفاهیمی که تمرینهای مفهومی آموزش میدهند، یک سرفصل را شکل میدهند. برای اطلاعات بیشتر دربارهی چگونگی طراحی یک سرفصل، مستندات سرفصل را ببینید.
میتوانید با اجرای دستورهای زیر از پوشهی ریشهی ترک، بهسرعت ساختار اولیهی یک تمرین مفهومی تازه را بسازید:
bin/fetch-configlet
bin/configlet create --concept-exercise <slug>
برای اطلاعات بیشتر، مستندات configlet create را ببینید.
فرادادهی تمرین مفهومی در کلید exercises.concept در فایل config.json تعریف میشود. این فراداده، UUID، اسلاگ و موارد دیگر تمرین را مشخص میکند.
{
"exercises": {
"concept": [
{
"uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
"slug": "cars-assemble",
"name": "Cars, Assemble!",
"concepts": ["if-statements", "numbers"],
"prerequisites": ["basics"]
}
]
}
}
هر تمرین مفهومی پوشهی خودش را درون پوشهی exercises/concept ترک دارد. اسم پوشهی تمرین مفهومی باید با ویژگی slug آن تمرین، که در فایل config.json تعریف شده است، مطابقت داشته باشد.
هر تمرین مفهومی چهار نوع فایل دارد:
این فایلها به دانشجو نشان داده میشوند تا به توضیح تمرین کمک کنند.
.docs/introduction.md: مفهوم یا مفاهیمی را که تمرین به دانشجو میآموزد معرفی میکند (الزامی).docs/instructions.md: دستورالعملهای تمرین را ارائه میدهد (الزامی).docs/hints.md: راهنماییهایی به دانشجو میدهد تا اگر در تمرین گیر کرد، خودش از بنبست بیرون بیاید (الزامی)این فایلها به دانشجو نشان داده نمیشوند، اما برای تعریف فرادادهی تمرین به کار میروند.
.meta/config.json: فرادادهی تمرین را در خود دارد (الزامی).meta/design.md: طراحی تمرین را توصیف میکند (الزامی)این فایلها رویکردهای تمرین را توصیف میکنند.
.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
└── concept
└── cars-assemble
├── .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
| └── Exemplar.cs (exemplar implementation)
├── CarsAssemble.cs (stub implementation)
└── CarsAssemblyTests.cs (tests)
ما برای تمرینهای تازه، رویکرد «ادغام خوشبینانه» را ترجیح میدهیم؛ یعنی ترکها میتوانند تمرینها را در وضعیت «کار در جریان» توسعه دهند. حداقل وضعیت معتبر، که configlet را پاس میکند و به شما اجازهی ادغام میدهد، این است:
config.json ترک، با status برابر با wip..meta/config.json
.docs/introduction.md.docs/instructions.md.docs/hints.md.docs/introduction.md
هدف: معرفی مفهوم یا مفاهیمی که تمرین به دانشجو میآموزد.
وجود: الزامی
about.md آن مفهوم بماند.برای نمونه، مقدمهی یک تمرین «رشتهها» ممکن است رشته را فقط «دنبالهای از نویسههای یونیکد» یا «زنجیرهای از بایتها» توصیف کند، به کاربران بگوید چطور یک رشته بسازند، و توضیح دهد که رشته متدهایی دارد که میتوان با آنها آن را دستکاری کرد. مگر آنکه دانشجو برای حل تمرین نیاز به فهم جزئیات دقیقتری داشته باشد، همین نوع توضیح کوتاه (بههمراه نمونهای از نحوهی نگارش آن) باید برای حل تمرین کافی باشد.
# Introduction
There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in snake case. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator:
```ruby
my_first_variable = 1
my_first_variable = "Some string"
my_first_variable = SomeComplexObject.new
```
.docs/introduction.md.tpl
هدف: قالبی برای تولید فایل introduction.md از آن.
وجود: اختیاری
سند introduction.md مفهوم یا مفاهیم تمرین را به دانشجو معرفی میکند. هر مفهوم همچنین introduction.md خودش را دارد که بیرون از بافت یک تمرین نمایش داده نمیشود.
اگر مقدمهی مفهوم باید عیناً در مقدمهی تمرین گنجانده شود، میتوان از فایل introduction.md.tpl استفاده کرد. این فایل اجازه میدهد با جاگیرندهها به مقدمههای مفهوم ارجاع دهید: %{concept:<concept-slug>}.
configlet میتواند از یک فایل قالب، فایل introduction.md تولید کند. در فایل تولیدشده، جاگیرندههای مفهوم با محتوای introduction آن مفهوم جایگزین میشوند.
وبسایت Exercism فقط سند introduction.md را میشناسد. وقتی از فایل قالب استفاده میشود، تولید introduction.md وظیفهی ترک است.
ترکها میتوانند برای هر تمرین تصمیم بگیرند که از قالب استفاده کنند یا نه. در بعضی موارد، آوردن عین مقدمهی مفهوم ممکن است بهینه نباشد. همیشه همان را انتخاب کنید که بهترین تجربهی یادگیری را برای دانشجو فراهم میکند.
# Introduction
%{concept:variables}
.docs/instructions.md
هدف: ارائهی دستورالعملهای تمرین.
وجود: الزامی
این فایل به دو بخش تقسیم میشود.
هر وظیفه باید این استانداردها را رعایت کند:
## 1. Do X، ## 2. Do Y).## 1. Check if an appointment has already passed).Implement method X(...) that takes an A and returns a Z)،برای ما بسیار مهم است که محتوای Exercism برای همه امن باشد و به همین دلیل هنگام تصمیمگیری دربارهی مناسب بودن یا نبودن یک داستان، اغلب جانب احتیاط را نگه میداریم. هرچند در ادغامها دقت میکنیم، میدانیم که آگاه بودن از آنچه ممکن است مشکلدار به نظر برسد دشوار است؛ پس همیشه فرض میکنیم شما با حسن نیت عمل میکنید و در بازبینی، بدون برخورد، تلاش میکنیم هر مشکلی را پیدا کنیم. اگر میخواهید داستانی را با ما بررسی کنید، لطفاً @exercism/leadership را منشن کنید تا با هم نگاهش کنیم. در ادامه چند نکتهی راهنما آمده است:
# Instructions
In this exercise you're going to write some code to help you cook a brilliant lasagna from your favorite cooking book.
## 1. Calculate the remaining oven time in minutes
Define the `Lasagna#remaining_minutes_in_oven` method that takes the actual minutes the lasagna has been in the oven as a parameter and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task.
```ruby
lasagna = Lasagna.new
lasagna.remaining_minutes_in_oven(30)
# => 10
```
.docs/hints.md
هدف: ارائهی راهنماییهایی به دانشجو تا وقتی در تمرین گیر میکند خودش از بنبست بیرون بیاید.
وجود: الزامی
## General بیایند.instructions.md مطابقت دارند (مثلاً ## 2. Do Y).## 2. Check if a book can be borrowed).Implement the 'canBorrowBook' function to check if a book can be borrowed. The function takes a book as its parameter and returns `true` if the book has not already been borrowed; otherwise, return `false`).دیدن راهنماییها مسیر «توصیهشده» به شمار نمیرود و ما (بهنرمی) استفاده از آن را جز وقتی دانشجو بدون آن نمیتواند پیش برود، تشویق نمیکنیم. به همین دلیل، خوب است در نظر بگیرید که دانشجویی که آن را میخواند کمی گیج یا سردرگم و شاید کلافه باشد.
# Hints
## General
- You need to define a [constant][constant] which should contain the [integer][integers] value specified in the recipe.
## 1. Calculate the remaining oven time in minutes
- You need to define a [method][methods] with a single parameter for the actual time so far.
[constants]: https://www.rubyguides.com/2017/07/ruby-constants/
[integers]: https://ruby-doc.org/core-2.7.0/Integer.html
[methods]: https://launchschool.com/books/ruby/read/methods
هدف: توصیف طراحی تمرین.
وجود: الزامی
این فایل اطلاعاتی دربارهی طراحی تمرین دارد؛ مواردی مانند هدف آن، اهداف آموزشیاش، آنچه نباید آموزش داده شود و بیشتر. این اطلاعات را میتوان از ایشوی GitHub متناظر با تمرین برداشت.
این فایل وجود دارد تا نگهدارندهها یا مشارکتکنندههای آینده را از دامنه و محدودیتهای یک تمرین آگاه کند و از گرایش طبیعی به پیچیدهتر شدن تمرینها در گذر زمان جلوگیری کند.
# Design
## Goal
The goal of this exercise is to teach the student the basics of programming in Ruby.
## Learning objectives
- Know what a variable is.
- Know how to define a variable.
- Know how to update a variable.
## Out of scope
- Memory and performance characteristics.
- Method overloads.
## Concepts
The Concepts this exercise unlocks are:
- `basics`: know what a variable is; know how to define a variable; know how to update a variable.
## Prerequisites
There are no prerequisites.
.meta/config.json
هدف: شامل فرادادهی تمرین است.
وجود: الزامی
این فایل فرادادهی تمرین را در خود دارد:
authors: اسم کاربری GitHub نویسنده(های) تمرین (الزامی)
contributors: اسم کاربری GitHub مشارکتکننده(های) تمرین (اختیاری)
forked_from: تمرین یا تمرینهایی که این تمرین از آنها فورک شده است (اگر تمرین فورک شده باشد، الزامی است)files: مکان فایلهای بهکاررفته در این تمرین، نسبت به پوشهی تمرین (الزامی)
solution: فایل(های) پیادهسازی استاب (الزامی)test: فایل(های) تست (الزامی)exemplar: فایل(های) پیادهسازی معیار (الزامی)editor: فایلهای دیگری که در ویرایشگر بهصورت فقطخواندنی نمایش داده میشوند (اختیاری)invalidator: فایلهایی که با تغییرشان، راهحل از رده خارج میشود (اختیاری)language_versions: الزامات نسخهی زبان (اختیاری)blurb: توصیف کوتاهی از این تمرین. طولش باید کمتر یا مساوی ۳۵۰ باشد. از Markdown پشتیبانی نمیشود (الزامی)source: منبعی که این تمرین بر آن مبتنی است (اختیاری)source_url: نشانی منبعی که این تمرین بر آن مبتنی است (اختیاری)representer: فرادادهی مربوط به نحوهی پردازش این فایل توسط representer (اختیاری)
version: عددی صحیح برای نسخهی representer که در تمرین استفاده میشود (اگر کلید والد موجود باشد، الزامی است)icon: اسلاگ آیکون (فهرست کامل آیکونها را در این نشانی ببینید). اگر مشخص نشود، از اسلاگ تمرین استفاده میشود (اختیاری)custom: هر دادهی غیراستاندارد و مخصوص تمرین. میتوان از آن برای سفارشیسازی رفتار ابزارهای ترک در هر تمرین استفاده کرد (اختیاری)اگر کسی هم نویسنده و هم مشارکتکننده است، او را فقط بهعنوان نویسنده فهرست کنید.
{
"authors": ["FSharpForever"],
"files": {
"solution": ["Lasagna.fs"],
"test": ["LasagnaTests.fs"],
"exemplar": [".meta/Exemplar.fs"]
},
"blurb": "Learn the basics of F# by cooking Lucian's Luscious Lasagna"
}
فرض کنید کاربر FSharpForever تمرینی به اسم log-levels برای ترک F# نوشته است. PythonProfessor این تمرین را برای ترک Python تطبیق میدهد. بعدها کاربر GladToHelp تمرین را بهبود میدهد.
{
"authors": ["PythonProfessor"],
"contributors": ["GladToHelp"],
"files": {
"solution": ["log_levels.py"],
"test": ["log_levels_test.py"],
"exemplar": [".meta/exemplar.py"],
"editor": ["test_helper.py"]
},
"forked_from": ["fsharp/log-levels"],
"language_versions": ">=3.7",
"blurb": "Learn how to work with strings by processing log lines.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Log_file",
"representer": {
"version": 2
},
"icon": "logs",
"custom": {
"parallel": true
}
}
توجه کنید که:
forked_from درست است.language_versions رشتهای آزاد است و ترکها میتوانند هرطور که میخواهند از آن استفاده و تفسیرش کنند..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 نسخهی ۴ که رویکرد را بهطور یکتا مشخص میکند. این UUID باید هم درون ترک و هم در میان همهی ترکها یکتا باشد و هرگز تغییر نکندslug: اسلاگ رویکرد، که رشتهای با حروف کوچک و بهشکل kebab-case است. این اسلاگ باید میان همهی اسلاگهای رویکرد در ترک یکتا باشد. طولش باید کمتر یا مساوی ۲۵۵ باشد.title: عنوان رویکرد. طولش باید کمتر یا مساوی ۲۵۵ باشد.blurb: توصیف کوتاهی از این رویکرد. طولش باید کمتر یا مساوی ۳۵۰ باشد. از 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» تمرین نمایش داده میشود.
تعداد خطوطش باید کمتر یا مساوی ۸ باشد.
برای اطلاعات بیشتر دربارهی آنچه باید در این فایل بیاید، مستندات را ببینید.
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 نسخهی ۴ که مقاله را بهطور یکتا مشخص میکند. این UUID باید هم درون ترک و هم در میان همهی ترکها یکتا باشد و هرگز تغییر نکندslug: اسلاگ مقاله، که رشتهای با حروف کوچک و بهشکل kebab-case است. این اسلاگ باید میان همهی اسلاگهای مقاله در ترک یکتا باشد. طولش باید کمتر یا مساوی ۲۵۵ باشد.title: عنوان مقاله. طولش باید کمتر یا مساوی ۲۵۵ باشد.blurb: توصیف کوتاهی از این مقاله. طولش باید کمتر یا مساوی ۳۵۰ باشد. از 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» تمرین نمایش داده میشود.
تعداد خطوطش باید کمتر یا مساوی ۸ باشد.
برای اطلاعات بیشتر دربارهی آنچه باید در این فایل بیاید، مستندات را ببینید.
| Method | Mean | Allocated |
| -----: | --------: | --------: |
| Linq | 29.133 ns | 80 B |
| Array | 4.806 ns | - |
هدف: فراهم کردن نقطهی شروعی برای دانشجو.
وجود: الزامی
"files.solution" فایل .meta/config.json مشخص شوند.class Lasagna
def remaining_minutes_in_oven(actual_minutes_in_oven)
raise NotImplementedError, 'Please implement the Lasagna#remaining_minutes_in_oven method'
end
def preparation_time_in_minutes(layers)
raise NotImplementedError, 'Please implement the Lasagna#preparation_time_in_minutes method'
end
end
هدف: بررسی درستی راهحل.
وجود: الزامی
instructions.md استفاده کنند."files.test" فایل .meta/config.json مشخص شوند.require 'minitest/autorun'
require_relative 'lasagna'
class LasagnaTest < Minitest::Test
def test_remaining_minutes_in_oven
assert_equal 15, Lasagna.new.remaining_minutes_in_oven(25)
end
def test_preparation_time_in_minutes_with_one_layer
assert_equal 2, Lasagna.new.preparation_time_in_minutes(1)
end
def test_preparation_time_in_minutes_with_multiple_layers
assert_equal 8, Lasagna.new.preparation_time_in_minutes(4)
end
end
هدف: ارائهی پیادهسازی هدفی که دانشجو باید به آن برسد.
وجود: الزامی
"files.exemplar" فایل .meta/config.json مشخص شوند.class Lasagna
EXPECTED_MINUTES_IN_OVEN = 40
PREPARATION_MINUTES_PER_LAYER = 2
def remaining_minutes_in_oven(actual_minutes_in_oven)
EXPECTED_MINUTES_IN_OVEN - actual_minutes_in_oven
end
def preparation_time_in_minutes(layers)
layers * PREPARATION_MINUTES_PER_LAYER
end
end
هدف: تضمین اینکه تستها بتوانند اجرا شوند.
وجود: اگر فایلهای پیشفرض برای اجرای تستها کافی نباشند، الزامی است
بعضی زبانها برای اجرای تستها به فایلهای اضافی نیاز دارند. نمونههایی از اینها فایلهای پروژهی C# و فایلهای package.json در Node هستند که بدون آنها اجرای تستها ممکن نیست.
بعضی فایلها مخصوص تمرینهای تکتک نیستند، بلکه به همهی تمرینها مربوط میشوند. برای اطلاعات بیشتر مستندات را ببینید.
تمرینهای مفهومی باید بر اساس داستان/تمشان نامگذاری شوند، نه بر اساس مفهوم یا مفاهیمشان.
نمونههای خوب اسم:
Tim from MarketingLucian's Luscious LasagnaCalculator Conundrumاسمهای نامجاز:
Booleans: از اسم مفهوم استفاده میکند، نه اسم داستانExercise #1: یک تمرین داستان/تم نیستوقتی تمرینی را بدون تغییرات اساسی فورک میکنید، در صورت امکان از اسم اصلی استفاده کنید.
هر تمرین همچنین یک اسلاگ دارد که نسخهی نرمالشدهی اسم تمرین است و بر پایهی قواعد زیر ساخته میشود:
[a-z0-9-]+)two-fer بهجای 2-fer)نمونههای خوب اسلاگ:
tim-from-marketinglucians-luscious-lasagnacalculator-conundrumاسلاگهای نامجاز:
TIM-FROM-MARKETING: از حروف کوچک استفاده نمیکند (یعنی tim-from-marketing)TimFromMarketing: از kebab-case استفاده نمیکند (یعنی tim-from-marketing)floating-point-numbers: از اسم مفهوم استفاده میکند، نه اسم داستاننحوهی نمایش مستندات تمرین به دانشجو هنگام استفاده از ویرایشگر درونمرورگری با هنگام استفاده از CLI تفاوت دارد. برای اطلاعات بیشتر این سند را ببینید.
هر تمرین یک آیکون همراه دارد.
بهطور پیشفرض، آیکونی نمایش داده میشود که اسمش با اسلاگ تمرین مطابقت دارد.
میتوان این را با مشخص کردن ویژگی icon در فایل .meta/config.json تمرین تغییر داد.
اگر تمرین موجودی را فورک میکنید، احتمالاً از قبل آیکونی برای آن تمرین وجود دارد. اگر نه، لطفاً یک ایشو در مخزن website-icons باز کنید.