المنطق البولياني

في الدرس 03، تعلمنا عن العوامل، بما في ذلك العوامل المنطقية and, or, not. في هذا الدرس، سنركز على الأحكام الصحيحة/الخاطئة — المفهوم الأكثر أساسية في علوم الحاسوب. المنطق البولياني هو أساس جميع الجمل الشرطية والتحكم في الحلقات والتحقق من الأذونات.


1. القيم المنطقية: True و False

هناك قيمتان منطقيتان فقط: True و False. سُميتا على اسم عالم الرياضيات البريطاني جورج بول، الذي أسس الجبر البولياني — الأساس النظري لـ "0 و 1" في الحوسبة الحديثة.

PYTHON
print(True)    # يُخرج: True
print(False)   # يُخرج: False
print(type(True))   # <class 'bool'>

عوامل المقارنة تُنتج نتائج منطقية:

PYTHON
print(5 > 3)      # True
print(10 == 5)    # False
print(7 <= 7)     # True
print(3 != 3)     # False

القيم المنطقية هي أيضاً أرقام

في بايثون، True و False هما في الواقع فئات فرعية من intTrue يعادل 1، False يعادل 0:

PYTHON
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 سيُربك القراء.

مثال: نتائج الفحص الصحي (الصعوبة ⭐)

PYTHON
# أنشئ قيماً منطقية باستخدام عوامل المقارنة
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}")
▶ جرّب الكود

المخرجات:

TEXT
Adult: True
Tall: True
Overweight: False
Adult AND Tall: True

2. not: النفي

not تعني "عكس" — يصبح الأسود أبيضاً، والأبيض أسوداً.

PYTHON
print(not True)      # False
print(not False)     # True
print(not (5 > 3))   # False (5>3 هي True، منفية تصبح False)

not شائعة الاستخدام في سيناريوهين:

السيناريو 1: التحقق من "عدم تحقق الشرط"

PYTHON
# ليس مشرفاً — لا يمكنه دخول لوحة التحكم
is_admin = False
if not is_admin:
    print("You do not have admin access.")
# يُخرج: You do not have admin access.

السيناريو 2: التحقق مما إذا كان المتغير فارغاً

PYTHON
# تحقق مما إذا كان المستخدم لم يقدم اسماً
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
PYTHON
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

مثال: فحص تسجيل الدخول (الصعوبة ⭐)

PYTHON
# محاكاة تسجيل الدخول — اسم المستخدم الصحيح وكلمة المرور الصحيحة
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 — الحساب مقفل
▶ جرّب الكود

المخرجات:

TEXT
Login result: False
Final result: False

4. or: واحد على الأقل True

or تعني "أو" — إذا كان شرط واحد على الأقل صحيحاً، النتيجة True. فقط عندما يكون كلاهما خاطئاً تكون النتيجة False.

اليسار اليمين النتيجة
True True True
True False True
False True True
False False False
PYTHON
# يمكن الراحة في عطلات نهاية الأسبوع أو العطلات الرسمية
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

تمرين: التحقق الكامل من جدول الحقيقة

PYTHON
# تحقق من جدول الحقيقة باستخدام الكود — جميع مجموعات 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}")

المخرجات:

TEXT
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 ← اليمين لا يُنفّذ

PYTHON
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}")

المخرجات:

TEXT
False and check_right():
Result: False

True and check_right():
-> check_right was called!
Result: True

or تقييم قصير: اليسار True ← اليمين لا يُنفّذ

PYTHON
print("True or check_right():")
result = True or check_right()    # check_right لن يُنفّذ
print(f"Result: {result}")

الاستخدامات الكلاسيكية للتقييم القصير

1. الوصول الآمن: منع أخطاء None

PYTHON
# افترض أن 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. تعيين القيم الافتراضية

PYTHON
# إذا لم يدخل المستخدم اسماً، استخدم القيمة الافتراضية
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 الشائعة

PYTHON
# هذه القيم تعادل 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:

PYTHON
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 لتبسيط الكود

PYTHON
# غير موصى به (مطول)
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}")
💡 نصيحة: الاستفادة من truthiness تجعل الكود أنظف. if name: هو أكثر "بايثونية" من if name != "":. لكن كن حذراً لا تفرط في استخدامه — if score: لن يُنفّذ عندما score=0. إذا كنت بحاجة للتمييز بين "الدرجة 0" و "لا توجد درجة"، استخدم is not None.


7. is و is not: مقارنة الهوية

is يقارن ما إذا كان متغيران يشيران إلى نفس الكائن (نفس المساحة في الذاكرة)، وليس ما إذا كانت قيمهما متساوية. ذكرنا هذا في الدرس 03؛ إليك المزيد من الأمثلة للتوضيح.

PYTHON
# == يقارن القيم، 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، وليس ==:

PYTHON
# الطريقة الصحيحة
result = None
if result is None:
    print("No result")

# غير موصى به
if result == None:
    print("No result")

حالات الاستخدام الشائعة


❓ أسئلة شائعة

س ما الفرق بين 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

📝 تمارين

  1. أساسي (الصعوبة ⭐): توقع قيم هذه التعبيرات، ثم تحقق:

    • not (10 > 5)
    • True and False or True
    • not False and True
    • (5 > 3) or (2 > 10) and (8 == 8)تلميح: انتبه للأولوية — and أعلى من or
  2. متوسط (الصعوبة ⭐⭐): اكتب كوداً للتحقق من سلسلة إدخال المستخدم:

    • إذا كان الإدخال فارغاً، أخرج "الإدخال لا يمكن أن يكون فارغاً"
    • إذا كان الإدخال كله مسافات، عامله أيضاً كـ "الإدخال لا يمكن أن يكون فارغاً" (تلميح: استخدم strip())
    • إذا كان طول الإدخال أقل من 6، أخرج "يجب أن يكون الإدخال 6 أحرف على الأقل"
    • خلاف ذلك، أخرج "الإدخال صالح"
  3. متقدم (الصعوبة ⭐⭐⭐): اكتب "مدقق أرقام ثلاثي." بالنظر إلى رقم مكون من 3 خانات num (مثل 153)، حدد:

    • هل هو زوجي؟ (استخدم %)
    • هل هو قابل للقسمة على كل من 3 و 5؟
    • هل هو متناظر؟ (رقم المئات يساوي رقم الآحاد، مثل 121, 353)
    • كم عدد الشروط المذكورة أعلاه التي تحققت؟ أخرج العدد.

    استخدم فقط التعبيرات المنطقية لجميع الفحوصات — بدون جمل if (احفظها للدرس التالي).

100%