3  التكرار

لماذا؟؟؟

التعيين النسبي

كثيرًا ما نريد زيادة العدد أو إنقاصه؛ لذلك وضعت بايثون ما يسمى التعيين النسبي (Augmented Assignment). فجمل التعيين التالية متكافئة:

  • x = x + 1 تعادل x += 1
  • x = x - 1 تعادل x -= 1
  • x = x * 2 تعادل x *= 2
  • x = x / 2 تعادل x /= 2

جرب النص البرمجي أدناه لترى النتيجة:

i = 0
i = i + 1
i += 1
print(i)
2

جملة التعيين المشروط

تستطيع في بايثون أن تجعل جملة التعيين تأخذ قيمتها بحسب شرطٍ معين. مثلاً:

flowchart TD
    IF{{if age > 14}}
    IF -- False --> S2["status = 'child'"]
    IF -- True --> S1["status = 'adult'"]

    style IF fill:#82aeff, stroke:#333, stroke-width:2px;
    linkStyle 0 color:red;

age = 18
status = 'adult' if age > 14 else 'child'

print(status)
adult

وهي مكافئة للنص البرمجي التالي:

age = 18

if age > 14:
  status = 'adult'
else:
  status = 'child'

print(status)
adult

ويحصل تسلسل التعيين المشروط بالصيغة التالية:

score = 75
grade = "A" if score >= 90 else "B" if score >= 80 else "C"
print(grade)
C

flowchart TD
  S1["score = 75"] --> IF1
  IF1{{if score >= 90}} -- True --> A["grade = 'A'"]
  IF1 -- False --> IF2{{if score >= 80}} -- True --> B["grade = 'B'"]
  IF2 -- False --> C["grade = 'C'"]
  
  style IF1 fill:#82aeff, stroke:#333, stroke-width:2px;
  style IF2 fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 2,4 color:red;

تضمين الجمل الشرطية

جمل الشرط المضمنة هي جمل if داخل جمل if أخرى. على سبيل المثال:

flowchart TD
  IF1{{if condition_1}}
  IF1 -- False --> ELSE1
  IF1 -- True --> IF2{{if condition_2}}
  IF2 -- False --> code_2
  IF2 -- True --> code_1
  ELSE1[code_3]

  style IF1 fill:#82aeff, stroke:#333, stroke-width:2px;
  style IF2 fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 0,2 color:red;

if <boolean expression>:
    if <boolean expression>:
        <code>
    else:
        <code>
else:
    <code>

ننبه مرة أخرى أن المحاذاة مهمة. يجب أن تكون جملة if الداخلية ذات محاذاة أكثر من جملة if الخارجية.

مثال

افترض أننا نريد تعيين درجة لطالب بناءً على نتيجته، وفقًا للجدول التالي:

Mark Grade
95-100 A+
90-94 A
85-89 B+
80-84 B
70-79 C
60-69 D
0-59 F
score = 95

if score >= 90:
  if score >= 95:
    print("Outstanding: A+")
  else:
    print("Excellent: A")

elif score >= 80:
  if score >= 85:
    print("Very Good: B+") 
  else:
    print("Good: B")

elif score >= 70:
  print("Okay: C")

elif score >= 60:
  print("Poor: D")

else:
  print("Failed: F")
Outstanding: A+

وهذا تصوير له:

التكرار

حلقة التكرار: هي الرجوع بالتنفيذ لجملة سابقة (غالبًا تكون سطرًا سابقًا) وذلك يحصل عددًا من المرات أو معلَّقًا بشرط.

فللتكرار طريقتان:

  • سرد مكرر (for): حيث يعيَّن متغير التكرار لكل عنصر في المكرر، واحدًا تلوَ الآخر. (وسيأتي ذكره في باب الجمع المرتب)
  • التكرار بشرط (while): حيث يستمر التكرار مادام الشرط متحققًا. (وهو موضوع هذا القسم)

التكرار بشرط

نبدأ بالتكرار بالطريقة غير المحددة، وهي جُملة تبدأ بالكلمة while على النحو التالي. كأنها if متكررة إلى حين تخلُّف الشرط (أن يصبح False). وإن لم يتحقق الشرط أصلاً فلا ينفذ القطعة المضمَّنة أصلا:

flowchart TD
  WHILE{{while condition}}
  WHILE -- False --> END
  WHILE -- True --> S1[code] --> WHILE
  
  style WHILE fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 0 color:red;

while <boolean expression>:
    <code>

مثال:

flowchart TD
  S0["i = 0"] --> WHILE{{"while i < 5"}}
  WHILE -- False --> S3["Done"]
  WHILE -- True --> S1["print(i)"] --> S2["i += 1"] --> WHILE

  style WHILE fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 0 color:red;

i = 0
while i < 5:
    print(i)
    i += 1
print('Done')
0
1
2
3
4
Done

لنقم بتتبع الخطوات عندما تكون i = 0:

  1. 0 < 5 تؤول True، فنطبع 0 ونزيد i لتصبح 1
  2. 1 < 5 تؤول True، فنطبع 1 ونزيد i لتصبح 2
  3. 2 < 5 تؤول True، فنطبع 2 ونزيد i لتصبح 3
  4. 3 < 5 تؤول True، فنطبع 3 ونزيد i لتصبح 4
  5. 4 < 5 تؤول True، فنطبع 4 ونزيد i لتصبح 5
  6. 5 < 5 تؤول False،فنخرج من الحلقة
  7. نطبع Done

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

لاحظ أن نسيان جملة الزيادة (i += 1) يجعل الشرط دائمًا صحيحًا، فيدور البرنامج في حلقة لا نهيائة ولا يخرج أبدًا. ويعتبر هذا خطأ برمجيًّا يتعذر على البرنامج التعامل معه بنفسه؛ بل يجب على المبرمج أن يكتشفه. وسيأتي الكلام عن أنواع الأخطاء في البرمجة في باب الأخطاء.

الخروج من الحلقة

  • تستخدم كلمة break لإيقاف عملية التكرار كلها.
  • تستخدم كلمة continue للانتقال إلى الكرة التالية متخطيةً بقية الخطوات في الكرة الحالية.

أولاً نمثل لاستعمال جملة break على النحو التالي:

flowchart TD
  S0["i = 0"] --> WHILE{{"while i < 5"}}
  WHILE -- False --> Done["Done"]
  WHILE -- True --> IF1{{"if i == 3"}}
  IF1 -- break --> Done
  IF1 -- False --> S1["print(i)"] --> S2["i += 1"] --> WHILE

  style WHILE fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 1,4 color:red;

i = 0
while i < 5:
    if i == 3:
        break
    print(i)
    i += 1
print('Done')
0
1
2
Done

وهذا مثال لاستخدام عبارة continue للتخطي:

flowchart TD
  S0["i = 0"] --> WHILE{{"while i < 5"}}
  WHILE -- False --> Done["Done"]
  WHILE -- True --> IF1{{"if i == 3"}}
  IF1 -- True --> S3["i += 1"]
  S3 -- continue -->  WHILE
  IF1 -- False --> S1["print(i)"] --> S2["i += 1"] --> WHILE

  style WHILE fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 1,5 color:red;
  linkStyle 4 color:blue;

i = 0
while i < 5:
    if i == 3:
        i += 1
        continue
    print(i)
    i += 1
print('Done')
0
1
2
4
Done

أما جملة break المضمنة تحت طبقتين من التكرار فإن الذي يتوقف هو التكرار الداخلي فقط، ولا يتوقف الخارجي. وهذا مثال:

flowchart TD
  INIT1["i = 0"] --> WHILE1
  WHILE1{{"while i < 3"}}
    S3["i += 1"] --> WHILE1
    WHILE1 -- True --> INIT2["j = 0"] --> WHILE2
    WHILE2{{"while j < 3"}}
      WHILE2 -- True --> IF1{{"if i == 1"}} -- break --> WHILE1
      IF1 -- False --> S1["print(i, j)"] --> S2["j += 1"] --> WHILE2
    WHILE2 -- False --> S3

  style WHILE1 fill:#82aeff, stroke:#333, stroke-width:2px;
  style WHILE2 fill:#82aeff, stroke:#333, stroke-width:2px;
  linkStyle 5,8 color:red;

i = 0
while i < 3:
    j = 0
    while j < 3:
        if i == 1:
            break
        print(i, j)
        j += 1
    i += 1
print('Done')
0 0
0 1
0 2
2 0
2 1
2 2
Done

الملحق بعدم المطابقة

تعتبر بايثون بعض القيَم تابعة لعدم المطابقة (False) وهي:

  • False
  • None
  • 0
  • 0.0
  • ''
  • []
  • ()
  • {}
  • set()

وما عدا ذلك فملحق بالمطابقة (True).

if False or None or 0 or 0.0 or '' or [] or () or {} or set():
    print('True')
else:
    print('False')
False