طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 101 · تركيب البيانات والخوارزميات
الدرس 3 · الوحدة 2: تحليل وتقييم الخوارزميات

كتابة الخوارزمية والتحقق من صحتها

كيف تكتب خوارزمية واضحة، وكيف تتأكد أنها صحيحة في كل الحالات؟ ⏱ نحو 25 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تتبع مراحل حل المسألة: الفهم، فشبه الكود، فالتنفيذ والاختبار.
  • تكتب الخوارزمية بشبه الكود ثم تحوّلها إلى بايثون.
  • تتتبع الخوارزمية خطوة بخطوة.
  • تختبر صحة الخوارزمية بالحالات الحدّية و assert.

١من الفكرة إلى الكود: ثلاث مراحل

المبرمج المحترف لا يبدأ بكتابة الكود. يكتب الخوارزمية أولًا بلغة واضحة، ثم يحوّلها إلى كود، ثم يختبرها.

المرحلةالمثال: هل القائمة مرتبة تصاعديًّا؟
1. فهم المسألةالمدخل: قائمة أرقام. المخرج: True أو False.
2. الخوارزمية بشبه الكودلكل عنصرين متجاورين: إن كان الأيسر أكبر من الأيمن فالجواب False. إن انتهت القائمة دون ذلك فالجواب True.
3. التنفيذ والاختبارنكتب الدالة، ونجربها على حالات مختلفة.

٢شبه الكود Pseudocode

شبه الكود وصف للخطوات بلغة قريبة من الكود، لكنه لا يلتزم بقواعد لغة معينة. الهدف: أن تفكّر في الحل دون أن تشغلك الأقواس والنقطتان.

خوارزمية: هل القائمة مرتبة؟
المدخل: قائمة a فيها n عنصرًا
1. لكل موقع i من 0 إلى n − 2:
    2. إذا كان a[i] أكبر من a[i + 1]: أرجع «لا»
3. أرجع «نعم»
main.py
def is_sorted(a):    for i in range(len(a) - 1):        if a[i] > a[i + 1]:            return False    return True print(is_sorted([2, 5, 9, 14]))print(is_sorted([2, 9, 5, 14]))
Shell×
>>> %Run main.py
True
False
>>>

٣تتبّع الخوارزمية خطوة بخطوة

اضغط «التالي» وراقب i والمقارنة في كل خطوة. التتبع اليدوي أقوى أداة لفهم الخوارزمية واكتشاف أخطائها:

🔎 تتبّع: هل [3, 8, 6] مرتبة؟
main.py
def is_sorted(a):    for i in range(len(a) - 1):        if a[i] > a[i + 1]:            return False    return True print(is_sorted([3, 8, 6]))
Variables · المتغيّرات في الذاكرة
Shell×

٤الاختبار: هل الخوارزمية صحيحة دائمًا؟

نجاح الخوارزمية في مثال واحد لا يثبت صحتها. نختبرها بحالات مقصودة، وأهمها الحالات الحدّية Edge Cases: الأطراف التي ينساها المبرمج.

نوع الحالةمثالالجواب المتوقع
عادية[1, 4, 9]True
الخلل في الآخر[1, 4, 9, 2]False
قائمة فارغة[]True
عنصر واحد[7]True
قيم مكررة[3, 3, 3]True
أرقام سالبة[-5, -2, 0]True

والأمر assert يتحقق أن الشرط صحيح، ويوقف البرنامج برسالة خطأ إن لم يكن. هكذا نكتب اختبارات تلقائية:

main.py
def is_sorted(a):    for i in range(len(a) - 1):        if a[i] > a[i + 1]:            return False    return True assert is_sorted([1, 4, 9]) == Trueassert is_sorted([1, 4, 9, 2]) == Falseassert is_sorted([]) == Trueassert is_sorted([7]) == Trueassert is_sorted([3, 3, 3]) == Trueassert is_sorted([-5, -2, 0]) == Trueprint("نجحت كل الاختبارات")
Shell×
>>> %Run main.py
نجحت كل الاختبارات
>>>

٥حين يكشف الاختبار خطأً

هذه نسخة فيها خطأ شائع في حد الحلقة. لاحظ كيف تكشفه حالة بسيطة:

main.py
def is_sorted(a):    for i in range(len(a)):        # خطأ: i تصل إلى آخر موقع        if a[i] > a[i + 1]:            return False    return True print(is_sorted([1, 2, 3]))
Shell×
>>> %Run main.py
Traceback (most recent call last):
File "main.py", line 7, in <module>
print(is_sorted([1, 2, 3]))
File "main.py", line 3, in is_sorted
if a[i] > a[i + 1]:
IndexError: list index out of range
>>>

عند i = 2 يحاول البرنامج قراءة a[3]، وهي غير موجودة. الحد الصحيح range(len(a) - 1)؛ لأن آخر مقارنة بين العنصرين الأخيرين.

توقّع وتحقّق

وصف الخطوات بلغة قريبة من الكود دون قواعد لغة معينة:

Pseudocode.

أي حالة حدّية مهمة لاختبار دالة تعمل على قائمة؟

الطرف الأدنى.

ماذا يفعل assert حين يكون الشرط خطأ؟

AssertionError.

للمقارنة بين كل عنصر وتاليه نمر بـ i في:

آخر زوج: الموقعان n-2 و n-1.

الخلاصة

تحدٍّ برمجي: عدد مرات الظهور مع اختبارات

متوسط

اكتب دالة count_of(a, x) تُرجع عدد مرات ظهور x في القائمة a دون استخدام a.count، ثم اختبرها بالحالات الحدّية.

المطلوب:
  • حلقة تمر على العناصر وعدّاد.
  • اختبارات assert: قائمة فارغة، وعنصر غير موجود، وعنصر مكرر، وقائمة كل عناصرها x.
  • اطبع في الأخير: نجحت الاختبارات

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
def count_of(a, x):    pass # اختباراتك هنا
المطلوب×
نجحت الاختبارات
💡 تلميح 1
ابدأ العدّاد بصفر قبل الحلقة.
💡 تلميح 2
assert count_of([], 5) == 0

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
def count_of(a, x):    n = 0    for v in a:        if v == x:            n += 1    return n assert count_of([], 5) == 0assert count_of([1, 2, 3], 9) == 0assert count_of([4, 1, 4, 4], 4) == 3assert count_of([7, 7], 7) == 2print("نجحت الاختبارات")
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس