cb
codebamin
الفصل 10 · المعاملات المنطقية (Boolean Operators)

المعامل المنطقي or

تعلمنا القيم المنطقية (booleans)، أي True وFalse، عندما تعرفنا على جمل if. وتعلمنا أيضًا عوامل المقارنة == و< و> و<= و>= التي تنتج قيمًا منطقية. الآن نريد دمج القيم المنطقية حتى نستطيع التعبير عن شروط أكثر تعقيدًا.

تخيل مثلًا أن لديك صديقين هما Alice وBob. الدالة التالية تستقبل معاملًا واحدًا اسمه name وتتحقق هل الشخص بهذا الاسم من أصدقائك.

انسخ الكود وشغّله في المحرر:

__copyable__ __program_indented__

لنرَ كيف يمكن تبسيط ذلك.

يمكننا دمج if وelif باستخدام العامل or. العامل or هو عامل منطقي (boolean operator)؛ أي عامل، مثل + أو -، لكنه يجمع قيمتين منطقيتين (True أو False).

التعبير A or B تكون قيمته True إذا كانت A أو B تساوي True، بما في ذلك حالة كون الاثنتين True. ولا تكون النتيجة False إلا عندما تكون كلتا القيمتين False.

جرّب في الطرفية:

True or True

جيد، جرّب الآن:

True or False

توقع النتيجة أولًا، ثم نفّذ التعبير.

وأخيرًا جرّب:

False or False

هذه هي الحالة الوحيدة بين الحالات الأساسية التي يعطي فيها or القيمة False.

ارجع إلى المحرر، واستبدل:

if name == "Alice": return True elif name == "Bob": return True

بـ:

if name == "Alice" or name == "Bob": return True

كما ترى، ستعيد is_friend القيمة True عندما يكون name هو Alice أو Bob. العامل or يقع بين التعبيرين المنطقيين name == "Alice" وname == "Bob"، فيجمع نتيجتي المقارنتين في شرط واحد.

يمكننا تبسيط الدالة أكثر. لاحظ أن:

name == "Alice" or name == "Bob"

هو تعبير منطقي في حد ذاته، وأن فرعي الدالة يعيدان أيضًا True أو False.

الدالة الحالية:

  • تعيد True عندما تكون نتيجة name == "Alice" or name == "Bob" هي True.
  • وتعید False عندما تكون نتيجة التعبير نفسه هي False.

إذن يمكننا ببساطة إعادة نتيجة التعبير نفسه مباشرة.

هذه قاعدة شائعة لتبسيط الكود. إذا وجدت نفسك تكتب:

if x: return True else: return False

وكان x نفسه قيمة منطقية، فيمكن دائمًا اختصار ذلك إلى:

return x

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

انتبه جيدًا إلى الطريقة التي كتبنا بها الشرط:

return name == "Alice" or name == "Bob"

من الأخطاء الشائعة كتابة:

return name == "Alice" or "Bob"

قد تبدو هذه الصيغة منطقية إذا قرأتها كلغة طبيعية، كأنها تعني: «أعد ما إذا كان name يساوي Alice أو Bob». لكن بايثون لا يفسر or بهذه الطريقة.

استبدل سطر return في الكود بالصيغة الخاطئة السابقة وشغّل البرنامج، ثم لاحظ النتيجة.

تتبّع التعبير السابق خطوة بخطوة بدل قراءته كجملة إنجليزية. افصل أولًا المقارنة name == "Alice" عن القيمة الموجودة على يمين or، وراقب ما تصبح عليه نتيجة كل جزء أثناء التقييم.

عند تتبع التعبير خطوة بخطوة نرى أن:

name == "Alice" or "Bob"

لا يتحول إلى:

name == ("Alice" or "Bob")

كما قد نتخيل عند قراءته كلغة طبيعية، وإنما يُفهم هكذا:

(name == "Alice") or ("Bob")

وعندما تكون name == "Alice" هي False يعيد or في هذا المثال القيمة الموجودة على اليمين، أي النص "Bob".

القاعدة العملية التي تحتاجها الآن بسيطة: إلى أن تصبح مرتاحًا تمامًا مع سلوك or، ضع تعبيرًا منطقيًا كاملًا على جانبيه، لأنه عامل منطقي. الصيغة name == "Alice" or "Bob" تكسر هذه القاعدة.

إذا كنت فضوليًا، فالتعريف الشائع «A or B تكون True إذا كانت A أو B صحيحة» هو تبسيط مناسب عندما نتعامل مع القيم المنطقية. التعريف الأدق هو: إذا كانت A قيمة truthy فإن A or B يعيد A نفسها ولا يقيّم B أصلًا؛ وإذا لم تكن A truthy فإنه يعيد B. عندما تكون A وB قيمتين منطقيتين يتوافق هذا تمامًا مع التعريف المبسط. هنا A هي name == "Alice"، فإذا كانت False تصبح نتيجة التعبير هي B، أي النص "Bob".

وهل توجد طريقة لتجنب تكرار name ==؟ نعم في بعض الحالات. مثلًا يمكنك استخدام العامل in مع قائمة:

return name in ["Alice", "Bob", "Charlie"]

لكن لا يمكن استبدال كل استخدامات or بهذه الطريقة.

التمرين: اكتب دالة اسمها is_valid_percentage تستقبل وسيطًا عدديًا واحدًا x. يجب أن تعيد True إذا كانت x بين 0 و100 شاملًا الحدين، وأن تعيد False في غير ذلك. يجب أن تستخدم الدالة or وأن تجتاز الاختبارات:

__copyable__ check_result(is_valid_percentage(-1), False) check_result(is_valid_percentage(0), True) check_result(is_valid_percentage(50), True) check_result(is_valid_percentage(100), True) check_result(is_valid_percentage(101), False)

فكّر أولًا في الحالة غير الصالحة: متى تكون النسبة أقل من الحد الأدنى أو أكبر من الحد الأقصى؟

أحسنت!

solution.py
1
2
3
4
5
6
7
8
9
10
الطرفية (shell)
>>>