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

في الدرس 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

(1) القيم البوليانية هي أرقام أيضاً

في بايثون، 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}")
▶ جرّب الكود

Output:

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 صحيحة، وبالنفي تصبح 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 سلسلة فارغة. سنتناول القيم "الزائفة" لاحقاً.

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

Output:

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

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

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

Output:

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، لكنه مهم جداً لدرجة أننا سنتعمق أكثر. المعاملات المنطقية في بايثون تتوقف عن التقييم فوراً بمجرد تحديد النتيجة، دون تنفيذ بقية التعبير.

(1) الدائرة القصيرة لـ 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}")

Output:

TEXT 📖 للعرض فقط
False and check_right():
Result: False

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

(2) الدائرة القصيرة لـ or: اليسار True -> اليمين لا يُنفذ

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

(3) الاستخدامات الكلاسيكية للتقييم بالدائرة القصيرة

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

PYTHON
# افترض أن user قد يكون None (المستخدم غير موجود)
user = None
# user.get("name") سيسبب خطأً — None ليس له طريقة get

# استخدم الدائرة القصيرة للحماية:
name = user and user.get("name")
print(name)   # None — user زائف، حدثت دائرة قصيرة، ولم تُستدعَ user.get()

# إذا كان المستخدم موجوداً:
user = {"name": "Xiao Ming"}
name = user and user.get("name")
print(name)   # Xiao Ming

2. تعيين القيم الافتراضية

PYTHON
# إذا لم يُدخل المستخدم اسماً، استخدم قيمة افتراضية
user_input = ""           # سلسلة فارغة (زائفة)
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" بيثوني جداً — إذا كان الجانب الأيسر زائفاً (سلسلة فارغة)، استخدم الأيمن؛ وإذا كان صادقاً (به محتوى)، استخدم الأيسر. إنه يستفيد من سلوك الدائرة القصيرة لـ or.



6. القيم الصادقة والزائفة

في بايثون، يمكن استخدام أي قيمة كقيمة بوليانية في الشرط. بعض القيم تعتبر "زائفة"، وكل ما عداها "صادق".

(1) القيم الزائفة الشائعة

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 — قيمة فارغة

كل ما عدا ذلك صادق:

PYTHON
print(bool(1))          # True — عدد غير صفري
print(bool(-5))         # True — الأعداد السالبة صادقة أيضاً!
print(bool("Python"))   # True — سلسلة غير فارغة
print(bool(" "))        # True — المسافة حرف، وغير الفارغ صادق
print(bool([1, 2]))     # True — قائمة غير فارغة

تحذير: -5 و " " (المسافة) كلاهما صادق، وقد يفاجئك ذلك. -5 عدد صحيح غير صفري، لذا فهو صادق. المسافة حرف، مما يجعل السلسلة غير فارغة، لذا فهي صادقة. فقط السلسلة الفارغة "" زائفة.

(2) استخدام الصدقية لتبسيط الكود

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

تلميح: الاستفادة من الصدقية تجعل الكود أنظف. 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 بسبب التحسين الداخلي في بايثون، فإن هذا تفصيل تنفيذي وغير موثوق. استخدم دائماً == لمقارنة القيم.

(1) الاستخدام الصحيح: التحقق من None

لدى مجتمع بايثون عرف — عند التحقق مما إذا كانت القيمة None، استخدم دائماً is، وليس == أبداً:

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

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


▶ مثال: التحقق من شروط التسجيل (الصعوبة ⭐⭐)

PYTHON
username = "alice2026"
password = "abc123"
age = 20
agreed_terms = True

is_valid = (
    bool(username) and
    len(password) >= 6 and
    age >= 18 and
    agreed_terms
)

reason = (
    (not username and "Username is empty") or
    (len(password) < 6 and "Password too short") or
    (age < 18 and "Underage") or
    (not agreed_terms and "Terms not agreed") or
    "Registration successful"
)

print(f"Registration result: {is_valid}")
print(f"Reason: {reason}")

age = 16
is_valid2 = bool(username) and len(password) >= 6 and age >= 18 and agreed_terms
reason2 = (
    (not username and "Username is empty") or
    (len(password) < 6 and "Password too short") or
    (age < 18 and "Underage") or
    (not agreed_terms and "Terms not agreed") or
    "Registration successful"
)
print(f"Registration result: {is_valid2}")
print(f"Reason: {reason2}")
▶ جرّب الكود

Output:

TEXT 📖 للعرض فقط
Registration result: True
Reason: Registration successful
Registration result: False
Reason: Underage


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


❓ أسئلة شائعة

س ما الفرق بين True و "True"؟
ج True (بدون علامات اقتباس) قيمة بوليانية؛ و "True" (بعلامات اقتباس) سلسلة نصية. إنهما مختلفتان: type(True) هي <class 'bool'>، و type("True") هي <class 'str'>. في الشرط، if "True": دائماً True (السلسلة غير الفارغة صادقة)، و if "False": أيضاً دائماً True (غير فارغة أيضاً). لذا لا تضع علامات اقتباس حول القيم البوليانية في الشروط أبداً.
س متى يجب أن أستخدم is مقابل ==؟
ج استخدم == في 99% من الحالات. is عرفية فقط في سيناريو واحد — التحقق من None: if result is None:. استخدم == لكل مقارنات القيم الأخرى. تذكر: == تقارن "القيمة"، و is تقارن "الهوية".
س ما هي المزالق التي ينطوي عليها التقييم بالدائرة القصيرة لـ and/or؟
ج المأزق الأكثر شيوعاً يتعلق باستدعاءات الدوال. إذا وضعت استدعاء دالة على الجانب الأيمن من and أو or، فقد لا يُنفذ بسبب الدائرة القصيرة، ولن تعرف أنه تم تخطيه. إذا كانت تلك الدالة لها آثار جانبية (تسجيل السجلات، إرسال رسائل البريد الإلكتروني، تحديث العدادات)، فقد تسبب الدائرة القصيرة سلوكاً غير متسق. ممارسة جيدة: إذا كان للتعبير الأيمن آثار جانبية، لا تعتمد على الدائرة القصيرة — اكتبها بشكل منفصل.
س لماذا تُرجع not not "hello" قيمة True؟
ج not "hello" تقيّم أولاً "hello" كقيمة بوليانية (السلسلة غير الفارغة صادقة)، ثم تنفيها لتحصل على False. ثم not not "hello" تنفي False مرة أخرى، لتحصل على True. لذا not not x تعادل bool(x) — تحويل x إلى قيمة بوليانية. لكن هذا النمط غير شائع؛ استخدم bool(x) مباشرة للوضوح.

📖 ملخص


📝 تمارين

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

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

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

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

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

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%