المنطق البولياني
في الدرس 03، تعلمنا عن العوامل، بما في ذلك العوامل المنطقية
and,or,not. في هذا الدرس، سنركز على الأحكام الصحيحة/الخاطئة — المفهوم الأكثر أساسية في علوم الحاسوب. المنطق البولياني هو أساس جميع الجمل الشرطية والتحكم في الحلقات والتحقق من الأذونات.
1. القيم المنطقية: True و False
هناك قيمتان منطقيتان فقط: True و False. سُميتا على اسم عالم الرياضيات البريطاني جورج بول، الذي أسس الجبر البولياني — الأساس النظري لـ "0 و 1" في الحوسبة الحديثة.
print(True) # يُخرج: True
print(False) # يُخرج: False
print(type(True)) # <class 'bool'>
عوامل المقارنة تُنتج نتائج منطقية:
print(5 > 3) # True
print(10 == 5) # False
print(7 <= 7) # True
print(3 != 3) # False
القيم المنطقية هي أيضاً أرقام
في بايثون، True و False هما في الواقع فئات فرعية من int — True يعادل 1، False يعادل 0:
print(True + True) # 2 (True=1, اثنان True = 2)
print(True * 10) # 10
print(False * 100) # 0
True == 1 و False == 0 في بايثون (لذا True + True يساوي 2)، لا تستخدمهما بهذه الطريقة أبداً. القيم المنطقية مخصصة للحكم المنطقي، وليس للحساب. كتابة كود مثل score + True سيُربك القراء.
مثال: نتائج الفحص الصحي (الصعوبة ⭐)
# أنشئ قيماً منطقية باستخدام عوامل المقارنة
age = 25
height = 175
weight = 70
is_adult = age >= 18 # True
is_tall = height > 170 # True
is_heavy = weight > 80 # False
print(f"Adult: {is_adult}")
print(f"Tall: {is_tall}")
print(f"Overweight: {is_heavy}")
# أخرج القيم المنطقية مباشرة — إنها قيم، وليس نصاً
print(f"Adult AND Tall: {is_adult and is_tall}")
المخرجات:
Adult: True
Tall: True
Overweight: False
Adult AND Tall: True
2. not: النفي
not تعني "عكس" — يصبح الأسود أبيضاً، والأبيض أسوداً.
print(not True) # False
print(not False) # True
print(not (5 > 3)) # False (5>3 هي True، منفية تصبح False)
not شائعة الاستخدام في سيناريوهين:
السيناريو 1: التحقق من "عدم تحقق الشرط"
# ليس مشرفاً — لا يمكنه دخول لوحة التحكم
is_admin = False
if not is_admin:
print("You do not have admin access.")
# يُخرج: You do not have admin access.
السيناريو 2: التحقق مما إذا كان المتغير فارغاً
# تحقق مما إذا كان المستخدم لم يقدم اسماً
username = ""
if not username:
print("Username cannot be empty!")
# يُخرج: Username cannot be empty!
هناك خدعة "التحويل البولياني الضمني" في بايثون هنا — السلسلة الفارغة "" تعادل False في فحوصات الشروط. لذا not username هي True عندما تكون username سلسلة فارغة. سنغطي أي القيم "falsy" لاحقاً.
not تعني "نفي." في الكود، if not is_admin: تُقرأ كـ "إذا لم يكن مشرفاً."
3. and: كلاهما يجب أن يكون True
and تعني "كلاهما" — يجب أن يكون كلا الشرطين صحيحين لتكون النتيجة True. إذا كان أي منهما خاطئاً، النتيجة False.
| اليسار | اليمين | النتيجة |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
age = 22
has_id = True
# كلا الشرطين يجب أن يتحققا
can_buy_alcohol = age >= 18 and has_id
print(can_buy_alcohol) # True (كلاهما بالغ ولديه هوية)
# سيناريو آخر: التقدم لبطاقة ائتمان يتطلب دخل >= 50 ألف ونقاط ائتمان >= 600
income = 80 # آلاف
credit_score = 650
qualified = income >= 50 and credit_score >= 600
print(f"Credit card application: {qualified}") # True
مثال: فحص تسجيل الدخول (الصعوبة ⭐)
# محاكاة تسجيل الدخول — اسم المستخدم الصحيح وكلمة المرور الصحيحة
username_correct = True
password_correct = False
can_login = username_correct and password_correct
print(f"Login result: {can_login}") # False — كلمة المرور خاطئة
# أضف طبقة أخرى: يجب ألا يكون الحساب مقفلاً
account_locked = True
can_login = username_correct and password_correct and not account_locked
print(f"Final result: {can_login}") # False — الحساب مقفل
المخرجات:
Login result: False
Final result: False
4. or: واحد على الأقل True
or تعني "أو" — إذا كان شرط واحد على الأقل صحيحاً، النتيجة True. فقط عندما يكون كلاهما خاطئاً تكون النتيجة False.
| اليسار | اليمين | النتيجة |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
# يمكن الراحة في عطلات نهاية الأسبوع أو العطلات الرسمية
is_weekend = True
is_holiday = False
can_rest = is_weekend or is_holiday
print(can_rest) # True (إنها عطلة نهاية الأسبوع)
# أمن المترو: إذا كان لديك ماء أو مشروب، تحتاج إلى تفتيش
has_water = True
has_drink = False
need_check = has_water or has_drink
print(f"Security check needed: {need_check}") # True
تمرين: التحقق الكامل من جدول الحقيقة
# تحقق من جدول الحقيقة باستخدام الكود — جميع مجموعات and و or
a = True
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = True
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
المخرجات:
True and True = True
True or True = True
True and False = False
True or False = True
False and True = False
False or True = True
False and False = False
False or False = False
5. التقييم القصير
ذكرنا هذا في الدرس 03، لكنه مهم جداً لدرجة أننا سنتعمق أكثر. العوامل المنطقية في بايثون تتوقف عن التقييم فوراً بمجرد تحديد النتيجة، دون تنفيذ التعبير المتبقي.
and تقييم قصير: اليسار False ← اليمين لا يُنفّذ
def check_right():
print("-> check_right was called!")
return True
print("False and check_right():")
result = False and check_right() # check_right لن يُنفّذ
print(f"Result: {result}\n")
print("True and check_right():")
result = True and check_right() # check_right سيُُنفّذ
print(f"Result: {result}")
المخرجات:
False and check_right():
Result: False
True and check_right():
-> check_right was called!
Result: True
or تقييم قصير: اليسار True ← اليمين لا يُنفّذ
print("True or check_right():")
result = True or check_right() # check_right لن يُنفّذ
print(f"Result: {result}")
الاستخدامات الكلاسيكية للتقييم القصير
1. الوصول الآمن: منع أخطاء None
# افترض أن user قد يكون None (المستخدم غير موجود)
user = None
# user.get("name") سيُسبب خطأ — None ليس لديه طريقة get
# استخدم التقييم القصير للحماية:
name = user and user.get("name")
print(name) # None — user falsy، اختصر، user.get() لم يُستدعَ
# إذا كان المستخدم موجوداً:
user = {"name": "Xiao Ming"}
name = user and user.get("name")
print(name) # Xiao Ming
2. تعيين القيم الافتراضية
# إذا لم يدخل المستخدم اسماً، استخدم القيمة الافتراضية
user_input = "" # سلسلة فارغة (falsy)
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, guest
user_input = "Zhang San"
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, Zhang San
user_input or "default" هو نمط بايثوني جداً — إذا كان الجانب الأيسر falsy (سلسلة فارغة)، استخدم اليمين؛ إذا كان truthy (له محتوى)، استخدم اليسار. يستفيد من سلوك التقييم القصير لـ or.
6. القيم Truthy و Falsy
في بايثون، أي قيمة يمكن استخدامها كقيمة منطقية في شرط. بعض القيم تُعتبر "falsy"، وكل شيء آخر "truthy."
قيم Falsy الشائعة
# هذه القيم تعادل False في الشروط
print(bool(False)) # False — خطأ منطقي
print(bool(0)) # False — صفر
print(bool(0.0)) # False — صفر عشري
print(bool("")) # False — سلسلة فارغة
print(bool([])) # False — قائمة فارغة (سنغطيها لاحقاً)
print(bool(None)) # False — قيمة فارغة
كل شيء آخر هو truthy:
print(bool(1)) # True — رقم غير صفري
print(bool(-5)) # True — الأعداد السالبة أيضاً truthy!
print(bool("Python")) # True — سلسلة غير فارغة
print(bool(" ")) # True — المسافة حرف، غير فارغة فهي truthy
print(bool([1, 2])) # True — قائمة غير فارغة
-5 و " " (مسافة) كلاهما truthy، وهذا قد يفاجئك. -5 هو عدد صحيح غير صفري، لذا فهو truthy. المسافة حرف، مما يجعل السلسلة غير فارغة، لذا فهي truthy. فقط السلسلة الفارغة "" هي falsy.
استخدام Truthiness لتبسيط الكود
# غير موصى به (مطول)
name = "Xiao Ming"
if name != "":
print(f"Hello, {name}")
# موصى به (موجز)
name = "Xiao Ming"
if name:
print(f"Hello, {name}")
# غير موصى به
score = 85
if score != 0:
print(f"Score: {score}")
# موصى به
score = 85
if score:
print(f"Score: {score}")
if name: هو أكثر "بايثونية" من if name != "":. لكن كن حذراً لا تفرط في استخدامه — if score: لن يُنفّذ عندما score=0. إذا كنت بحاجة للتمييز بين "الدرجة 0" و "لا توجد درجة"، استخدم is not None.
7. is و is not: مقارنة الهوية
is يقارن ما إذا كان متغيران يشيران إلى نفس الكائن (نفس المساحة في الذاكرة)، وليس ما إذا كانت قيمهما متساوية. ذكرنا هذا في الدرس 03؛ إليك المزيد من الأمثلة للتوضيح.
# == يقارن القيم، is يقارن الهوية
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — نفس القيم
print(a is b) # False — لكن ليس نفس كائن القائمة
print(a is c) # True — c هي a، تشير إلى نفس القائمة
# التخزين المؤقت للأعداد الصغيرة (تحسين داخلي في بايثون)
x = 256
y = 256
print(x is y) # قد يكون True — الأعداد الصغيرة مخزنة مؤقتاً
x = 1000
y = 1000
print(x is y) # قد يكون False — الأعداد الكبيرة غير مخزنة مؤقتاً
is أبداً لمقارنة الأعداد الصحيحة أو السلاسل النصية بالقيمة. على الرغم من أن الأعداد الصغيرة قد تُرجع أحياناً True مع is بسبب تحسين بايثون الداخلي، هذه تفاصيل تنفيذية وغير موثوقة. استخدم دائماً == لمقارنة القيم.
الاستخدام الصحيح: التحقق من None
مجتمع بايثون لديه اصطلاح — عند التحقق مما إذا كانت القيمة None، استخدم دائماً is، وليس ==:
# الطريقة الصحيحة
result = None
if result is None:
print("No result")
# غير موصى به
if result == None:
print("No result")
حالات الاستخدام الشائعة
- التحكم في الأذونات:
is_admin or (is_logged_in and has_permission)— ادمج شروطاً متعددة لتقرير ما يمكن للمستخدم فعله. - التحقق من صحة الإدخال:
username and password— تحقق مما إذا كان المستخدم قدم كليهما. - القيم الافتراضية للمعلمات الاختيارية:
timeout or 30— إذا لم يتم تعيين timeout، استخدم القيمة الافتراضية 30 ثانية. - سلسلة الوصول الآمن:
user and user.address and user.address.city— وصول آمن طبقة تلو الأخرى؛ اختصر عند أي خطوة falsy. - التحكم في التبديل:
is_enabled and is_connected— كلا الشرطين يجب أن يتحققا لتستمر العملية.
❓ أسئلة شائعة
True و "True"؟True (بدون علامات اقتباس) هي قيمة منطقية؛ "True" (مع علامات اقتباس) هي سلسلة نصية. إنهما مختلفان: type(True) هو <class 'bool'>، type("True") هو <class 'str'>. في شرط، if "True": هو دائماً True (سلسلة غير فارغة هي truthy)، و if "False": هو أيضاً دائماً True (أيضاً غير فارغة). لذا لا تضع علامات اقتباس حول القيم المنطقية في الشروط.
س:متى يجب استخدام is مقابل ==؟ ج:استخدم == في 99% من الحالات. is اصطلاحي فقط في سيناريو واحد — التحقق من None: if result is None:. استخدم == لجميع مقارنات القيم الأخرى. تذكر: == يقارن "القيمة"، is يقارن "الهوية."
س:ما مخاطر التقييم القصير لـ and/or؟ ج:المخاطرة الأكثر شيوعاً تتعلق باستدعاءات الدوال. إذا وضعت استدعاء دالة على الجانب الأيمن من and أو or، فقد لا يُنفّذ بسبب التقييم القصير، ولن تعلم أنه تم تخطيه. إذا كان لتلك الدالة آثار جانبية (تسجيل، إرسال رسائل بريد إلكتروني، تحديث عدادات)، يمكن أن يسبب التقييم القصير سلوكاً غير متسق. ممارسة جيدة: إذا كان للتعبير الأيمن آثار جانبية، لا تعتمد على التقييم القصير — اكتبها بشكل منفصل.
س:لماذا not not "hello" يُرجع True؟ ج:not "hello" أولاً يُقيّم "hello" كقيمة منطقية (سلسلة غير فارغة هي truthy)، ينفيها ليحصل على False. ثم not not "hello" ينفي False مرة أخرى، ليحصل على True. لذا not not x يعادل bool(x) — تحويل x إلى قيمة منطقية. لكن هذا النمط غير شائع؛ استخدم bool(x) مباشرة للوضوح.📖 ملخص
- القيم المنطقية لها قيمتان فقط:
TrueوFalse؛ إنهما فئات فرعية منint(True=1,False=0)، لكن لا تستخدمهما في الحساب notينفي: صحيح يصبح خطأ، خطأ يصبح صحيحاًandيتطلب أن يكون كلا القيمتين صحيحتينorيتطلب أن تكون قيمة واحدة على الأقل صحيحة- القيم falsy في بايثون تشمل:
False,0,0.0,"",[],None— كل شيء آخر هو truthy - التقييم القصير:
andمع اليسار false ← اليمين لا يُنفّذ؛orمع اليسار true ← اليمين لا يُنفّذ - التقييم القصير يتيح نمطين كلاسيكيين: "الوصول الآمن" و "القيم الافتراضية"
isيقارن الهوية،==يقارن القيمة؛ استخدمisلفحوصاتNone
📝 تمارين
-
أساسي (الصعوبة ⭐): توقع قيم هذه التعبيرات، ثم تحقق:
not (10 > 5)True and False or Truenot False and True(5 > 3) or (2 > 10) and (8 == 8)— تلميح: انتبه للأولوية —andأعلى منor
-
متوسط (الصعوبة ⭐⭐): اكتب كوداً للتحقق من سلسلة إدخال المستخدم:
- إذا كان الإدخال فارغاً، أخرج "الإدخال لا يمكن أن يكون فارغاً"
- إذا كان الإدخال كله مسافات، عامله أيضاً كـ "الإدخال لا يمكن أن يكون فارغاً" (تلميح: استخدم
strip()) - إذا كان طول الإدخال أقل من 6، أخرج "يجب أن يكون الإدخال 6 أحرف على الأقل"
- خلاف ذلك، أخرج "الإدخال صالح"
-
متقدم (الصعوبة ⭐⭐⭐): اكتب "مدقق أرقام ثلاثي." بالنظر إلى رقم مكون من 3 خانات
num(مثل 153)، حدد:- هل هو زوجي؟ (استخدم
%) - هل هو قابل للقسمة على كل من 3 و 5؟
- هل هو متناظر؟ (رقم المئات يساوي رقم الآحاد، مثل 121, 353)
- كم عدد الشروط المذكورة أعلاه التي تحققت؟ أخرج العدد.
استخدم فقط التعبيرات المنطقية لجميع الفحوصات — بدون جمل if (احفظها للدرس التالي).
- هل هو زوجي؟ (استخدم



