الوحدات
أهداف التعلّم
بعد إتمام هذا القسم
- ستعرف ما هي وحدة Python
- ستكون قادرًا على تضمين وحدة في برنامجك باستخدام الأمر
import- ستعرف كيف تبحث عن مزيد من المعلومات عن محتويات الوحدات
العودة إلى تصحيح الأخطاء
لقد صادفنا بالفعل عددًا لا بأس به من طرق تصحيح الأخطاء في هذه الدورة. ينبغي أن تكون أداة التصوير المرئي مألوفة لك الآن، كما أصبحت أوامر الطباعة التشخيصية عادة قديمة راسخة. وربما جرّبت أيضًا مصحّح الأخطاء المدمج في Visual Studio Code. وإذا واجهت مشكلات تتعلق بعدم عثور مصحّح الأخطاء على ملفاتك، فقد كانت هناك بعض النصائح للتعامل مع هذه الحالات في الجزء السابق.
جاء الإصدار 3.7 من Python بأداة أخرى سهلة ومفيدة لتصحيح أخطاء البرامج: الأمر breakpoint().
يمكنك إضافة هذا الأمر إلى أي موضع في شيفرتك (ضمن القواعد النحوية المعتادة، بطبيعة الحال). وعند تشغيل البرنامج يتوقف التنفيذ عند الموضع الذي أدخلت فيه الأمر breakpoint. وفيما يلي مثال على جهود تصحيح الأخطاء عند إكمال أحد تمارين الجزء السابق (يُرجى تجاهل أسماء المتغيّرات الفنلندية في الصور، والتركيز على الوظيفة):

عندما يتوقف التنفيذ عند الأمر breakpoint، تُفتح نافذة طرفية تفاعلية. وهنا يمكنك كتابة أي شيفرة كما تفعل في طرفية Python عادية، ورؤية كيف تعمل الشيفرة عند ذلك الموضع بالتحديد في البرنامج.
الأمر breakpoint مفيد بشكل خاص عندما تعرف أن سطرًا ما من الشيفرة يُسبّب خطأً، لكنك لا تعرف تمامًا سببه. أضف نقطة توقف قبل سطر الشيفرة المشكِل مباشرة وشغّل برنامجك. الآن يمكنك تجربة خيارات مختلفة في نافذة الطرفية التفاعلية، ومعرفة الأوامر الصحيحة التي ينبغي تضمينها في برنامجك.
ومن الممكن أيضًا متابعة التنفيذ من الموضع الذي توقف عنده. فالأمر continue، أو اختصاره c، المكتوب في طرفية تصحيح الأخطاء يستأنف التنفيذ حتى بلوغ نقطة التوقف التالية. وتُصوّر الصورة التالية حالة نُفّذت فيها الحلقة بالفعل بضع مرات:

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

الأمر exit يُنهي تنفيذ البرنامج.
عندما تنتهي من تصحيح الأخطاء، تذكّر إزالة أوامر breakpoint من شيفرتك!
استخدام الوحدات
يحتوي تعريف لغة Python أصلًا على بعض الدوال المفيدة، مثل الدالة len التي تُعيد طول سلسلة نصية أو قائمة، أو الدالة sum التي تُعيد مجموع العناصر في بنية بيانات، لكن ذلك لن يكفي المبرمج إلا إلى حدّ معيّن. و_المكتبة القياسية_ (standard library) في Python مجموعة من الدوال والكائنات الموحّدة، يمكن استخدامها لتوسيع القدرة التعبيرية لـ Python بطرق كثيرة. وقد استخدمنا بالفعل بعض الدوال المعرّفة في المكتبة القياسية في تمارين سابقة، مثلًا عند حساب الجذور التربيعية.
وتتكوّن المكتبة القياسية من وحدات (modules) تحتوي على دوال وأصناف مجمّعة حول موضوعات ووظائف مختلفة. وفي هذا الجزء من الدورة سنتعرّف على بعض وحدات Python المفيدة. وسنتعلّم أيضًا كتابة وحداتنا الخاصة.
الأمر import يجعل محتويات الوحدة المعطاة متاحة في البرنامج الحالي. ولننظر عن قرب إلى العمل مع وحدة math. فهي تحتوي على تعريفات بعض الدوال الرياضية، مثل sqrt للجذر التربيعي وlog للوغاريتم.
import math
# The square root of the number 5
print(math.sqrt(5))
# the base 2 logarithm of the number 8
print(math.log(8, 2))
2.23606797749979
3.0
الدوال معرّفة في وحدة math، لذا يجب الإشارة إليها بالصيغة math.sqrt وmath.log في شيفرة البرنامج.
تحديد أقسام معيّنة من وحدة
وهناك طريقة أخرى لاستخدام الوحدات، وهي تحديد كيان معيّن من الوحدة بالأمر from. وإذا أردنا استخدام الدالتين sqrt وlog فقط من وحدة math، فيمكننا فعل ما يلي:
from math import sqrt, log
print(sqrt(5))
print(log(5,2))
وكما ترى أعلاه، لا نحتاج إلى بادئة math عند استخدام الدوال المستورَدة بهذه الطريقة.
وأحيانًا يكون من المفيد الاستيراد السريع لـ_جميع_ محتويات وحدة بترميز النجمة:
from math import *
print(sqrt(5))
print(log(5,2))
ويمكن أن يكون استيراد الوحدات بترميز النجمة مفيدًا عند الاختبار وفي بعض المشاريع الأصغر، لكنه قد يطرح بعض المشكلات الجديدة أيضًا. وسنصادف هذه المشكلات لاحقًا.
تمرين برمجي: الوتر
يُرجى كتابة دالة اسمها
hypotenuse(leg1: float, leg2: float)، تأخذ طولَي الضلعين المجاورين للزاوية القائمة في مثلث قائم. وينبغي أن تُعيد الدالة طول الوتر، أي الضلع المقابل للزاوية القائمة.
ويمكنك استخدام مبرهنة فيثاغورس لحساب النتيجة. وستحتاج إلى الدالة sqrt من وحدة math.
بعض الأمثلة:
print(hypotenuse(3,4)) # 5.0
print(hypotenuse(5,12)) # 13.0
print(hypotenuse(1,1)) # 1.4142135623730951
محتويات الوحدة
تحتوي وثائق Python على موارد واسعة عن كل وحدة في مكتبة Python القياسية. وتضمّ الوثائق معلومات عن الدوال والتوابع المعرّفة في الوحدة، وكيف يمكن استخدام الوحدة. فمثلًا، هذا هو الرابط إلى وثائق وحدة math:
- https://docs.python.org/3/library/math.html
ويمكننا أيضًا إلقاء نظرة على محتويات الوحدة بالدالة dir:
import math
print(dir(math))
تُعيد الدالة قائمة بالأسماء التي تعرّفها الوحدة. وقد تكون هذه الأسماء، مثلًا، أسماء أصناف أو قيمًا ثابتة أو دوالًّا:
['\_\_doc\_\_', '\_\_name\_\_', '\_\_package\_\_', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
تمرين برمجي: المحارف الخاصة
تحتوي وحدة Python المسماة string على بعض الثوابت النصية، التي تعرّف مجموعات معيّنة من المحارف. ومنها مثلًا الأحرف الصغيرة ومحارف الترقيم. يُرجى التعرّف على هذه الثوابت، ثم كتابة دالة اسمها
separate_characters(my_string: str). تأخذ الدالة سلسلة نصية كوسيط لها، وينبغي أن تفصل محارف السلسلة النصية إلى ثلاث سلاسل نصية أخرى، وتُعيدها في صف (tuple):
- ينبغي أن تحتوي السلسلة النصية الأولى على الأحرف اللاتينية الصغيرة والكبيرة (الثابت النصي
ascii_letters) - ينبغي أن تحتوي السلسلة النصية الثانية على جميع محارف الترقيم التي يعرّفها الثابت النصي
punctuation - ينبغي أن تحتوي السلسلة النصية الثالثة على جميع المحارف الأخرى (بما في ذلك المسافات البيضاء)
وينبغي أن تظهر المحارف في السلاسل النصية الثلاث بالترتيب نفسه الذي ظهرت به في السلسلة النصية الأصلية.
ومثال على عمل الدالة:
parts = separate_characters("Olé!!! Hey, are ümläüts wörking?")
print(parts[0])
print(parts[1])
print(parts[2])
OlHeyaremltswrking
!!!,?
é üäü ö
تمرين برمجي: الكسور
يُرجى التعرّف على وحدة Python المسماة
fractions. واستخدمها لكتابة دالة اسمهاfractionate(amount: int)، تأخذ عدد الأجزاء كوسيط لها. وينبغي أن تقسّم الدالة العدد 1 إلى عدد من الكسور المتساوية في الحجم يساوي ما يحدّده الوسيط، وتُعيدها في قائمة.
ومثال على عمل الدالة:
for p in fractionate(3):
print(p)
print()
print(fractionate(5))
1/3
1/3
1/3
[Fraction(1, 5), Fraction(1, 5), Fraction(1, 5), Fraction(1, 5), Fraction(1, 5)]