My name is Adam and I'm 25 years old
4 الأفعال
الفعل: قطعة كود مخزَّنة مسمَّاة. عادة ما يكون لها عوامل متغيرة.
نحو: int(x)
لإنشاء العدد الصحيح من النص. مثل: int("12")
ينتج: 12
.
وقد يأخذ عاملين نحو: round(x, n)
مثل: round(10.259, 2)
ينتج: 10.26
.
وقد يأخذ عاملاً واحدًا لكنَّهُ قائمة نحو: sum(numbers)
مثل: sum([1, 2, 3, 4, 5])
ينتج: 15
.
وقد يكون عدد عوامله لا محدودًا نحو: print(*values)
. وعلامة النجمة *
تشير لقبول عوامل مفكوكة على نحو ما تقدَّم، لا كالقائمة. مثل:
فإن print
قبلت خمسة عوامل:
- النص:
"My name is"
- قيمة المتغير:
name
- النص:
"and I'm"
- قيمة المتغير:
age
- النص:
"years old"
وقد يكون عامله غير واجب نحو: range(start, stop, step)
وقد تقدم الكلام عنها في باب التكرار.
ولدينا الفعل help(func)
يطلب مساعدة الفعل المعيَّن، بلا أقواس، هكذا:
Help on built-in function sum in module builtins:
sum(iterable, /, start=0)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
وقد عرفت أن طلب التنفيذ يكون بالقوسين بعد اسمه ()
، وتوضَع العوامل فيهما وهي ضربان:
- عامل مؤثر
- عامل متأثر
وفي كل ما سبق كانت العوامل من نوع المؤثر؛ لأنها كانت تؤثر في النتيجة ولا تتأثر بها.
أما المتأثر فنحو فعل الترتيب من مكتبة القائمة: list.sort(xs)
فإن المتأثر به القائمة نفسها، مثل:
فأما جملة list.sort
فإن اسم النوع list
أردنا منه الفعل sort
، وأتيْنا بالقوسين لطلب تنفيذه، ووضعنا المتأثر xs
فيه.
ومع أننا لم نعيِّن النتيجة، فقد تغيَّرت القائمة، وهذا ما نقصده بأن المتأثر هو ما يتأثر بالفعل:
بعكس الترتيب بالفعل الذي ليس من المكتبة: sorted(xs)
فإنَّ القائمة فيه ليست متأثرًا؛ إذْ يُنتِجُ الفعلُ قائمةً جديدةً ولا يغير القائمة المُدخلة:
xs = [40, 20, 10, 30]
ys = sorted(xs)
print(xs, "لم يعمل الفعل في القائمة نفسها")
print(ys, "هي قائمة جديدة")
[40, 20, 10, 30] لم يعمل الفعل في القائمة نفسها
[10, 20, 30, 40] هي قائمة جديدة
ويجتمع المؤثر والمتأثر في نحو:
فالفعل list.append
يأخذ القائمة، ويضيف إليها القيمة 50
. ولذلك نقول الأوَّل متأثر والثاني مؤثر. وإن شئت قل: متأثر ومؤثر.
وقد وضعت اللغات الشيئية (Object-Oriented) مثل بايثون صياغة خاصَّةً: للفِعْل المُقَدَّمِ مفعولُه. ونقصد بالمفعول الشيئ المتأثر؛ فهكذا:
- مفعول ثم فعل ثم العوامل المؤثرة:
xs.append(25)
- اسم ثم فعل ثم مفعول ثم العوامل المؤثرة:
list.append(xs, 25)
وكلاهما يؤدي نفس المعنى.
وحرف النقطة .
يصل لما هو مُسنَد إلى الشيء، سواءٌ كان اسم نوع نحو list
أو معيَّنًا من النوع نحو xs
.
ومثاله أيضًا في الفعل list.sort
يأخذ القائمة، ويصنفها:
وقد تُعَيَّنُ العوامل بأحد طريقتين:
- تعيين بالموضع: نحو:
round(3.14159, 2)
- تعيين بالاسم: نحو:
round(number=3.14159, ndigits=2)
فلا يشترط فيه ترتيب العوامل.
ويجوز استعمال الطريقتين معًا في نحو: list.sort(numbers, reverse=True)
ويشترط فيه تقدم التعيين بالموضع ليكون في مكانه، ثم يتبعه التعيين بالاسم حيث لا يشترط الترتيب فيه.
4.1 التعريف والتفاصيل والتنفيذ
نذلف الآن لإنشاء أفعال جديدة.
يعرَّف الفعل بـ def
ويتكون من ثلاثة أجزاء:
- اسم الفعل: الذي يُطلَبُ به
- العوامل: سميت كذلك لأن نتيجة الفعل تتغير بتغيرها. ويتم تعيينها لاحقًا
- التفاصيل: وهي القطعة البرمجية التي جُعِلَ اسمه عنوانًا لها
أما جملة الرجوع return
فإنَّها مخرج الفعل بالنتيجة لموضع الطلب.
وعند طلب التنفيذ نعين العوامل ..
فينتج لنا بطلب calculate_grade(95)
نسخة معيَّنة من تفاصيل الفعل، نسمّيها ظرف التنفيذ ؛ يكون فيه المتغير score=95
كأنه هكذا:
if 95 >= 90:
return "A"
elif 95 >= 80:
return "B"
elif 95 >= 70:
return "C"
elif 95 >= 60:
return "D"
else:
return "F"
وبطلب تنفيذ calculate_grade(80)
يكون الظرف هكذ:
if 80 >= 90:
return "A"
elif 80 >= 80:
return "B"
elif 80 >= 70:
return "C"
elif 80 >= 60:
return "D"
else:
return "F"
لاحظ أن نتيجة السطرين بحسب الظرفين المختلفين:
وقد نعدد عوامل كثيرة، نحو:
def weather_condition(temperature, humidity, wind_speed):
if temperature >= 30 and humidity >= 60 and wind_speed >= 10:
return "Rainy"
elif temperature >= 20 and humidity >= 50 and wind_speed >= 5:
return "Cloudy"
elif temperature >= 10 and humidity >= 30 and wind_speed >= 0:
return "Sunny"
return "Normal"
ويكون طلبها بالطريقتين كما تقدَّم، بالموضع أو بالاسم (ولا يشترط في الثانية الترتيب):
4.2 العوامل الجائزة
الأصل في العوامل المعرَّفة الوجوب؛ إلا ما عُيِّن عند التعريف، ولو بالقيمة العدميَّة None
أو ما يوازيها من القيَم الصفرية. وينسخُ ذلك التعيينَ التعيينُ عند طلب الفعل.
لو أردنا للفعل أن يتكيَّف بحسب المؤثر المعيَّن، بحيث:
- لو عينت السلزيوس فالتحويل لفهرنهايت:
convert_temperature(celsius=32)
- لو عينت الفهرنهايت فالتحويل لسلزيوس:
convert_temperature(fahrenheit=89.6)
وإليك معادلة التحويل بين نوعيْ درجة الحرارة:
\[ F = \frac{9}{5} C + 32 \]
فنعرِّفُ العوامل بقيَم عدميَّة، ونفحص وجودها بالشرط is not None
لنُعمِلَها أو نهملها:
نتأكد:
4.3 التصريح بالنوع
وجاز في بايثون ذكر أنواع العوامل والنواتج، وليس بلازِم ولا مُلزِم. فوجودُها وضوحٌ للمبرمِجين ولا يُلزِمُك بها المفسِّر. نحو:
فعبارة: a: int = 0
تتكون من ثلاثة أجزاء:
- اسم العامل:
a
- نوعه:
int
- القيمة الابتدائية:
0
وكذلك b: str = ''
مثلها.
وبعد السهم نوع ناتج الفعل: -> float
ومن الأنواع المبنيَّة في بايثون:
int
الأعداد الصحيحة، نحو:10
float
الأعداد العشرية، نحو:10.5
str
وهي نوع النص، نحو:"Salam"
list
قائمة وإن شئت تحديد نوع العنصر الواحد فيها؛ فإنك تضعه بين القوسين المربعين، نحو:list[int]
list[float]
list[str]
4.4 نطاق التسمية
ومن خصائصها أن المتغيرات في الداخل لا تظهر للخارج.
فنتوقع وقوع خطأ هنا لأن bmi
غير معرفة إلا في نطاق الفعل:
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[38], line 1 ----> 1 print(bmi) NameError: name 'bmi' is not defined
وعلى العكس فإن المعرَّفات الخارجة معروفة في الداخل؛ فيمكن أن تكون عاملة في الفعل:
والنصيحة العامة: أن يكون الاستعمال تاليًا لأخص نطاق، ما أمكن.
4.5 ثمرة الفعل
تُخرج الأفعال نتائج معالجتها بإحدى طريقتين:
- الرجوع: حيث ترجِع النتيجة بجملة
return
لموضع طلب الفعل، وغالبًا ما يتم تعيينه نحو:y = sqrt(x)
- العمل في مفعول:
- مذكور، نحو:
list.sort(xs)
حيث تعدَّل القيمة التي يشير إليها المتغيرxs
- محذوف، نحو:
print(...)
حي وُضِعَت لمفعوله قيمة ابتدائيةfile=sys.stdout
لذا تُكتَبُ النتيجة على الشاشة
- مذكور، نحو:
والفعل دائمًا يرجع بنهاية آخر جملة فيه، لكن الذي لا يصرَّحُ فيه بكلمة الرجوع return
تُقدَّر له القيمة العدمية: None
ويسمى الفعل حنيها خاويًا (void).
تأمل المثال التالي الذي يأخذ عوامل ثم لا يرجع بشيء، لكنه يُظهر النتيجة على الشاشة، وقد كتبنا فيه جملة الرجوع return None
لكنها مقدَّرة على أية حال، ولا يلزمنا أن نضعها: