برمجة بايثون 2026 — جامعة هلسنكي › الجزء 3: الحلقات 3 / 15 السابق التالي

الحلقات مع الشروط

أهداف التعلّم

بعد إتمام هذا القسم

  • ستعرف كيف تنشئ حلقة while مع شرط
  • ستعرف ما الأدوار التي تؤدّيها التهيئة وصياغة الشرط وتحديث المتغيّرات في الحلقة
  • ستتمكّن من إنشاء حلقات بأنواع مختلفة من الشروط

عن تمارين هذه الدورة

يتطلب أن تصير مبرمجًا ماهرًا الكثير من التدريب، بل أحيانًا تدريبًا ميكانيائيًّا في جوهره. كما أنه ينطوي على تنمية مهارات حلّ المشكلات وتطبيق الحدس. ولهذا تحتوي هذه الدورة على الكثير من التمارين بأنواع مختلفة. فبعضها يطلب منك تطبيق ما تعلّمته في المادة تطبيقًا مباشرًا إلى حدٍّ كبير، لكن بعضها الآخر متعمَّد أكثر ويتّسم بأنه مفتوح النهاية.

قد يبدو بعض التمارين مربكًا في البداية، لكن لا داعي للقلق. فليس أيٌّ من التمارين إلزاميًّا بشكل قاطع، وفي الحقيقة لا تحتاج سوى إلى 25 % من نقاط كل جزء لاجتياز الدورة. ويمكنك العثور على مزيد من التفاصيل حول اجتياز الدورة في صفحة الدرجات.

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

وحين يصبح الأمر صعبًا حتمًا، فعليك بكلمة عزاء: فالمهمة التي تبدو صعبة إلى حدٍّ مستحيل هذا الأسبوع من المرجح أن تبدو سهلة إلى حدٍّ كبير بعد نحو أربعة أسابيع.

في القسم السابق تعلّمنا استخدام حلقة while True لتكرار أجزاء من الشيفرة. وفي هذه الصيغة يكون شرط الحلقة هو True، أي أن الشرط يتحقّق في كل مرة. وكنا نحتاج إلى الخروج من الحلقة صراحةً في كل مرة تفاديًا لحلقة لا نهائية. فمثلًا:

# Print numbers until the variable a equals 5
a = 1
while True:
    print(a)
    a += 1
    if a == 5:
        break
1
2
3
4

بالطبع، لا يجب أن يكون الشرط هو True دائمًا، بل يمكن استخدام أي تعبير منطقي (Boolean) كشرط. والهيكل العام لجملة while هو كما يلي:

while <condition>:
    <block>

الفكرة هنا أن التنفيذ يمضي ذهابًا وإيابًا، متحقّقًا في كل مرة مما إذا كان الشرط صحيحًا، ومنفِّذًا الشيفرة داخل الكتلة مرارًا وتكرارًا. وإذا كان الشرط خاطئًا في أي لحظة، فإن تنفيذ البرنامج يتابع من السطر الذي يلي كتلة while.

3_1_1.png

في الحلقة التالية يكون الشرط هو number < 10. ولا تُنفَّذ الكتلة داخل الحلقة إلا إذا كان المتغيّر number أقل من 10.

number = int(input("Please type in a number: "))

while number < 10:
    print(number)
    number += 1

print("Execution finished.")

قد يطبع هذا ما يلي:

Please type in a number: **4**
4
5
6
7
8
9
Execution finished.

في هذه البنية يُفحص الشرط دائمًا قبل تنفيذ الكتلة داخل الحلقة. وقد يحدث ألّا تُنفَّذ الكتلة أبدًا، مثل الآتي:

Please type in a number: **12**
Execution finished.

12 ليس أقل من 10، ولذلك لا يطبع البرنامج أي عدد على الإطلاق.

التهيئة والشرط والتحديث

لإنشاء حلقة ستحتاج غالبًا إلى تضمين ثلاث خطوات متمايزة: التهيئة، والشرط، وتحديث متغيّرات التكرار.

يقصد بـ_التهيئة_ (initialisation) ضبط القيمة أو القيم الأولى للمتغيّر أو المتغيّرات المستخدَمة في شرط الحلقة. وكثيرًا ما تُسمَّى هذه بتغيّرات التكرار (iteration) أو بالمُتكرِّرات (iterator). وتُنفَّذ هذه الخطوة قبل دخول الحلقة لأول مرة. أما الشرط (condition) فيحدّد المدة التي يُنفَّذ فيها الحلقة، إذ يُكتب في البدايات تمامًا من الحلقة. وأخيرًا، في كل تكرار من تكرارات الحلقة تُحَدَّث المتغيّراتُ المشاركة في الشرط، بحيث يقرب كل تكرار الحلقة خطوة واحدة من نهايتها. وتوضّح الصورة التالية هذه الخطوات:

3_1_2.png

إذا غاب أيٌّ من هذه المكونات الثلاثة، فلن تعمل الحلقة على الأرجح على نحو صحيح. ومن الأخطاء النموذجية إغفال خطوة التحديث:

number = 1

while number < 10:
    print(number)

print("Execution finished.")

هنا لا تتغيّر قيمة المتغيّر number أبدًا. فالبرنامج عالق في حلقة لا نهائية، وتتكرّر القطعة نفسها من الشيفرة بالضبط مرارًا وتكرارًا حتى يوقف المستخدم التنفيذ، مثلًا بالضغط على Control + C:

1
1
1
1
1
(continued ad infinitum...)

تمرين تفاعلي: طباعة الأعداد

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

ينبغي أن تبدو مخرجاتك كما يلي:

2
4
6
8
etc...

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.

تمرين تفاعلي: إصلاح الشيفرة: العدّ التنازلي

في البرنامج التالي بعض المشكلات النحوية:

print("Are you ready?")
number = int(input("Please type in a number: "))
while number = 0:
print(number)
print("Now!")

يُرجى إصلاحه بحيث يطبع ما يلي:

Are you ready?
Please type in a number: **5**
5
4
3
2
1
Now!

هذا التمرين مشابه لتمرين العدّ التنازلي في القسم الأخير، لكن يُرجى ألّا تستخدم حلقة while True في هذه المرة!

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.

كتابة الشروط

أي تعبير منطقي (Boolean)، أو أي دمج thereof، هو شرط صالح في الحلقة. فمثلًا، يطبع البرنامج التالي كل ثالث عدد، لكن فقط ما دام العدد أقل من 100 وغير قابل للقسمة على 5:

number = int(input("Please type in a number: "))

while number < 100 and number % 5 != 0:
    print(number)
    number += 3

مثالان لتنفيذ البرنامج بمُدخَلات مختلفة:

Please type in a number: **28**
28
31
34
37
Please type in a number: **96**
96
99

حين يكون المُدخَل هو 28 تنتهي الحلقة عند العدد 37، لأن العدد التالي هو 40، وهو قابل للقسمة على 5. وحين يكون المُدخَل هو 96 تنتهي الحلقة عند العدد 99، لأن العدد التالي هو 102، وهو ليس أقل من 100.

متى ما كتبت حلقة، ينبغي أن تتأكّد من أن تنفيذ الحلقة سينتهي دائمًا عند نقطة ما. والبرنامج التالي إما أن ينتهي أو لا ينتهي، حسب المُدخَل:

number = int(input("Please type in a number: "))

while number != 10:
    print(number)
    number += 2

إذا كان المُدخَل عددًا زوجيًا ويساوي 10 أو أقل، فإن الحلقة ستتوقّف:

Please type in a number: **4**
4
6
8

في أي حالة أخرى تُنفَّذ الحلقة بلا نهاية، إذ لا سبيل أبدًا لأن يساوي المتغيّر 10. فمثلًا، المُدخَلات 3 أو 12 مُدخَلات تنتهي في حلقة لا نهائية.

تمرين تفاعلي: الأعداد

يُرجى كتابة برنامج يطلب من المستخدم عددًا. ثم يطبع البرنامج جميع الأعداد الصحيحة الأكبر من الصفر والأصغر من المُدخَل.

Upper limit: **5**
1
2
3
4

يُرجى ألّا تستخدم القيمة True كشرط لحلقة while في هذا التمرين!

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.

نصائح للتنقيح

تخيّل أنك تكتب برنامجًا أعقد قليلًا، مثل البرنامج في التمرين التالي، قوى العدد 2. قد تبدو المحاولات الأولى كالتالي:

limit = int(input("Upper limit:"))
number = 1
while number == limit:
   # more code

هنا يبدأ البرنامج بقراءة المُدخَل، ثم يتابع الهيكل العام للحلقة مع محاولة أوّلية لكتابة شرط.

من المرجح ألا تعمل الشيفرة كما هو مرغوب في المحاولة الأولى. وقد يلزم اختبارها عشرات المرات بل مئات المرات قبل أن تعمل على نحو صحيح.

إن هذه القطعة من الشيفرة تطلب مُدخَلًا من المستخدم في كل مرة، ما يجعل اختبارها بطيئًا ومرهقًا. فمع كل اختبار للبرنامج يجب كتابة المُدخَل.

وإحدى طرق تفادي ذلك هي «الترميز الثابت» (hard-coding) للمُدخَل أثناء الاختبار:

# let's hard-code the input value for testing
limit = 8 # int(input("Upper limit"))
number = 1
while number == limit:
   # more code 

وحين يعمل البرنامج مع المُدخَل المرمَّز ثابتًا الواحد، يسهل اختباره بمُدخَلات أخرى مرمَّزة ثابتًا كذلك. وحين يبدو أنه يعمل على نحو صحيح في كل الأحوال، يمكن اختباره بمُدخَل من المستخدم.

تنفع هذه الحيلة مع كثير من الاختبارات التي تُقيَّم بها تمارين هذه الدورة. فإذا أخبرك الاختبار بأن البرنامج يعمل على نحو خاطئ عندما يكون المُدخَل هو، مثلًا، 42، فيمكن ترميز ذلك المُدخَل ثابتًا في البرنامج وأنت تبحث عن مصدر الخطأ:

# the test said the program works incorrectly when the input is 42
limit = 42 # int(input("Upper limit"))
number = 1
while number == limit:
   # more code

سبق أن ذُكر التنقيح بعبارات الطباعة عدة مرات في الجزء السابق من الدورة. وستصبح البرامج التي يُطلب منك كتابتها أكثر تعقيدًا كلما تقدّمت الدورة. ومن المرجح أن يزيد مقدار التنقيح الذي ستحتاج إليه تبعًا لذلك. والأسباب الشائعة للأخطاء تكمن في الشروط التي تنهي الحلقات؛ فقد تعمل على نحو صحيح مع بعض المُدخَلات وتفشل مع غيرها، وليس سبب ذلك ظاهرًا دائمًا.

ولهذا فقد حان وقت أن تُدرج التنقيح بعبارات الطباعة ضمن ممارساتك البرمجية، إن لم تكن قد فعلت ذلك من قبل. ويمكنك العثور على تعليمات التنقيح في القسم الأول والقسم الرابع من الجزء السابق.

إلى جانب عبارات الطباعة، توجد أدوات كثيرة أخرى يمكن استخدامها في التنقيح. ومن بينها أداة التمثيل المرئي على موقع Python Tutor. وتتيح لك الأداة تنفيذ شيفرتك سطرًا بسطر، كما تُريك القيمَ المخزّنة في المتغيّرات عند كل خطوة.

في الصورة التالية نرى الشيفرة المعطوبة قليلًا من مثال التنقيح في القسم السابق ممثَّلةً بواسطة Python Tutor:

3_1_3.png

يشير السهم الأحمر إلى الموضع الذي بلغه تنفيذ البرنامج في هذه اللحظة. وتعرض الأداة ما طُبع حتى الآن، كما تُريك القيمة التي يملكها كل متغيّر عند كل خطوة. ويتقدّم التنفيذ سطرًا بسطر عند الضغط على Next.

كل ما عليك فعله لاستخدام أداة التمثيل المرئي هو نسخ شيفرتك ولصقها في نافذة الشيفرة في الأداة. وللأداة بعض القيود مقارنةً بإصدار Python المستخدَم في هذه الدورة. فإذا صادفتك رسائل أخطاء غامضة، فقد يكون من الأفضل تجربة طريقة تنقيح أخرى.

نادرًا ما يكون المبرمجون ذوو الخبرة من المستخدمين المكثّفين لأداة التمثيل المرئي، لكنها قد تكون عونًا ثمينًا للمبتدئ. والبرمجة بوصفها تخصّصًا لا تترك مكانًا يذكر للحظ أو للصدفة. ومن الضروري أن يفهم المبرمج القيمَ التي تُنشئها شيفرته في أي لحظة من لحظة التنفيذ. فإذا لم تكن القيم المخزّنة في المتغيّرات كما هو متوقّع، فعلى الأرجح يوجد خطأ في البرنامج.

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

تمرين تفاعلي: قوى العدد 2

يُرجى كتابة برنامج يطلب من المستخدم إدخال حدّ أعلى. ثم يطبع البرنامج أعدادًا بحيث يكون كل عدد بعده مزدوجَ العدد الذي يسبقه، انطلاقًا من العدد 1. أي أن البرنامج يطبع قوى العدد 2 بالترتيب.

ينتهي تنفيذ البرنامج حين يصبح العدد التالي الذي ستُطبعه أكبر من الحدّ الذي ضبطه المستخدم. ولا ينبغي طباعة أي أعداد أكبر من الحدّ.

Upper limit: **8**
1
2
4
8
Upper limit: **20**
1
2
4
8
16
Upper limit: **100**
1
2
4
8
16
32
64

يُرجى ألّا تستخدم القيمة True كشرط لحلقة while في هذا التمرين!

ما هي قوى العدد 2؟ القوة الأولى للعدد 2 هي العدد 1. والتي تليها هي 1 في 2، أي 2. والتي تليها هي 2 في 2، أي 4. والتي تليها هي 4 في 2، أي 8، وهكذا. فكل قوة في المتتالية تُضرب في اثنين لإنتاج القوة التالية.

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.

تمرين تفاعلي: قوى الأساس n

يُرجى تغيير البرنامج في التمرين السابق بحيث يقوم المستخدم أيضًا بإدخال الأساس الذي يُضرب فيه (في البرنامج السابق كان الأساس دائمًا 2).

Upper limit: **27**
Base: **3**
1
3
9
27
Upper limit: **1234567**
Base: **10**
1
10
100
1000
10000
100000
1000000

يُرجى ألّا تستخدم القيمة True كشرط لحلقة while في هذا التمرين!

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.

تمرين تفاعلي: مجموع الأعداد المتتالية، النسخة 1

يُرجى كتابة برنامج يطلب من المستخدم إدخال حدّ. ثم يحسب البرنامج مجموع الأعداد المتتالية (1 + 2 + 3 + ...) حتى يصبح المجموع مساويًا على الأقل للحدّ الذي ضبطه المستخدم. وينبغي أن يعمل البرنامج كالتالي:

Limit: **2**
3
Limit: **10**
10
Limit: **18**
21

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

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.

بناء السلاسل النصية

في الأسبوع الأول من الدورة تعلّمنا أنه من الممكن «بناء» السلاسل النصية من سلاسل نصية أقصر باستخدام المشغّل +. فمثلًا، هذه شيفرة Python صحيحة:

words = "pride"
words = words + ", prejudice"
words = words + " and python"

print(words)
pride, prejudice and python

يتيح لنا المشغّل += كتابة هذا بأسلوب أكثر اختصارًا قليلًا:

words = "pride"
words += ", prejudice"
words += " and python"

print(words)

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

course = "Introduction to Programming"
grade = 4

verdict = "You have received "
verdict += f"the grade {grade} "
verdict += f"from the course {course}"

print(verdict)
You have received the grade 4 from the course Introduction to Programming

في التمرين السابق حسبتَ مجموعَ الأعداد المتتالية عبر إضافة قيمة جديدة داخل حلقة في كل مرة.

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

تمرين تفاعلي: مجموع الأعداد المتتالية، النسخة 2

يُرجى كتابة نسخة جديدة من البرنامج في التمرين السابق. وبالإضافة إلى النتيجة، ينبغي له أيضًا أن يطبع العملية الحسابية التي أُجريت:

Limit: **2**
The consecutive sum: 1 + 2 = 3
Limit: **10**
The consecutive sum: 1 + 2 + 3 + 4 = 10
Limit: **18**
The consecutive sum: 1 + 2 + 3 + 4 + 5 + 6 = 21

ويمكنك افتراض أن العدد الذي يكتبه المستخدم يساوي دائمًا 2 أو أكثر.

ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.