تمارين التطبيق


التمارين التطبيقية هي تمارين مصممة لتتيح للطلاب حل مسألة يختارونها، بهدف استخدام المفاهيم التي تعلموها حتى الآن.

هل ترغب في إضافة أول تمرين تطبيقي لك إلى مسار؟ اطّلع على وثائق إضافة تمرين تطبيقي أو شاهد فيديو الشرح التوضيحي 👇

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، أو دمج السلاسل النصية، أو تعداد المحارف، وغيرها، ستكون كلها أمثلة جيدة.

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 (التنفيذ المثالي)
        ├── Isogram.cs (التنفيذ الأولي)
        └── IsogramTests.cs (الاختبارات)

ملف: .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: رابط المصدر الذي يستند إليه هذا التمرين (اختياري)
  • 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 يحدّد الأسلوب بشكل فريد. يجب أن يكون المعرّف فريدًا داخل المسار وكذلك عبر جميع المسارات، ويجب ألا يتغيّر أبدًا
    • slug: معرّف slug للأسلوب، وهو سلسلة نصية بحروف صغيرة وبنمط kebab-case. يجب أن يكون الـ slug فريدًا عبر جميع معرّفات slugs الأساليب داخل المسار. يجب أن يكون طوله أقل من أو يساوي 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 فريدًا عبر جميع معرّفات slugs المقالات داخل المسار. يجب أن يكون طوله أقل من أو يساوي 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.

مثال

using System;

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

ملف: الاختبارات

الغرض: التحقق من صحة الحل.

الوجود: مطلوب

  • ينبغي أن يكون الكود بسيطًا قدر الإمكان.
  • استخدم فقط ميزات اللغة التي تقدّمها المتطلبات المسبقة للتمرين (ومتطلباتها المسبقة، وهكذا).
  • يُعرض ملف الاختبارات على الطالب عند البرمجة داخل المتصفح، ويُحمَّل إلى نظام ملفات الطالب عند استخدام واجهة سطر الأوامر.
  • يفضّل 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"));
}

ملف: التنفيذ المثالي

الغرض: توفير تنفيذ نموذجي يجتاز جميع الاختبارات.

الوجود: مطلوب

  • يُستخدم هذا التنفيذ للتحقق من وجود تنفيذ يجتاز الاختبارات. وهو ليس عمدًا الكود المستهدف الذي نريد أن يسعى إليه الطالب.
  • ينبغي لكل مسار أن يتحقق من أن التنفيذ المثالي يجتاز الاختبارات في إعداد التكامل المستمر الخاص به.
  • لن يُعرض هذا الكود على الموجّهين.
  • لا يُعرض الملف المثالي على الطالب عند البرمجة داخل المتصفح، ولا يُحمَّل إلى نظام ملفات الطالب عند استخدام واجهة سطر الأوامر.
  • يجب تحديد المسارات النسبية إلى ملف (ملفات) التنفيذ المثالي في مفتاح "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، والتي بدونها لا يمكن تشغيل الاختبارات.

ملفات مشتركة

بعض الملفات ليست خاصة بتمارين فردية، بل تنطبق على جميع التمارين. راجع الوثائق لمزيد من المعلومات.

العرض

هناك فرق في كيفية عرض وثائق التمرين على الطالب عند استخدام المحرّر داخل المتصفح مقابل استخدام واجهة سطر الأوامر. راجع هذا المستند لمزيد من المعلومات.

الأيقونة

لكل تمرين أيقونة مرافقة. افتراضيًا، الأيقونة المعروضة هي التي يطابق اسمها معرّف slug الخاص بالتمرين. ويمكن تجاوز ذلك بتحديد خاصية icon في ملف .meta/config.json الخاص بالتمرين.

إذا كنت تنفّذ تمرينًا من بيانات problem-specifications الوصفية، فمن المرجح أن هناك أيقونة لهذا التمرين بالفعل. وإن لم تكن موجودة، فيرجى فتح تذكرة في مستودع website-icons.