التعامل مع الأخطاء البرمجية والثغرات

التعامل مع الأخطاء البرمجية والثغرات

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

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

الأخطاء البرمجية والثغرات

يمكنك فهم الطرق المختلفة التي يمكن أن تسوء بها الأمور من خلال المثالين التاليين. أولاً، ضع في اعتبارك هذه العبارة:

If it is rained, taken your umbrella.

(إذا هطل المطر، خذ شمسيتك).

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

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

اقرأ الآن العبارة التالية:

If it is raining, take your sunglasses and leave your umbrella at home.

(إذا كانت السماء تمطر، خذ نظارتك الشمسية واترك المظلة في المنزل).

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

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

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

التصحيح مثل كونك المحقق في فيلم الجريمة حيث تكون أنت أيضًا الجاني.

فيليبي فورتيس

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

فهم رسائل الخطأ البرمجي

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

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys()
     income = 0
      qty = input(f"How many {item}s have you sold? ")
     income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

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

هناك نوعان من استخدامات السلسلة f-string التي تعرّفت عليها في الفصول السابقة. في السطر الأخير، ستلاحظ أنه داخل الأقواس المتعرجة {} في سلسلة f-string، يتبع اسم المتغير income بعض الرموز الإضافية. هذا يخبر Python أن تعرض قيمة الدخل income كعدد عائم float لأقرب منزلتين عشريتين.

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

  File "<path>/<filename>.py", line 3
    for item in items.keys()
                            ^
SyntaxError: invalid syntax

(خطأ نحوي: بناء جملة غير صالح)

عندما تتلقى رسالة خطأ، يجب أن يبدأ عملك التحري دائمًا بالجملتين التاليتين:

  • موقع الخطأ location: الملف ورقم السطر في السطر الأول من رسالة الخطأ
  • نوع ووصف الخطأ type and description: السطر الأخير من رسالة الخطأ

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

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

يتم عرض السطر المخالف أيضًا في رسالة الخطأ مع وجود سهم (^) يشير إلى الموقع المحتمل للخطأ. والخطأ هنا هو أن النقطتين : مفقودة. لنصلح هذا الخطأ ونحاول إعادة تشغيل الكود:

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():
     income = 0
      qty = input(f"How many {item}s have you sold? ")
     income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

رسالة الخطأ موجودة الآن على سطر مختلف ومن نوع مختلف:

  File "<path>/<filename>.py", line 5
    qty = input(f"How many {item}s have you sold? ")
IndentationError: unexpected indent

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

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():
    income = 0
    qty = input(f"How many {item}s have you sold? ")
    income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

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

دعنا ندخل قيمة لكمية القهوة المُباعة وننتقل إلى ما يلي:

How many Coffees have you sold? 10

ولكن بمجرد الضغط على Return / Enter، ستصلك رسالة خطأ أخرى:

Traceback (most recent call last):
  File "<path>/<filename>.py", line 6, in <module>
    income = income + qty * items[item]
TypeError: can't multiply sequence by non-int of type 'float'

لقد واجهت نوع خطأ آخر الآن، TypeError. لقد تعلّمت الكثير عن أنواع البيانات في الفصول السابقة. توضح لك رسالة الخطأ هذه أن المشكلة تتعلق بوجود أنواع بيانات خاطئة في الأماكن الخطأ. كما أن وصف الخطأ غني بالمعلومات. تخبرك الرسالة أن البرنامج لا يمكنه ضرب التسلسل بعدد غير صحيح non-int من النوع العائم أو العشري “float”.

آمل أن تكون قد حصلت على قبعة شارلوك هولمز الخاصة بك لارتدائها. دعونا نلقي نظرة على الجملتين المهمتين. تكمن المشكلة في الضرب، وبالتالي فإن جزء السطر الذي يجب أن تبدأ في النظر إليه هو qty * items[item] لأنه الجزء الذي يحتوي على عملية الضرب. يشير وصف الخطأ إلى تسلسل sequence و non-int. ربما خمنت أن non-int تشير إلى قيمة ليست عددًا صحيحًا. القيمة هي عدد عشري في هذه الحالة.

ومع ذلك، يجب أن تكون قيمة الكمية هي الرقم 10، ويجب أن تكون قيمة items[item] هي سعر القهوة، حيث أن item يساوي “Coffee” في التكرار الأول للحلقة for. سعر القهوة هو العدد العشري 2.2، والذي يمثل 2.20 جنيه إسترليني. في القسم التالي، ستتعرّف على واحدة من أقوى أدوات التحقيق في تصحيح الأخطاء البرمجية: إنها وظيفة الطباعة المتواضعة print().

النظر في لقطات من البيانات

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

  • ما هي قيمة البيانات
  • ما هو نوع البيانات

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

نظرًا لحدوث الخطأ في السطر 6، يمكنك طباعة قيمة المتغيرين المهمين على السطور التي تسبق ذلك مباشرةً للتحقق من احتوائهما على البيانات التي تتوقعها:

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():
    income = 0
    qty = input(f"How many {item}s have you sold? ")
    print(qty)
    print(items[item])
    income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

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

How many Coffees have you sold? 10
10
2.2

Traceback (most recent call last):
  File "<path>/<filename>.py", line 8, in <module>
    income = income + qty * items[item]
TypeError: can't multiply sequence by non-int of type 'float'

هذا الدليل لا يقودك إلى أي مكان. يبدو أن المطبوعات تُظهر أن القيم التي تحصل عليها هي ما كنت تتوقعه. الشيء التالي الذي يجب التحقق منه هو نوع بيانات هذه المتغيرات. بدلاً من طباعة القيم، يمكنك الآن طباعة نوع البيانات:

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():
    income = 0
    qty = input(f"How many {item}s have you sold? ")
    print(type(qty))
    print(type(items[item]))
    income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

سيعرض هذا الرمز الآن أنواع البيانات قبل رسالة الخطأ:

How many Coffees have you sold? 10
<class 'str'>
<class 'float'>

Traceback (most recent call last):
  File "<path>/<filename>.py", line 8, in <module>
    income = income + qty * items[item]
TypeError: can't multiply sequence by non-int of type 'float'

قيمة items[item] هي بالفعل عدد عشري، كما توقعت وكما هو موضح في رسالة الخطأ. ومع ذلك، فإن قيمة qty هي من نوع سلسلة str. في الفصل الرابع، قرأت أن السلسلة string عبارة عن تسلسل sequence، وهو ما يفسّر استخدام هذا المصطلح في رسالة الخطأ.

يمكنك دائمًا التحقق من فهمك للمشكلة التي تشير إليها رسالة الخطأ من خلال محاولة تكرارها في وحدة التحكم:

>>> "hello" * 2.5
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'float'

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

>>> [34, 45, 23, 12] * 2.5
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'float'

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

>>> "hello" * 2
'hellohello'

>>> [34, 45, 23, 12] * 2
[34, 45, 23, 12, 34, 45, 23, 12]

دعنا نعود إلى النص الذي يحتوي على كود بائع السوق. قادك الاستقصاء إلى استنتاج أن هناك خطأ ما في قيمة المتغير “الكمية” qty. في هذه الحالة، يتم تحديد المتغير qty على السطر السابق. هذا هو المكان الذي يجب أن يكون الخطأ فيه. في هذه المرحلة، قد تتذكر أن دالة input() تقوم دائمًا بإرجاع سلسلة. لقد واجهت هذا الخطأ في أول مشروع عملت عليه في الفصل الأول.

يمكنك الآن حل هذه المشكلة عن طريق تحويل السلسلة إلى عدد صحيح. يمكنك أيضًا إزالة عبارات print () عند قيامهم بعملهم ولم تعد هناك حاجة إليهم:

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():
    income = 0
    qty = input(f"How many {item}s have you sold? ")
    qty = int(qty)
    income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

عند تشغيل البرنامج الآن، سترى أنه يمكنك متابعة حلقة for بأكملها:

How many Coffees have you sold? 10
How many Teas have you sold? 10
How many Chocolates have you sold? 10

The income today was £25.00

يا هلا! أخيرًا، إنه يعمل!

البحث عن الثغرات والأخطاء البرمجية

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

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

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

How many Coffees have you sold? 10
How many Teas have you sold? 0
How many Chocolates have you sold? 0

The income today was £0.00

الآن، جرب بيع 10 أكواب شاي فقط:

How many Coffees have you sold? 0
How many Teas have you sold? 10
How many Chocolates have you sold? 0

The income today was £0.00

وأخيرًا، يمكنك إدخال 10 للشوكولاتة ولكن ليس للعناصر الأخرى:

How many Coffees have you sold? 0
How many Teas have you sold? 0
How many Chocolates have you sold? 10

The income today was £25.00

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

أنت تعرف ما هي المشكلة ولكن هذا لا يعني أن المشكلة قد تم حلها. يبدو أن المشكلة تتعلق بالمتغير income هذه المرة. لذلك يمكنك استخدام نفس الأداة السابقة والبدء بطباعة قيمة الدخل income:

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():
    income = 0
    qty = input(f"How many {item}s have you sold? ")
    qty = int(qty)
    income = income + qty * items[item]
    print(income)
print(f"\nThe income today was £{income:0.2f}")

يبدو الإخراج الآن كما يلي:

How many Coffees have you sold? 10
22.0
How many Teas have you sold? 10
15.0
How many Chocolates have you sold? 10
25.0

The income today was £25.00

يتم حساب قيمة الدخل بشكل صحيح بواسطة الكود كما تظهر مخرجات الطباعة print(). ومع ذلك، يبدو أن متغير الدخل income لا يتذكّر القيم السابقة في كل مرة يتم فيها تشغيل الحلقة for.

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

دعنا نزيل هذا السطر الإشكالي:

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

for item in items.keys():

    qty = input(f"How many {item}s have you sold? ")
    qty = int(qty)
    income = income + qty * items[item]
    print(income)
print(f"\nThe income today was £{income:0.2f}")

ولكن بمجرد كتابة القيمة الأولى، ستعود إلى ظهور خطأ:

How many Coffees have you sold? 10
Traceback (most recent call last):
  File "<path>/<filename>.py", line 7, in <module>
    income = income + qty * items[item]
NameError: name 'income' is not defined

تحصل الآن على NameError. الكلمة Name لها معنى محدد في بايثون. كل متغير ووظيفة وكل كائن في برنامج الكمبيوتر له اسم. هذه هي الملصقات الموجودة على الصناديق (المتغيرات)، أو أسماء الكتب (الوحدات المستوردة)، أو الملصقات الموجودة على الأبواب التي تؤدي إلى الغرف المجاورة (الدوال). يحدث خطأ “الاسم غير معرّف” name not defined عندما يتعذر على البرنامج العثور على أي مرجع للاسم في أي مكان في الغرفة البيضاء.

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

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

income = 0
for item in items.keys():
    qty = input(f"How many {item}s have you sold? ")
    qty = int(qty)
    income = income + qty * items[item]
print(f"\nThe income today was £{income:0.2f}")

أخيرًا ، يمكنك الادعاء بثقة أن الكود يعمل:

How many Coffees have you sold? 10
How many Teas have you sold? 10
How many Chocolates have you sold? 10

The income today was £62.00

عند التعامل مع الأخطاء والثغرات في التعليمات البرمجية، غالبًا ما تحتاج إلى تتبع ما يحدث للبيانات أثناء تشغيل البرنامج. تريد أن تنظر داخل البرنامج أثناء تشغيله. يُعد استخدام أسطر الطباعة ()print في المكان الجيد طريقة فعّالة للقيام بذلك. تحتاج إلى الحصول على لقطة snapshot  لما يلي:

  • قيمة البيانات
  • نوع البيانات

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

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

items = {"Coffee": 2.2, "Tea": 1.5, "Chocolate": 2.5}

income = 0
for item, value in items.items():
    qty = input(f"How many {item}s have you sold? ")
    qty = int(qty)
    income = income + qty * value
print(f"\nThe income today was £{income:0.2f}")

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

استخدام أدوات تصحيح الأخطاء المتقدمة

تعتبر وظيفة print () بسيطة وفعّالة كأداة لتصحيح الأخطاء البرمجية. نصيحتي هي التمسك باستخدام هذه الأداة في الوقت الحالي.

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

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

دعنا نعود إلى أحد الأخطاء التي واجهتها سابقًا عندما اكتشفت في النهاية أن الكمية qty كانت عبارة عن سلسلة عندما أردتها أن تكون عددًا صحيحًا. يمكنك إدراج نقطة توقف breakpoint  في أي مكان تريده في برنامجك. في PyCharm، يمكنك النقر فوق الهامش الموجود بجوار السطر حيث تريد إدراج نقطة التوقف. يُظهر IDE نقطة التوقف كنقطة حمراء في الهامش:

استخدام مصحح الأخطاء البرمجية المرئي في PyCharm للتعامل مع الأخطاء والثغرات البرمجية
استخدام مصحح الأخطاء البرمجية المرئي في PyCharm للتعامل مع الأخطاء والثغرات البرمجية

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

استخدام مصحح الأخطاء البرمجية المرئي في PyCharm للتعامل مع الأخطاء والثغرات
استخدام مصحح الأخطاء البرمجية المرئي في PyCharm للتعامل مع الأخطاء والثغرات

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

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

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

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

الخلاصة

سوف ترتكب أخطاء. سوف تكتب الأخطاء البرمجية والثغرات في برامجك. لا يمكنك تجنب ذلك، ولكن يمكنك معرفة كيفية البحث عن الأخطاء والثغرات وإصلاحها بسرعة وكفاءة.

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

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

نصف البرمجة فقط هي كتابة الكود. والـ 90٪ الأخرى هي تصحيح أخطاء.

مجهول

وبما أنك تسأل، فإليك سؤال آخر:

أحيانًا يكون من المفيد البقاء في السرير يوم الاثنين بدلاً من قضاء بقية الأسبوع في تصحيح كود يوم الاثنين.

دان سليمان / كريستوفر طومسون

كل النكات تعتمد على المبالغة فلا داعي للقلق! لكن التصحيح يلعب دورًا مهمًا جدًا في كتابة الكود والبرمجة.

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

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

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

الخطوات التالية – تسلق الشجرة

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

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

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

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

على طول الطريق، ستتسلّق أيضًا بعض الفروع ذات الصلة بمعظم تطبيقات البرمجة ولكنها ليست في جذع الشجرة الرئيسي. بعد فصل White Room interlude، ستتعلم المزيد حول الدوال، وستستكشف أيضًا البرمجة الشيئية Object-Oriented Programming والكلاس Classes. هذه الموضوعات هي المعرفة المطلوبة لأي تطبيق للبرمجة قد تكون مهتمًا به.

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

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

المصدر

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