الرئيسية » المراجع العلمية » علوم الكمبيوتر » الحلقات والقوائم والأساسيات في بايثون

الحلقات والقوائم والأساسيات في بايثون

أساسيات البرمجة - الحلقات والقوائم والأساسيات في بايثون

آخر تحديث: أكتوبر 3, 2022

الحلقات والقوائم والأساسيات في بايثون

في مشروعك الأول، تعرفت على العديد من الموضوعات الأساسية في البرمجة. ستحتاج إلى الأدوات والأساليب التي استخدمتها لكتابة لعبة Angry Goblin لأي برمجة ستفعلها في المستقبل. في هذا الفصل، ستستكشف المزيد من اللبنات الأساسية التي ستحتاجها لكتابة برامج الكمبيوتر، بما في ذلك المزيد من الحلقات والقوائم.

ولكن قبل الانتقال للتعرف على الأدوات الجديدة، أود أن أقدم لكم الغرفة البيضاء The White Room.

الغرفة البيضاء

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

عندما تفتح ملف Python جديدًا وفارغًا في محررك، فإنك تنشئ غرفة بيضاء جديدة. على الرغم من أن ملف Python الخاص بك لا يزال فارغًا، فإن الغرفة البيضاء ليست فارغة تمامًا. على الرف السفلي يوجد كتيب أحمر صغير يسمى “مضمن” built-in. يحتوي هذا الكتيب على عدد صغير نسبيًا من كلمات بايثون تساعدك في البدء. كما يتضمن الوظائف أو الدوال الأساسية والكلمات الرئيسية التي يمكنك الوصول إليها على الفور، مثل دالة الطباعة print() والإدخال input()، ودوال الجمل الشرطية if وwhile.

يجب أن يكون البرنامج قادرًا على العثور على مرجع لأي كلمة تكتبها في البرنامج. الكلمة يجب أن تكون في مكان ما في الغرفة البيضاء. في الوقت الحالي، المكان الوحيد الذي يمكن لبايثون أن تبحث فيه هو الكتيب الأحمر الصغير المسمى “مضمن” built-in، لأن هذا هو العنصر الوحيد في الغرفة البيضاء.

يمكنك فتح ملف جديد وكتابة:

print

لا يوجد إخراج عند تشغيل البرنامج أعلاه، ولكن وراء الكواليس، يبحث برنامج الكمبيوتر حول الغرفة البيضاء لمحاولة العثور على مرجع لكلمة print. سيجده في الكتيب “مضمن”، وبالتالي سيكون البرنامج مقتنعًا بأنه وجد هذه الكلمة. يعرف بايثون ما تعنيه هذه الكلمة لأنه تمكن من العثور عليها في الغرفة البيضاء. جرب الآن ما يلي:

Say-hello

عند تشغيل هذا الرمز، ستصلك رسالة الخطأ التالية:

Traceback (most recent call last):
  File "<path>/<filename>.py", line 1, in <module>
    say_hello
NameError: name 'say_hello' is not defined

ستشاهد الأخطاء كثيرًا عند البرمجة، وسنناقشها بمزيد من التفصيل لاحقًا. تخبرك رسالة الخطأ هذه أن برنامج الكمبيوتر بحث في كل مكان في الغرفة البيضاء ولم يتمكن من العثور على كلمة say_hello في أي مكان. يخبرك السطر الأخير من رسالة الخطأ أن الاسم ‘say_hello’ غير محدد. في الوقت الحالي، الشيء الوحيد في الغرفة البيضاء هو الكتيب “المضمن”، وكلمة say_hello ليست موجودة فيه!

عندما أنشأت متغيرات في الفصل الأول وخصصت بيانات للمتغير، وصفت ذلك على أنه إنشاء صندوق تخزين. دعونا نلقي نظرة على هذا السيناريو مع ما يلي:

say_hello = "Hello there, how are you doing today?"

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

من الآن فصاعدًا، عندما تكتب say_hello في برنامجك، سينظر البرنامج حول الغرفة البيضاء، وسيجد شيئًا يحمل التسمية say_hello. إنه صندوق به بعض المحتويات بداخله. لذلك سيقوم برنامج الكمبيوتر بإحضار الصندوق وإحضار ما بداخله، وهو سلسلة الأحرف “مرحبًا، كيف حالك اليوم؟”.

في الوقت الحالي، سأضيف إضافة أخرى إلى الغرفة البيضاء. تشبيه آخر استخدمته في الفصل الأول هو مكتبة كبيرة بها آلاف الكتب. يمكنك استيراد وحدة نمطية باستخدام أمر الاستيراد import. الكلمة الرئيسية المخصصة لأمر الاستيراد import هي إحدى الكلمات الموجودة في الكتيب “المضمن”:

import random

هنا أنت تطلب من برنامج الكمبيوتر الخاص بك مغادرة الغرفة البيضاء، والذهاب إلى المكتبة الكبيرة والبحث عن كتاب يسمى random، ثم إعادته إلى الغرفة البيضاء ووضعه على أحد الرفوف. من الآن فصاعدًا، عندما تكتب كلمة random، سيجد برنامجك كتابًا يسمى random في الغرفة البيضاء. عندما تكتب random، فإنك تطلب من البرنامج إخراج الكتاب من رف الكتب. يمكنك بعد ذلك النظر داخل هذا الكتاب باستخدام تدوينة النقطة random.randint().

سنعود إلى تشبيه الغرفة البيضاء The White Room من وقت لآخر في هذا الكتاب للمساعدة في فهم ما يجري داخل برنامج الكمبيوتر.

كتابة كود جاف DRY Code

هناك نكتة سأشاركها فيما يلي. هناك العديد من النكات في عالم البرمجة، لكن روح الدعابة العامة في البرمجة غريبة بعض الشيء. لقد تم تحذيرك.

الوصايا العشر في البرمجة هي:

  1. لا تكرر نفسك Don’t Repeat Yourself
  2. لا تكرر نفسك Don’t Repeat Yourself
  3. لا تكرر نفسك Don’t Repeat Yourself
  4. لا تكرر نفسك Don’t Repeat Yourself
  5. لا تكرر نفسك Don’t Repeat Yourself
  6. لا تكرر نفسك Don’t Repeat Yourself
  7. لا تكرر نفسك Don’t Repeat Yourself
  8. لا تكرر نفسك Don’t Repeat Yourself
  9. لا تكرر نفسك Don’t Repeat Yourself
  10. لا تكرر نفسك Don’t Repeat Yourself

وبغض النظر عن النكات، فإن مبدأ “لا تكرر نفسك” هو مبدأ أساسي لكل شيء في البرمجة، وغالبًا ما يُشار إليه باستخدام الاختصار DRY.

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

ستسمع كثيرًا عن التعليمات البرمجية التي يجب أن تكون أكثر جفافًا. سترى أنه غالبًا ما توجد طرق عديدة لتحقيق نفس الأهداف في البرمجة، لكن بعض الخيارات أكثر جفافًا من غيرها. الكود الجاف DRY Code أسهل في الحفاظ عليه وأقل عرضة للتسبب في أخطاء.

قد تسمع أيضًا عن رمز WET. كود WET هو كود غير جاف! وإليك حس الفكاهة لدى المبرمجين الذي يتألق مرة أخرى مع محاولات تعديل الاختصار لإنشاء “الاسم الخلفي” لـ WET:

  • نحن نستمتع بالكتابة We Enjoy Typing
  • اكتب كل شيء مرتين Write Everything Twice
  • تضييع وقت الجميع Waste Everyone’s Time

سوف نشير إلى مبدأ الجفاف DRY في كثير من الأحيان.

الحلقات في بايثون Loops

واحدة من أكثر الطرق وضوحًا للحفاظ على الكود الخاص بنا جافًا DRY هي استخدام الحلقات Loops. والحلقة Loop تقوم بتكرار كتلة من التعليمات البرمجية Block. من الجيد لبرنامج الكمبيوتر أن يعيد نفسه لأنه سريع ولا يشعر بالملل. ما نريد تجنبه هو أننا، المبرمجين، لا نكرر أنفسنا.

لقد استخدمت بالفعل إحدى الطرق الرئيسية لإنشاء حلقة في بايثون. في لعبة Angry Goblin، استخدمت الحلقة while loop لتكرار مجموعة من التعليمات البرمجية حتى يخمّن اللاعب موقع العفريت. هناك أداة أساسية ثانية لإنشاء حلقات في بايثون وهي الحلقة for.

الحلقات في بايثون: الحلقة for

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

print("Don't Repeat Yourself")

لكن هذا البيان مهم للغاية لدرجة أنك تريد تكراره 10 مرات وبالتالي تكرر نكتة البرمجة الشهيرة. الخيار الأول هو نسخ السطر ولصقه 10 مرات. لكن هذا لن يتبع مبدأ الكود الجاف DRY. بدلاً من ذلك، يمكنك استخدام حلقة for. لننشئ حلقة for، ثم سنقسم ما يحدث خطوة بخطوة:

for something in range(10):
    print("Don't Repeat Yourself")

عند تشغيل هذا الكود، سترى السطر معروضًا 10 مرات. دعنا نقسم هذين السطرين من التعليمات البرمجية لمعرفة ما يفعله كل شيء:

  • الكلمة الرئيسية for هي إحدى الكلمات الرئيسية في الكتيب “المضمن” التي تشير إلى أننا نريد أن نكتب، كما خمنت، الحلقة for.
  • نطاق الدالة range() هو دالة مضمنة أخرى تُرجع نطاقًا من الأرقام. في هذه الحالة، يعطينا النطاق range(10) عشرة أرقام. سترى ما هي هذه الأرقام قريبًا.
  • النقطتان : في نهاية السطر الأول والمسافة البادئة في بداية السطر الثاني هي جوانب من قواعد بناء الجملة Syntax في لغة Python والتي رأيتها بالفعل عند كتابة حلقة while وعبارة if في البرنامج الأول.
  • ماذا عن كلمة something؟ هل هذا أمر مضمن أيضًا؟ الجواب لا. دعونا نرى ما هي حقيقة هذا الشيء.

كلمة something لم تكن موجودة في الغرفة البيضاء قبل كتابتها في عبارة الحلقة for. إنه متغير تقوم بإنشائه عندما تكتبه في السطر التالي: for something in range(10):

المتغير something هو نفس نوع الصندوق كما هو الحال عندما تقوم بإنشاء متغير باستخدام عامل الإسناد = كما فعلت في الفصل الأول. لإقناعك أنه لا يوجد شيء مميز في اسم something، يمكنك تجربة الإصدارات التالية:

for pizza_with_cheese in range(10):
    print("Don't Repeat Yourself")

أو في الواقع:

for vcnxzbvjihafynariayenmsx in range(10):
    print("Don't Repeat Yourself")

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

for something in range(10):
    print(something)

وناتج هذا الكود هو كالتالي:

0
1
2
3
4
5
6
7
8
9

تتكرر دالة print () عشر مرات كما هي في حلقة for. ومع ذلك، فإنها تطبع قيمة مختلفة في كل مرة. يتغير محتوى المربع المسمى something في كل مرة تتكرر فيها الحلقة. الأرقام من 0 إلى 9 هي القيم المعطاة بواسطة النطاق range(10). إنها ليست الأرقام العشرة التي ربما توصل إليها الإنسان لأننا عادةً ما نبدأ العد من الرقم 1، ولكن العديد من لغات البرمجة تبدأ في العد من الصفر. ستصادف هذه الغرابة كثيرًا وستعتاد عليها في النهاية.

دعنا نستخدم هذه الميزة لمحاولة إظهار الأرقام من 1 إلى 10 في بداية كل سطر يقول “لا تكرر نفسك”. ستحتاج إلى إنشاء سلسلة تبدو كالتالي: “1. لا تكرر نفسك” “1. Don’t Repeat Yourself”. ومع ذلك، سيحتاج الرقم إلى التغيير في كل مرة تتكرر فيها الحلقة.

في الفصل الأول، قمنا بدمج سلسلتين باستخدام عامل + لسلسلة التسلسلات concatenation. هنا، ستستخدم طريقة أفضل لتنسيق السلاسل:

for something in range(10):
     print(f"{something+1}. Don't Repeat Yourself")

هل لاحظت الحرف الإضافي f أمام علامة التنصيص المفتوحة؟ يشير هذا الحرف f إلى أنك تستخدم نوعًا خاصًا من السلسلة يسمى f-string، والتي تعني سلسلة منسقة formatted string. هناك أيضًا زوج من الأقواس المتعرجة {} في السلسلة f. كل ما هو داخل الأقواس المتعرجة يتم تقييمه على أنه جملة بايثون أولاً، ثم يتم وضع النتيجة بدلاً من {} في السلسلة. عندما تمر الحلقة for عبر الأسطر ذات المسافة البادئة لأول مرة، يكون للمتغير قيمة صفر. لذلك يتم تقييم something+1 إلى القيمة 1. في كل مرة تتكرر الحلقة، ستزداد هذه القيمة بمقدار 1.

الناتج من الكود أعلاه هو:

  1. لا تكرر نفسك
  2. لا تكرر نفسك
  3. لا تكرر نفسك
  4. لا تكرر نفسك
  5. لا تكرر نفسك
  6. لا تكرر نفسك
  7. لا تكرر نفسك
  8. لا تكرر نفسك
  9. لا تكرر نفسك
  10. لا تكرر نفسك

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

يمكنك تكرار كتلة من التعليمات البرمجية بأي عدد من المرات باستخدام حلقة for مع الوظيفة المضمنة range().

الحلقات: الحلقة while

أنت الآن على دراية بنوعين من الحلقات في Python، الحلقة for والحلقة while. إذا كان كلاهما يكرر كتلة من التعليمات البرمجية، فأي واحدة يجب أن تستخدمها؟

في معظم الحالات، عندما تحتاج إلى تكرار كتلة من التعليمات البرمجية، يمكنك كتابة الكود الخاص بك بطريقة معينة بحيث يمكنك استخدام حلقة for أو while. ومع ذلك، فإن كل نوع من أنواع الحلقات هو الأنسب لاستخدامات محددة.

عندما تريد تكرار كتلة من التعليمات البرمجية لعدد ثابت من المرات، فإن حلقة for هي الأداة المناسبة لهذه الوظيفة.

إذا كنت لا تعرف عدد المرات التي يجب عليك فيها تكرار كتلة التعليمات البرمجية وتعتمد على برنامج الكمبيوتر لاتخاذ القرار، بناءً على ما يحدث في البرنامج، فإن حلقة while هي الأفضل. في لعبة Angry Goblin، كان هذا هو سبب استخدامك حلقة while loop. كان يجب أن تستمر الحلقة في التكرار حتى يخمن اللاعب.

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

يمكنك المحاولة وتجربة حلقة while بأمثلة قصيرة مثل ما يلي:

import random

a_number = 0

while a_number <= 20:
    a_number = random.randint(1, 25)
    print(f"This is the random number: {a_number}")

print("You have found one larger than 20")

دعنا نفصّل هذا الرمز باستخدام الغرفة البيضاء White Room للمساعدة في فهم كيف يرى الكمبيوتر هذا البرنامج:

  • import random

تقوم بإنشاء غرفة بيضاء جديدة عندما تفتح الملف لأول مرة، ثم تقوم باستيراد random. ينتقل برنامج الكمبيوتر إلى المكتبة لجلب الكتاب random وإحضاره إلى الغرفة البيضاء.

  • a_number = 0

تطلب من البرنامج الحصول على صندوق، وتسميته a_number، ووضع العدد الصحيح صغر داخل الصندوق.

  • While a_number <= 20:

الكلمة الرئيسية while موجودة في الكتيب “المضمن”. يحتوي الكتيب على “القواعد” التي يجب أن يتبعها البرنامج عند التعامل مع حلقة while.

عندما تكتب a_number، يجد البرنامج صندوقًا بهذا الاسم، ويخرجه من الرف ويخرج محتوياته. يحتوي الصندوق حاليًا على الرقم صفر.

بينما يقرأ البرنامج بقية هذا السطر، سيجد بعد ذلك عامل التشغيل <=. سيقارن البرنامج 0الرقم صفر بـالرقم 20. ويقرر أن الإجابة صحيحة لأن صفر أصغر من 20.

نظرًا لأن while متبوعة بـ True، فسيتم الآن تشغيل الكود ذي المسافة البادئة بعد العبارة while.

  • indented block

تحت كتلة المسافة البادئة، ينتقل البرنامج الآن إلى مهمة أخرى. سينظر أولاً في الجانب الأيمن من عامل التشغيل =. يقوم البرنامج بإخراج الكتاب random من الرف، ويفتحه ويبحث عن كلمة randint. عندئذٍ ستقوم دالة randint () بعملها. سيتم اختيار رقم عشوائي بين 1 و25. أي رقم يتم اختياره سيتم تخزينه في الصندوق.

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

ستقوم وظيفة print () بطباعة الرقم المختار بمجرد جلب محتويات الصندوق a_number.

  • نهاية الحلقة

نظرًا لأن هذه هي نهاية الكود في حلقة while، فسيعود البرنامج إلى السطر الذي يحتوي على جملة while. لكن الآن، عندما يجلب الصندوق a_number، لن يجد العدد الصحيح صفر، الذي كان موجودًا في البداية. سيحتوي الصندوق الآن على أي رقم تم اختياره عشوائيًا باستخدام الدالة randint (). سيتحقق عامل التشغيل <= من الرقمين ويصدر حكمًا: صواب أو خطأ.

طالما أن الرقم الموجود في الصندوق أقل من أو يساوي 20، فإن الكود الموجود في الحلقة سيستمر في التكرار. في مرحلة ما، سيختار randint () عددًا أكبر من 20. عندما يحدث هذا ويعود البرنامج إلى العبارة while، سيتم تقييم هذا إلى أنه خطأ False. ولذلك سيتخطى البرنامج الكود في الحلقة. سينتقل إلى السطر التالي من التعليمات البرمجية الذي يتبع الحلقة، وهو السطر التالي الذي لا يحتوي على مسافة بادئة.

سيقوم البرنامج بطباعة البيان النهائي، وينتهي البرنامج. يمكن الآن تفكيك الغرفة البيضاء!

هذا هو الناتج من الكود:

This is the random number: 12
This is the random number: 17
This is the random number: 7
This is the random number: 17
This is the random number: 24
You have found one larger than 20

في كل مرة يتم فيها تشغيل البرنامج، ستكون الأرقام مختلفة. سيكون عدد التكرارات مختلفًا أيضًا. حاول تشغيل الكود عدة مرات لمعرفة المخرجات المختلفة التي تحصل عليها.

التبديل بين المبرمج والمستخدم

عندما تستخدم أجهزة الكمبيوتر يوميًا، فأنت تستخدم برنامجًا كتبه مبرمجون آخرون. أنت مستخدم البرنامج ولا تهتم بالشكل الذي تبدو عليه الشفرة. غالبًا لا يمكنك المعرفة بأي حال لأن الشفرة ستكون ملكية. يمكنك فقط أن تفعل ما يريدك المبرمج أن تفعله. عندما تنقر على زر، يحدث شيء ما، وهذا “الشيء” هو ما قرر المبرمج أنه سيحدث عند النقر على هذا الزر.

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

من المفيد التمييز بين الدورين. على سبيل المثال، إذا كنت تكتب لعبة ليخمن المستخدم رقمًا ، كما كان الحال مع لعبة Angry Goblin، فسيحتوي الرمز الخاص بك على السطر التالي:

goblin_position = 3

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

في بعض الأحيان يكون من المهم تذكر هذا التمييز بين المبرمج والمستخدم عند كتابة واختبار الكود.

المسافات البادئة

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

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

import random

a = random.randint(1, 10)

if a == 5:
    print("a is 5, after all")
    print("great news")
print("Have a good day")

السطران اللذان يحتويان على مسافة بادئة ينتميان إلى بعضهما البعض. إذا كانت a تساوي 5، فسيتم تنفيذ كلا السطرين. خلاف ذلك، سيتم تجاهل كلا السطرين.

السطر الأخير ليس له مسافة بادئة، لذلك سيحدث دائمًا.

من المفيد التعرف على بعض رسائل الخطأ التي قد تظهر لك عندما يكون هناك خطأ ما في المسافات البادئة:

import random

a = random.randint(1, 10)

if a == 5:

print("Have a good day")

عند تشغيل الكود أعلاه، ستتلقى رسالة الخطأ التالية:

File "<path>/<filename>.py", line 7
    print("Have a good day")
    ^
IndentationError: expected an indented block

خطأ مسافة بادئة: توقع وجود مسافة بادئة لكتلة.

تخبرك Python بأنها تتوقع كتلة من التعليمات البرمجية التي لها مسافة بادئة بعد عبارة if. تحتاج إلى تضمين سطر واحد على الأقل بمسافة بادئة بعد سطر ينتهي بالنقطتين :.

إليك خطأ آخر في المسافة البادئة:

import random

    a = random.randint(1, 10)

if a == 5:
    print("a is 5, after all")
    print("great news")
print("Have a good day")

هذا يعطي ما يلي:

File "<path>/<filename>.py", line 3
    a = random.randint(1, 10)
    ^
IndentationError: unexpected indent

خطأ مسافة بادئة: مسافة بادئة غير متوقعة

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

وإليك خطأ أخير في المسافة البادئة:

import random

a = random.randint(1, 10)

if a == 5:
     print("a is 5, after all")
    print("great news")
print("Have a good day")

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

File "<path>/<filename>.py", line 7
    print("great news")
                      ^
IndentationError: unindent does not match any outer indentation level

خطأ مسافة بادئة: لا يتطابق إلغاء المسافة البادئة مع أي مستوى مسافة بادئة خارجية.

إذا كنت تستخدم IDE مثل PyCharm، فستلاحظ أنه عند الضغط على مفتاح الإدخال Enter / Return بعد سطر ينتهي بنقطتين، تتم إضافة المسافة البادئة تلقائيًا. IDEs موجودة لمساعدتك وتجعل حياتك أسهل. وأثناء حديثي عن IDEs مما يجعل حياتك أسهل، ستلاحظ أيضًا الإكمال التلقائي الذي تم بواسطة IDE الخاص بك. إذا بدأت في كتابة الأحرف القليلة الأولى من الكلمة، فسيقترح IDE خيارات، ويمكنك الضغط على مفتاح الإدخال Enter / Return للإكمال التلقائي. حقق أقصى استفادة من هذه الميزات المفيدة.

سيكون لديك غالبًا أكثر من مستوى واحد للمسافة البادئة. هذا مثال على ذلك:

import random

a = random.randint(1, 20)
b = random.randint(1, 20)

if a > 10:
    print("a is a big number, it seems")
    if b > 10:
        print("Whoa, both a and b are in double digits!")

تتكون كتلة التعليمات البرمجية التي “تنتمي” إلى عبارة if الأولى، والتي تتحقق مما إذا كان a أكبر من 10، من ثلاثة أسطر. أحد هذه الأسطر، وهو الأخير، هو أيضًا جزء من جملة شرطية أخرى if، والتي تتحقق مما إذا كان b أكبر من 10. يحتوي السطر الأخير على عدد اثنين من المسافة البادئة: أحدهما يجعله جزءًا من عبارة if الأولى والآخر يجعله أيضًا جزء من عبارة if الثانية.

حاول إجراء تغيير بسيط على البرنامج أعلاه بحيث تطبع قيم a و b، ثم قم بتشغيل الكود عدة مرات. يجب أن تلاحظ أنه إذا كان a أكبر من 10، فسيتم طباعة السطر الذي يقول أن العدد a هو عدد كبير. إذا كان كل من a و b أكبر من 10، فستتم طباعة كلتا العبارتين.

ومع ذلك، إذا كانت قيمة b أكبر من 10 ولكن a ليست كذلك، فلن تتم طباعة أي شيء. هذا لأن تعليمة if الثانية هي جزء من كتلة التعليمات البرمجية التي تكون مشروطة بعبارة if الأولى. تحتاج عبارة if الثانية إلى أن تكون العبارة الأولى صحيحة حتى يتم أخذها في الاعتبار.

القوائم Lists

لقد استخدمت حتى الآن أنواع بيانات بسيطة نسبيًا في الأمثلة التي برمجتها حتى الآن. لقد استخدمت سلاسل strings لتخزين النصوص، والأعداد الصحيحة integers أو الأعداد العشرية floats لتخزين الأعداد، واستخدمت نوع البيانات المنطقية Boolean لتمثيل قيمة صواب True أو خطأ False.

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

name1 = "John"
name2 = "Kate"
name3 = "Jason"
name4 = "Mary"

لقد أنشأت أربعة صناديق تخزين منفصلة موجودة الآن على الرف في الغرفة البيضاء. أنت تعلم أن هذه الأسماء مرتبطة – إنها أسماء جميع أعضاء الفريق. ومع ذلك، فإن برنامج الكمبيوتر الخاص بك لا يعرف ذلك، وليس لديه طريقة لمعرفة أن هذه الأجزاء الأربعة من المعلومات مرتبطة ببعضها البعض. ستجعل هذه النقطة من الصعب معاملتهم كمجموعة في التعليمات البرمجية الخاصة بك. سيؤدي ذلك إلى برمجة كود من نوع WET للغاية.

لدى Python نوع بيانات للتعامل مع هذا الموقف. نوع البيانات هذا هو القائمة List. يمكنك إنشاء قائمة بأسماء أعضاء فريقك:

team_members = ["John", "Kate", "Jason", "Mary"]

الأقواس المربعة التي تلي عامل التعيين = تخبر Python أن البيانات المخزنة في المربع عبارة عن قائمة list. يتم فصل كل عنصر داخل القائمة بفاصلة. يتم الآن تخزين الأسماء الأربعة في صندوق تخزين واحد يسمى team_members. السلاسل الفردية هي العناصر الأولى والثانية والثالثة والرابعة في صندوق تخزين team_members.

تحتوي القائمة التي قمت بإنشائها أعلاه على سلاسل. ومع ذلك، يمكنك تخزين أي نوع بيانات داخل قائمة. يمكنك حتى مزج أنواع البيانات ومطابقتها:

my_numbers = [4, 6, 12, 9, 6, 23]
quiz_answers = [True, True, False, True, False]
useless_stuff = ["Hello", 35.3, False, "Bye Bye", 1]

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

استخدام القوائم في الفهرسة والشرائح

يمكنك الآن تجربة القوائم لمعرفة كيفية استخراج القيم منها. ستستخدم جلسة وحدة التحكم لهذا، مما يسهل الاستكشاف:

>>> my_numbers = [4, 6, 12, 9, 6, 23]
>>> my_numbers
[4, 6, 12, 9, 6, 23]

لقد أنشأت متغيرًا باسم my_numbers، والذي يخزن قائمة list، ثم طلبت من Python عرض محتويات هذا المتغير. يمكنك اختيار استرداد عنصر واحد فقط داخل القائمة:

>>> my_numbers[1]
6

هنا أنت تستخدم الأقواس المربعة مرة أخرى. ومع ذلك، فإن هذه الأقواس المربعة ليست أقواس قائمة بذاتها. بدلاً من ذلك، قمت بكتابتها فورًا بعد اسم القائمة. يعني هذا الترميز أنك ترغب في استخراج عنصر من القائمة. نسمي هذه الطريقة باسم الفهرسة indexing.

كان الرقم الذي تم استرداده عند كتابة my_numbers[1] هو العنصر الثاني في القائمة. ماذا عن العنصر الأول؟ قد تتذكر عندما استخدمت range () أنه عندما تحسب Python الأرقام، فإنها تبدأ من الصفر بدلاً من 1. إن العنصر الأول في القائمة ترتيبه أو فهرسه هو صفر:

>>> my_numbers[0]
4

ستعتاد على الفهرسة الصفرية قريبًا، ولكن في هذه الأثناء، قد تجد ذلك محبطًا. أنت لست وحدك! يمكنك حتى استخدام الفهرسة السالبة (-). تُستخدم الفهارس غالبًا لجمع الفهارس في الترميز:

>>> my_numbers[-1]
23

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

الشرائح

طريقة أخرى لاستخراج القيم من القائمة هي استخدام الشرائح slicing. إليك كيف تبدو الشرائح:

>>> my_numbers[2:5]
[12, 9, 6]

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

الأرقام المستخرجة من القائمة الأصلية هي الأرقام الثالثة والرابعة والخامسة في التسلسل. يمثل الفهرس 2 العنصر الثالث في القائمة حيث أن الفهرس الأول هو صفر. وكذلك، يمثل الفهرس 5 العنصر السادس في القائمة، وهو 23. نتيجة عملية الشرائح لا تتضمن هذه القيمة. والسبب في ذلك هو نزوة أخرى ستعتاد عليها بسرعة. عندما يكون هناك مرجع إلى نطاق من الأرقام في بايثون، يتم تضمين بداية النطاق، ولكن لا يتم تضمين النهاية. لذلك فإن الشريحة 2: 5 تشير إلى الأرقام من الفهرس 2 حتى الفهرس 5 ولكن باستثناء الفهرس 5. هذه طريقة طويلة للقول أن الفهارس الممثلة في الشريحة هي 2 و 3 و 4.

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

>>> more_numbers = [3, 67, 23, 1, 89, 4, 56, 2, 78, 4, 12, 8]
>>> more_numbers[2:10:2]
[23, 89, 56, 78]

الشريحة التي تستخدمها بين الأقواس المربعة هي الآن 2: 10: 2. يمثل الرقمان الأول والثاني بداية النطاق ونهايته كما كان من قبل. الرقم النهائي هو حجم الخطوة. تستخرج الشريحة العناصر من الفهرس 2 حتى الفهرس 10 ولكن باستثناء الفهرس 10 بخطوات من 2. وبذلك تحصل على العناصر الثالثة والخامسة والسابع والتاسعة من القائمة.

نظرًا لأن المبرمجين يحبون أن يكونوا كسالى، فهناك بعض الاختصارات المفيدة:

>>> more_numbers[:7]
[3, 67, 23, 1, 89, 4, 56]

>>> more_numbers[4:]
[89, 4, 56, 2, 78, 4, 12, 8]

>>> more_numbers[4::2]
[89, 56, 78, 12]

>>> more_numbers[::2]
[3, 23, 89, 56, 78, 12]

>>> more_numbers[::-1]
[8, 12, 4, 78, 2, 56, 4, 89, 1, 23, 67, 3]

إذا كنت ترغب في استخدام الشرائح من بداية النطاق، فلن تحتاج إلى كتابة صفر في البداية. يمكنك ترك القيمة فارغة. في المثال الأول، تقوم باستخراج العناصر من الفهرس صفر حتى الفهرس 7 واستبعاده باستخدام الشريحة [:7]، والتي تعادل [0:7]. تنطبق نفس القاعدة على نهاية النطاق. إذا كنت ترغب في الانتقال إلى نهاية القائمة، فيمكن حذف رقم النهاية، كما في المثال الثاني أعلاه.

في الشريحة الثالثة، تكون الشريحة [4::2]. يشير هذا الترميز إلى أنك تبحث عن عناصر من الفهرس 4 إلى نهاية النطاق مع الخطوات 2. القيمة التي تم حذفها هي الرقم الثاني في الشريحة الذي يمثل نهاية النطاق.

المثال الرابع يذهب إلى أبعد من ذلك. الشريحة المستخدمة هي [::2] وهي تستخرج النطاق الكامل من الفهارس ولكن بخطوات 2. المثال الأخير هو خدعة ستجدها مفيدة جدًا عندما تريد عكس القائمة.

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

استخدام الحلقات for مع القوائم

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

دعونا نلقي نظرة على مثال أعضاء الفريق مرة أخرى الذي تحدثنا عنه قبل قليل في هذا الفصل:

team_members = ["John", "Kate", "Jason", "Mary"]

ترغب في طباعة تحية لكل عضو في الفريق. ترغب في كتابة كود جاف DRY، لذلك عليك التفكير في استخدام حلقة for. عندما علمت عن حلقة for سابقًا، بدت عبارة for كما يلي:

for something in range(10):

تنتج دالة النطاق range() نطاقًا من الأرقام، وتتكرر حلقة for على هذه الأرقام، وتخصص أحد الأرقام للمتغير something في كل مرة. يمكن أن تتكرر حلقة for على أي شيء تتعرف عليه Python على أنه تسلسل. لذلك يمكنك استبدال دالة range () باسم قائمة لأن القائمة عبارة عن سلسلة من العناصر:

team_members = ["John", "Kate", "Jason", "Mary"]

for person in team_members:
    print(f"Hello {person}. How are you doing today?")

في هذا البرنامج القصير، تقوم أولاً بإنشاء صندوق يسمى team_members وهي قائمة تحتوي على أربعة سلاسل strings. في عبارة for، يتعرف البرنامج على team_m members كصندوق يتم تخزينه على الرفوف. يتعرف أيضًا على أنه تسلسل. لذلك، يمكن استخدامه في جملة for. يتم إنشاء المتغير person، ويتم تعيين العنصر الأول من team_members إلى person.

يتم المضي قدمًا في التكرار الأول للحلقة، ويتم طباعة العبارة باستخدام الكلمة “John” لتحل محل العنصر النائب {person} داخل السلسلة f-string. يعود البرنامج الآن إلى عبارة for وينتقل إلى العنصر الثاني في القائمة. يقوم بتعيين “Kate” للمتغير person. ستستمر الحلقة في التكرار حتى لا يكون هناك المزيد من العناصر في القائمة.

يعطي هذا الكود الناتج التالي:

Hello John. How are you doing today?
Hello Kate. How are you doing today?
Hello Jason. How are you doing today?
Hello Mary. How are you doing today?

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

الخلاصة

لقد غطيت في هذا الفصل:

  • ما يحدث بالفعل في برنامج الكمبيوتر من خلال تشبيه الغرفة البيضاء
  • كيفية تكرار التعليمات البرمجية باستخدام الحلقات: الحلقة for
  • كيفية فهم بعض رسائل الخطأ الشائعة
  • كيفية إنشاء القوائم
  • كيفية الوصول إلى العناصر من قائمة باستخدام الفهرسة وعمل الشرائح
  • كيفية استخدام الحلقات للتكرار من خلال قائمة باستخدام حلقة for

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

المصدر

  • كتاب البرمجة بلغة بايثون، تأليف: ستيفن جروبيتا. لندن، المملكة المتحدة. حاصل على دكتوراه في الفيزياء من جامعة إمبريال كوليدج بلندن. بكالوريوس (مع مرتبة الشرف) من الدرجة الأولى في الفيزياء والرياضيات من جامعة مالطا، 1996-2000.
  • موسوعة أساسيات البرمجة بلغة بايثون، ترجمة: د.م. مصطفى عبيد، مركز البحوث والدراساتمتعدد التخصصات.