الحلقات في بايثون: كرّر أي شيء بـ for و while

تعلّم حلقة for مع range()، وحلقة while بشرط، وأوقف التكرار بـ break، وتخطَّ دورة بـ continue، وتجنّب الحلقة التي لا تنتهي.

تخيّل أن معلّمك طلب منك كتابة الأعداد من 1 إلى 100 على السبورة. هل ستكتب print(1) ثم print(2) وهكذا مئة مرة؟ بالتأكيد لا. في هذا الدرس ستتعلّم كيف تجعل بايثون تكرّر أي عمل بدلًا عنك، مئة مرة أو مليون مرة، بسطرين فقط.

🎯 ماذا ستتعلم؟

بنهاية هذا الدرس ستكون قادرًا على:

  • تكرار عمل بعدد محدّد من المرات بحلقة for و range().
  • التحكم في بداية العدّ ونهايته وخطوته.
  • كتابة حلقة while تستمر ما دام الشرط صحيحًا.
  • إيقاف الحلقة في منتصفها بـ break، وتخطّي دورة واحدة بـ continue.
  • تجنّب الحلقة التي لا تنتهي أبدًا.

🧰 ماذا تحتاج قبل أن تبدأ؟

يجب أن تعرف المتغيّرات و القوائم، وأن تكتب شرطًا بسيطًا بـ if كما في درس الشروط. كل الأمثلة تعمل في مترجم بايثون في المتصفح بدون تثبيت.

الفكرة ببساطة

عندما تسمع أغنية فيها لازمة تتكرّر، لا يكتب المؤلّف الكلمات نفسها كل مرة. يكتب “تُعاد اللازمة 3 مرات” وينتهي الأمر.

هذا بالضبط ما تفعله الحلقة (loop) في بايثون. تكتب الأسطر التي تريد تكرارها مرة واحدة، وتخبر بايثون كم مرة تعيدها، أو إلى متى تستمر.

في بايثون نوعان من الحلقات. حلقة for تناسب التكرار بعدد معروف، مثل “لكل لاعب في الفريق”. وحلقة while تناسب التكرار ما دام شرط ما صحيحًا، مثل “ما دامت الطاقة أكبر من صفر”.

الخطوة 1: تذكير سريع بحلقة for

تذكّر من درس القوائم: حلقة for تأخذ عناصر القائمة واحدًا واحدًا، وتنفّذ الأسطر التي تحتها لكل عنصر.

subjects = ["رياضيات", "علوم", "عربي"]
for subject in subjects:
    print("عندي حصة", subject)
عندي حصة رياضيات
عندي حصة علوم
عندي حصة عربي

الأسطر التي تبدأ بمسافة بادئة هي جسم الحلقة (loop body). بايثون تنفّذها مرة لكل عنصر، ثم تكمل البرنامج بعد الحلقة.

الخطوة 2: العدّ بـ range()

ماذا لو أردت التكرار 5 مرات بدون قائمة؟ الدالة range() تصنع لك سلسلة أعداد جاهزة للحلقة. اكتب بين قوسيها عدد المرات:

for number in range(5):
    print("الدورة رقم", number)
الدورة رقم 0
الدورة رقم 1
الدورة رقم 2
الدورة رقم 3
الدورة رقم 4

لاحظ أمرين مهمّين. الأول أن العدّ يبدأ من صفر، تمامًا كفهارس القوائم. الثاني أن range(5) تعطي 5 أعداد فعلًا، لكنها تتوقف قبل الرقم 5 نفسه.

وإذا أردت أن يبدأ العدّ من رقم معيّن، اكتب البداية ثم النهاية. هنا نطبع درجات السلّم من 1 إلى 5:

for step in range(1, 6):
    print("الدرجة", step)
الدرجة 1
الدرجة 2
الدرجة 3
الدرجة 4
الدرجة 5

تذكّر القاعدة: البداية تُطبع، والنهاية لا تُطبع. لذلك كتبنا 6 لنصل إلى 5.

الخطوة 3: القفز بخطوات

الرقم الثالث في range() هو الخطوة (step)، أي كم نقفز في كل مرة. هنا نعدّ الأعداد الزوجية من 2 إلى 10:

for even in range(2, 11, 2):
    print(even)
2
4
6
8
10

بدأنا من 2، وقفزنا خطوتين في كل مرة، وتوقفنا قبل 11. ويمكنك أيضًا العدّ إلى الخلف بخطوة سالبة، كما في العدّ التنازلي قبل إطلاق صاروخ:

for count in range(5, 0, -1):
    print(count)
print("انطلاق! 🚀")
5
4
3
2
1
انطلاق! 🚀

لاحظ أن print("انطلاق! 🚀") بدون مسافة بادئة، لذلك ينفَّذ مرة واحدة بعد انتهاء الحلقة.

🚀 للمتقدمين: range() لا تصنع قائمة كاملة في الذاكرة. تنتج الأعداد واحدًا واحدًا عند الحاجة، لذلك range(1000000) لا تستهلك ذاكرة تُذكر. وإذا أردت رؤية أعدادها كقائمة، اكتب list(range(1, 6)).

الخطوة 4: حلقة while تستمر ما دام الشرط صحيحًا

أحيانًا لا تعرف عدد المرات مسبقًا. تعرف فقط متى تتوقف. هنا تأتي حلقة while، وتقرأ هكذا: “ما دام الشرط صحيحًا، كرّر”.

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

energy = 3
while energy > 0:
    print("قفزة! الطاقة المتبقية:", energy)
    energy = energy - 1
print("انتهت الطاقة، استرح قليلًا")
قفزة! الطاقة المتبقية: 3
قفزة! الطاقة المتبقية: 2
قفزة! الطاقة المتبقية: 1
انتهت الطاقة، استرح قليلًا

في كل دورة تفحص بايثون الشرط energy > 0 أولًا. إذا كان صحيحًا تنفّذ الجسم، وإذا صار خاطئًا تخرج من الحلقة.

السطر energy = energy - 1 هو الأهم في الحلقة. بدونه تبقى الطاقة 3 إلى الأبد، ولا تتوقف الحلقة أبدًا. سنعود لهذا الخطأ في قسم الأخطاء الشائعة.

يمكنك اختصار سطر الإنقاص بكتابة energy -= 1. وبالمثل count += 1 تعني count = count + 1.

الخطوة 5: إيقاف الحلقة بـ break

الكلمة break تعني “اخرج من الحلقة الآن”، حتى لو بقيت عناصر أو كان الشرط ما زال صحيحًا.

تخيّل أنك تبحث عن اسمك في قائمة طويلة. عندما تجده، لا داعي لإكمال البحث:

names = ["هند", "عمر", "سارة", "يوسف", "مريم"]
for name in names:
    print("نفحص:", name)
    if name == "سارة":
        print("وجدناها! نتوقف هنا")
        break
نفحص: هند
نفحص: عمر
نفحص: سارة
وجدناها! نتوقف هنا

الحلقة لم تصل إلى “يوسف” ولا “مريم”، لأن break أخرجتها فور العثور على الاسم.

الخطوة 6: تخطّي دورة بـ continue

الكلمة continue ألطف من break. تقول: “تجاهل بقية هذه الدورة، وانتقل إلى الدورة التالية”. الحلقة لا تتوقف، بل تقفز خطوة.

هنا نطبع الدرجات الناجحة فقط، ونتخطّى ما هو أقل من 50:

grades = [85, 42, 90, 30, 67]
for grade in grades:
    if grade < 50:
        continue
    print("ناجح بدرجة", grade)
ناجح بدرجة 85
ناجح بدرجة 90
ناجح بدرجة 67

عندما تكون الدرجة 42، ينفَّذ continue، فتقفز بايثون فوق سطر print وتأخذ الدرجة التالية.

🚀 للمتقدمين: في بايثون يمكن أن يكون للحلقة قسم else يُنفَّذ مرة واحدة عندما تنتهي الحلقة طبيعيًا، أي بدون break. جرّب حلقة بحث بـ for وضع بعدها else: مع print("لم نجد الاسم"). إذا خرجت الحلقة بـ break فلن تُطبع الرسالة، وإذا انتهت الأسماء كلها بدون عثور فستُطبع. هذا يغنيك عن متغيّر إضافي لتتبّع النتيجة.

⚠️ أخطاء شائعة

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

1. الحلقة التي لا تنتهي

❌ هذا الكود لا يتوقف أبدًا، لا تجرّبه
count = 1
while count <= 5:
    print(count)

نسينا زيادة count، فيبقى 1 دائمًا والشرط صحيح إلى الأبد. هذه تسمّى الحلقة اللانهائية (infinite loop). تأكّد دائمًا أن شيئًا داخل الحلقة يغيّر الشرط:

# ✅ نزيد العدّاد في كل دورة
count = 1
while count <= 5:
    print(count)
    count += 1
1
2
3
4
5

2. توقّع أن range(10) تصل إلى 10

❌ نتوقع أن يُطبع 10، لكنه لا يُطبع
for number in range(10):
    print(number)

آخر عدد يُطبع هو 9. النهاية في range() لا تُطبع أبدًا. إذا أردت 10 اكتب 11:

# ✅ نكتب النهاية زائد واحد
for number in range(8, 11):
    print(number)
8
9
10

3. break خارج الحلقة

❌
score = 0
if score == 0:
    break
SyntaxError: 'break' outside loop

الكلمتان break و continue تعملان داخل حلقة فقط. ضعهما داخل جسم for أو while:

# ✅ break داخل الحلقة
for attempt in range(1, 4):
    print("محاولة", attempt)
    if attempt == 2:
        break
محاولة 1
محاولة 2

🧪 جرّب بنفسك

التحدي 1: جدول الضرب

اطبع جدول ضرب الرقم 7 من 1 إلى 10 بحلقة for و range(). كل سطر بالشكل: 7 x 3 = 21.

# غيّر الحلقة لتطبع الجدول كاملًا من 1 إلى 10
for i in range(1, 3):
    print(7, "x", i, "=", 7 * i)
7 x 1 = 7
7 x 2 = 14
💡 اضغط لرؤية الحل
for i in range(1, 11):
    print(7, "x", i, "=", 7 * i)
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70

التحدي 2: مصروف الأسبوع

عندك 20 ريالًا، وتشتري كل يوم عصيرًا بـ 3 ريالات. استخدم حلقة while لتطبع المبلغ المتبقي بعد كل يوم، وتتوقف عندما لا يكفي المال لعصير جديد.

money = 20
# اكتب حلقة while تنقص 3 ما دام المال يكفي
print("المتبقي:", money)
المتبقي: 20
💡 اضغط لرؤية الحل
money = 20
day = 0
while money >= 3:
    money -= 3
    day += 1
    print("اليوم", day, "المتبقي:", money)
print("لا يكفي المال لعصير جديد")
اليوم 1 المتبقي: 17
اليوم 2 المتبقي: 14
اليوم 3 المتبقي: 11
اليوم 4 المتبقي: 8
اليوم 5 المتبقي: 5
اليوم 6 المتبقي: 2
لا يكفي المال لعصير جديد

التحدي 3: الأعداد الزوجية حتى إشارة التوقف

عندك قائمة أرقام. اطبع الأعداد الزوجية فقط، وتوقف تمامًا عندما تصل إلى الرقم 237. تذكّر أن number % 2 == 0 تعني أن العدد زوجي. ستحتاج continue و break معًا.

numbers = [12, 7, 40, 33, 8, 237, 50, 64]
# اطبع الزوجي فقط، وتوقف عند 237
for number in numbers:
    print(number)
12
7
40
33
8
237
50
64
💡 اضغط لرؤية الحل
numbers = [12, 7, 40, 33, 8, 237, 50, 64]
for number in numbers:
    if number == 237:
        break
    if number % 2 == 1:
        continue
    print(number)
12
40
8

✅ اختبر نفسك

  1. كم عددًا تطبع الحلقة for x in range(3, 8):؟

    • أ) 5
    • ب) 6
    • ج) 8
  2. ماذا تفعل continue داخل الحلقة؟

    • أ) توقف الحلقة نهائيًا
    • ب) تتخطّى بقية الدورة الحالية وتنتقل للدورة التالية
    • ج) تعيد الحلقة من البداية
  3. صح أم خطأ: حلقة while تفحص شرطها قبل كل دورة، وتتوقف عندما يصير الشرط خاطئًا.

💡 اضغط لرؤية الإجابات
  1. أ) 5، وهي الأعداد 3 و 4 و 5 و 6 و 7. النهاية 8 لا تُطبع.
  2. ب)، continue تقفز فوق بقية الجسم فقط، أما التي توقف الحلقة نهائيًا فهي break.
  3. صح. ولذلك يجب أن يغيّر شيء داخل الحلقة قيمة الشرط، وإلا صارت حلقة لانهائية.

📝 الخلاصة

  • حلقة for تكرّر جسمها لكل عنصر في قائمة، أو لكل عدد تنتجه range().
  • range(start, stop, step) تبدأ من start، وتتوقف قبل stop، وتقفز بمقدار step.
  • حلقة while تستمر ما دام الشرط صحيحًا، ويجب أن يتغيّر شيء داخلها حتى تتوقف.
  • break تخرج من الحلقة فورًا، و continue تتخطّى الدورة الحالية فقط.
  • الحلقة اللانهائية أشهر خطأ في while، والحل أن تعدّل قيمة الشرط في كل دورة.

⏭️ الخطوة التالية

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