تمارين المفاهيم هي تمارين مصمّمة لتعليم مفاهيم (برمجية) محدّدة. وتشكّل المفاهيم التي تعلّمها تمارين المفاهيم منهجًا. لمزيد من المعلومات حول كيفية تصميم منهج، اطّلع على توثيق المنهج.
يمكنك إنشاء هيكل تمرين مفهوم جديد بسرعة بتشغيل الأوامر التالية من الدليل الجذر للمسار:
bin/fetch-configlet
bin/configlet create --concept-exercise <slug>
لمزيد من المعلومات، اطّلع على توثيق configlet create
تُعرَّف البيانات الوصفية لتمرين المفهوم في المفتاح exercises.concept داخل ملف config.json. وتحدّد البيانات الوصفية معرّف UUID الخاص بالتمرين وقيمة slug والمزيد.
{
"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 (التنفيذ النموذجي)
├── CarsAssemble.cs (التنفيذ المبدئي)
└── CarsAssemblyTests.cs (الاختبارات)
نفضّل نهج «الدمج المتفائل» مع التمارين الجديدة، حيث يمكن للمسارات تطوير التمارين في حالة «قيد العمل». والحد الأدنى من الحالة الصالحة، التي ستجتاز 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
.meta/design.md
الغرض: وصف تصميم التمرين.
التواجد: مطلوب
يحتوي هذا الملف على معلومات حول تصميم التمرين، تشمل أشياء مثل هدفه، وأهدافه التعليمية، وما ينبغي عدم تدريسه، وغير ذلك. ويمكن استخراج هذه المعلومات من مشكلة 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: وصف قصير لهذا التمرين. ويجب أن يكون طوله <= 350. لا يُدعم Markdown (مطلوب)source: المصدر الذي يستند إليه هذا التمرين (اختياري)source_url: رابط المصدر الذي يستند إليه هذا التمرين (اختياري)representer: معلومات وصفية تتعلق بكيفية معالجة representer لهذا الملف (اختياري)
version: عدد صحيح لإصدار representer المستخدم للتمرين (مطلوب إذا وُجد المفتاح الأب)icon: قيمة slug الخاصة بالأيقونة (انظر القائمة الكاملة للأيقونات). وإذا لم تُحدَّد، فستُستخدم قيمة slug الخاصة بالتمرين (اختياري)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 من الإصدار V4 يميّز الأسلوب تمييزًا فريدًا. ويجب أن يكون المعرّف فريدًا داخل المسار وعلى مستوى جميع المسارات، وألّا يتغير أبدًا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
الغرض: مقتطف يعرض الأسلوب
التواجد: اختياري (مطلوب للأساليب)
يحتوي هذا الملف على مقتطف صغير يعرض الأسلوب. ويُعرض المقتطف في صفحة «التعمّق أكثر» الخاصة بالتمرين.
ويجب أن يكون عدد أسطره <= 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 يميّز المقالة تمييزًا فريدًا. ويجب أن يكون المعرّف فريدًا داخل المسار وعلى مستوى جميع المسارات، وألّا يتغير أبدًا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
الغرض: مقتطف يعرض الأسلوب
التواجد: اختياري (مطلوب للمقالات)
يحتوي هذا الملف على مقتطف صغير يعرض المقالة. ويُعرض المقتطف في صفحة «التعمّق أكثر» الخاصة بالتمرين.
ويجب أن يكون عدد أسطره <= 8.
اطّلع على التوثيق لمزيد من المعلومات حول ما ينبغي أن يحتويه هذا الملف.
| 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: التمرين ليس قصة أو فكرةعند نسخ تمرين دون تغييرات جوهرية، استخدم الاسم الأصلي إن أمكن.
slug
لكل تمرين أيضًا قيمة slug، وهي نسخة معياريّة من اسم التمرين وفق القواعد التالية:
[a-z0-9-]+)two-fer بدلًا من 2-fer)أمثلة جيدة على قيم slug:
tim-from-marketinglucians-luscious-lasagnacalculator-conundrumقيم slug غير مسموح بها:
TIM-FROM-MARKETING: لا يستخدم الحروف الصغيرة (أي tim-from-marketing)TimFromMarketing: لا يستخدم kebab-case (أي tim-from-marketing)floating-point-numbers: يستخدم اسم مفهوم، لا اسم قصةهناك اختلاف في طريقة عرض توثيق التمرين للطالب عند استخدام المحرر داخل المتصفح مقابل استخدام واجهة سطر الأوامر. اطّلع على هذا المستند لمزيد من المعلومات.
لكل تمرين أيقونة مصاحبة.
وبشكل افتراضي، تكون الأيقونة المعروضة هي التي يطابق اسمها قيمة slug الخاصة بالتمرين.
ويمكن تجاوز ذلك بتحديد خاصية icon في ملف .meta/config.json الخاص بالتمرين.
إذا كنت تنسخ تمرينًا موجودًا، فمن المحتمل أن تكون هناك أيقونة له بالفعل. وإن لم توجد، فيرجى فتح مشكلة في مستودع website-icons.