المُعامِلات

6.4 المُعامِلات

أهداف التعلم

في نهاية هذا القسم، ينبغي أن تكون قادرًا على:

  • تحديد وسائط الدالّة ومُعامِلاتها.
  • وصف كيفية تأثير قابلية التغيير على قدرة الدالّة على تعديل الوسائط.

الوسائط والمُعامِلات

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

نقطة تحقق

المتغيرات العامة والمحلية في برنامج يحتوي على دالّة

مفاهيم تطبيقية

الوسائط والمُعامِلات

تأمل ما يلي:

1
def print_welcome(name):
2
  print(f"Welcome {name}!")
3
4
username = int(input("Enter new username: "))
5
print_welcome(username)
1.
أي مما يلي يُعد وسيطًا؟
  1. name
  2. username
  3. name و username
2.
أي مما يلي يُعد مُعامِلًا؟
  1. name
  2. username
  3. name و username
3.
ما نطاق name؟
  1. print_welcome() فقط
  2. البرنامج بأكمله
4.
ماذا سيحدث لو تم تغيير username إلى name في السطرين 4 و 5؟
  1. نفس المخرجات
  2. خطأ/مخرجات خاطئة

الوسائط والمُعامِلات المتعددة

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

مثال 6.1

استخدام وسائط متعددة في استدعاء دالّة

    def print_div(op_1, op_2):
      """ Prints division operation """
      print(f"{op_1}/{op_2} = {op_1/op_2}")

    num_1 = 6
    num_2 = 3
    print_div(num_1, num_2) # تطبع "6/3 = 2.0"
    print_div(num_2, num_1) # تطبع "3/6 = 0.5"
    print_div(num_1) # خطأ: وسيط مفقود: op_2

مفاهيم تطبيقية

الوسائط والمُعامِلات المتعددة

تأمل ما يلي:

    def calc_distance(x1, y1, x2, y2):
      dist = math.sqrt((x2-x1)**2 + (y2-y1)**2)
      print(dist)

    p1_x =int(input("Enter point 1's x: "))
    p1_y =int(input("Enter point 1's y: "))
    p2_x =int(input("Enter point 2's x: "))
    p2_y =int(input("Enter point 2's y: "))
    calc_distance(p1_x, p1_y, p2_x, p2_y)
5.
أي مما يلي يُعد وسيطًا؟
  1. p1_x
  2. x1
6.
أي مما يلي يُعد مُعامِلًا؟
  1. p1_y
  2. y1
7.
ماذا ستكون قيمة x2 لاستدعاء الدالّة calc_distance(2, 4, 3, 6)؟
  1. 2
  2. 4
  3. 3
  4. 6
  5. Error

تعديل الوسائط وقابلية التغيير

في بايثون، المتغير هو اسم يشير إلى كائن مخزن في الذاكرة، أي مرجع كائن، لذا تستخدم بايثون نظام التمرير بمرجع الكائن (pass-by-object-reference). إذا تم تغيير وسيط داخل دالّة، فإن التغييرات تُحفظ أو تُفقد اعتمادًا على قابلية تغيير الكائن. الكائن القابل للتغيير (mutable) يمكن تعديله بعد إنشائه. تظهر تغييرات الدالّة على الكائن خارج الدالّة. الكائن غير القابل للتغيير (immutable) لا يمكن تعديله بعد إنشائه. لذا يجب على الدالّة إنشاء نسخة محلية لتعديلها، ولا تظهر تغييرات النسخة المحلية خارج الدالّة.

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

مثال 6.2

تحويل درجات الحرارة

ما قيم weekend_temps و type بعد انتهاء convert_temps()؟

    def convert_temps(temps, unit):
      if unit == "F":
        for i in range(len(temps)):
          temps[i] = (temps[i]-32) * 5/9
        unit = "C"
      else:
        for i in range(len(temps)):
          temps[i] = (temps[i]*9/5) + 32
        unit = "F"

    # درجات حرارة نهاية الأسبوع بالفهرنهايت.
    wknd_temps = [49.0, 51.0, 44.0]
    deg_sign = u"\N{DEGREE SIGN}" # يونيكود
    metric = "F"

    # التحويل من فهرنهايت إلى مئوية.
    convert_temps(wknd_temps, metric)
    for temp in wknd_temps:
      print(f"{temp:.2f}{deg_sign}{metric}", end=" ")

المخرجات هي 9.44°F 10.56°F 6.67°F. تم تغيير type إلى "C" داخل الدالّة لكن التغيير لم يُحفظ خارج الدالّة. لماذا تم الاحتفاظ بتغيير وسيط القائمة ولم يتم الاحتفاظ بتغيير وسيط السلسلة النصية؟ (تلميح: القائمة قابلة للتغيير. السلسلة النصية غير قابلة للتغيير.)

نقطة تحقق

استكشاف دالّة معيبة

مفاهيم تطبيقية

قابلية التغيير ووسائط الدوال

8.
في convert_temps()، يشير wknd_temps و temps إلى ________ في الذاكرة.
  1. نفس الكائن
  2. كائنات مختلفة
9.
بعد إسناد "C" إلى unit، يشير metric و unit إلى ________ في الذاكرة.
  1. نفس الكائن
  2. كائنات مختلفة
10.
deg_sign هي سلسلة نصية لا يمكن تغيير قيمتها بمجرد إنشائها. deg_sign هي ________.
  1. غير قابلة للتغيير
  2. قابلة للتغيير
11.
في السطر 16، unit ________.
  1. يشير إلى كائن بقيمة "C"
  2. غير موجود

جرّب بنفسك

طباعة مساحة المثلث القائم

اكتب دالّة، print_area()، تأخذ قاعدة المثلث القائم وارتفاعه كمدخلات وتطبع مساحة المثلث. مساحة المثلث القائم هي bh2bh2، حيث b هي القاعدة و h هو الارتفاع.

المدخلات المعطاة:

    3
    4

المخرجات هي:

    Triangle area: 6.0

جرّب بنفسك

تعديل الدرجات

اكتب دالّة، print_scores()، تأخذ قائمة من درجات الاختبار ورقمًا يمثل عدد النقاط المراد إضافتها. لكل درجة، اطبع الدرجة الأصلية ومجموع الدرجة والمكافأة. تأكد من عدم تغيير القائمة.

استدعاء الدالّة المعطى:

    print_scores([67, 68, 72, 71, 69], 10)

المخرجات هي:

    67 would be updated to 77
    68 would be updated to 78
    72 would be updated to 82
    71 would be updated to 81
    69 would be updated to 79