אופרטורים לוגיים

החומר במחברת זו הוא מעט תיאורטי. אין סיבה להיות עצובים, במחברת הבאה נעשה בו שימוש רחב.
ודאו שאתם מבינים היטב את החומר במחברת זו כדי לבסס את הידע שלכם כראוי.

מבוא

בשיעור הקודם למדנו קצת על ביטויים בוליאניים – ביטויים שתוצאתם היא בהכרח אמת או שקר.
ראינו איך מנסחים ביטויים כאלו, ולמדנו על אופרטורי השוואה כמו == או in, שבעזרתם אנחנו מחליטים באיזו צורה אנחנו רוצים להשוות בין ביטויים.
למדנו שביטויים כאלו יכולים לעזור לנו לשאול שאלות מעניינות, כמו אם למשתמש יש יותר מ־1000 ש"ח בבנק, או אם לבת שלו קוראים "שמחה".

אבל מה יקרה כשנרצה לשאול שאלות מורכבות יותר?
לדוגמה, אם התנאים להרשמה לבנק שלנו הם גם שיהיו לך יותר מ־1,000 ש"ח, וגם שתלמד בפקולטה נחשבת?
למרבה הצער, בכלים שיש ברשותנו כרגע לא נוכל לנסח שאלות מורכבות שכאלו.
במחברת זו זה נלמד על כלים חדשים, אופרטורים לוגיים, שיאפשרו לנו לנסח שאלות מורכבות יותר.

הגדרה

כאמור, לעזרתנו מתגייסים "אופרטורים לוגיים", שמטרתם לאפשר לנו לשאול שאלות בנוגע לקשרים בין ביטויים בוליאניים.
ישנם שלושה אופרטורים לוגיים: and ("וגם"), or ("או") ו־not ("לא").

דוגמאות

  • האם 2 גדול מ־1, וגם קטן מ־3?
  • האם הלקוח הזמין בירה, וגם גיל הלקוח נמוך מ־18?
  • האם הפיצה תגיע בחצי שעה הקרובה, או האם יש אוכל במקרר?
  • האם נתקע לי אוכל בין השיניים, וגם על השולחן לא נמצאים קיסמים?
  • האם המזגן בביתי פועל, וגם אני לא נמצא בביתי?
  • האם המשתמש הקיש בכספומט קוד סודי לא נכון, או ניסה למשוך מספר מזומנים גדול מהסכום שיש לו?

מהדוגמאות נוכל לשים לב לדפוס חוזר – האופרטורים הלוגיים "וגם" ו"או" מקבלים משני צידיהם ביטויים בוליאניים, ומחזירים ביטוי בוליאני אחד.
האופרטור הלוגי "לא" מקבל רק ביטוי בוליאני אחד, והופך אותו.
לדוגמה: בשאלה האם 2 גדול מ־1 (כן) וגם 2 קטן מ־3 (כן), האופרטור הלוגי "וגם" מקבל "כן" משני צידיו, ומחזיר את התשובה הסופית כן.

אופרטורים לוגיים

and / וגם

האופרטור הלוגי and פועל על שני ביטויים בוליאניים, אחד מימינו ואחד משמאלו, ומחזיר לנו ביטוי בוליאני אחד:
True אם הביטויים בשני צידיו היו True, או False בכל מקרה אחר.
מבחינת מינוחים, and נחשב "האופרטור" (operator), והביטויים שנמצאים מצידיו נקראים "האופרנדים".


In [ ]:
print("True and True => " + str(True and True))
print("False and True => " + str(False and True))
print("True and False => " + str(True and False))
print("False and False => " + str(False and False))

נבדוק, בעזרת פייתון, אם 2 גדול מ־1 וקטן מ־3:


In [ ]:
two_is_greater_than_one = 2 > 1
two_is_smaller_than_three = 2 < 3
two_is_between_one_and_three = two_is_greater_than_one and two_is_smaller_than_three
print(two_is_between_one_and_three)

או בקיצור:


In [ ]:
print(2 > 1 and 2 < 3)

or / או

האופרטור הלוגי or פועל על שני ביטויים בוליאניים, אחד מימינו ואחד משמאלו, ומחזיר לנו ביטוי בוליאני אחד:
True אם לפחות אחד מהביטויים, מימינו או משמאלו, הם True.
הוא יחזיר False רק אם הביטויים בשני הצדדים שלו הם False.
מבחינת מינוחים, or נחשב "האופרטור" (operator), והביטויים שנמצאים מצידיו נקראים "האופרנדים" (operands).


In [ ]:
print("True or True => " + str(True or True))
print("False or True => " + str(False or True))
print("True or False => " + str(True or False))
print("False or False => " + str(False or False))

נבדוק בעזרת פייתון אם אחת האותיות, a או x, נמצאות במילה "barvaz".


In [ ]:
a_in_barvaz = 'a' in 'barvaz'
x_in_barvaz = 'x' in 'barvaz'
a_or_x_in_barvaz = a_in_barvaz or x_in_barvaz
print(a_or_x_in_barvaz)

או בקיצור:


In [ ]:
print('a' in 'barvaz' or 'x' in 'barvaz')

not / לא

האופרטור הלוגי not פועל על ביטוי בוליאני אחד שבא אחריו, ומחזיר לנו את הביטוי הבוליאני ההפוך לו. רוצה לומר:
True אם הביטוי הבוליאני שאחריו הוא False.
False אם הביטוי הבוליאני שאחריו הוא True.
מבחינת מינוחים, not נחשב "האופרטור" (operator), והביטוי שנמצא אחריו נקרא "האופרנד" (operand).


In [ ]:
print("not True => " + str(not True))
print("not False => " + str(not False))

נבדוק בעזרת פייתון האם המילה "barvaz" לא כוללת בתוכה את האות "q":


In [ ]:
is_q_in_barvaz = 'q' in 'barvaz'
is_q_not_in_baraz = not is_q_in_barvaz
print(is_q_not_in_baraz)

או בקיצור:


In [ ]:
print(not 'q' in 'barvaz')

טריק מגניב כתוספת: פייתון מאפשרת לנו לכתוב את זה אפילו בצורה קריאה יותר, בעזרת האופרטור not in:


In [ ]:
print('q' not in 'barvaz')

דוגמה

לצורך המשך השיעור, נניח שיש לנו את המשתנים הבאים.
הריצו את התא ומלאו ערכים. נשתמש במשתנים האלו בהמשך.


In [ ]:
people_in_party = int(input('How many people in your party?: '))
whole_pizzas = int(input('How many pizzas did you order?: '))
slices_of_pizza = 8 * whole_pizzas

מסיבה שמחה היא מסיבה שיש בה לפחות 20 משתתפים, וגם יותר מ־100 משולשי פיצה.
עד עכשיו, היינו יכולים לבדוק האם מסיבה היא שמחה רק בצורה הזו, שמדפיסה לנו 2 תשובות:


In [ ]:
print(people_in_party >= 20)
print(slices_of_pizza > 100)

אפשר להגיד כאן שרק במקרה שגם בשורה הראשונה הודפס True וגם בשורה השנייה הודפס True, המסיבה היא מסיבה שמחה.
הסיטואציה הזו, כך נראה, מתאימה לאופרטור הלוגי הראשון שדיברנו עליו – and, ובשמו העברי "וגם".
השאלה ששאלנו היא "האם מספר האנשים במסיבה הוא לפחות 20, וגם מספר משולשי הפיצה במסיבה הוא מעל 100".
ננסח בקוד:


In [ ]:
print("Is it a happy party?")
print(people_in_party >= 20 and slices_of_pizza > 100)

"מסיבה עצובה" היא מסיבה שיש בה עד 5 משתתפים, או שבה אין משולש פיצה לכל משתתף.
עד עכשיו, היינו יכולים לעשות את זה רק בצורה הזו, שמדפיסה לנו 2 תשובות:


In [ ]:
print(people_in_party <= 5)
print(slices_of_pizza < people_in_party)

אפשר להגיד כאן שבמקרה שתוצאת השורה הראשונה היא True או שתוצאת השורה השנייה היא True, המסיבה היא מסיבה עצובה.
הסיטואציה הזו, כך נראה, מתאימה לאופרטור הלוגי השני שדיברנו עליו – or, ובשמו העברי "או".
השאלה ששאלנו היא "האם מספר האנשים במסיבה קטן או שווה ל־5, או מספר משולשי הפיצה קטן ממספר האנשים במסיבה".
ננסח בקוד:


In [ ]:
print("Is it a sad party?")
print(people_in_party <= 5 or slices_of_pizza < people_in_party)

טבלאות אמת

טבלאות אמת זו דרך ישנה נושנה לתאר את התוצאה של אופרטורים לוגיים בכל אחד מהמקרים האפשריים.
נצייר טבלאות כאלו עבור and, or ו־not.
אנחנו ממליצים שלא ללמוד אותן בעל פה, אלא להבין את ההיגיון שבהן.

תוצאה אופרנד שני אופרטור אופרנד ראשון
True True and True
False False and True
False True and False
False False and False
תוצאה אופרנד שני אופרטור אופרנד ראשון
True True or True
True False or True
True True or False
False False or False
תוצאה אופרנד ראשון אופרטור
False True not
True False not

מונחים

אופרטור לוגי
מילה שמבצעת פעולה בין שני ערכים בוליאניים. לפעמים נקרא גם "שער לוגי".
אופרנד
ברבים: אופרנדים. הערכים שעליהם מפעילים את הפעולה. במקרה שלנו, שעליהם אנחנו רוצים להחיל את האופרטור הלוגי.

תרגול

לא או או או וגם וגם?

בהנתן ההשמות שהתבצעו בשורה הבאה, רשמו בצד את התוצאות של כל אחת מהשורות הבאות.
רק לאחר מכן הריצו, ובדקו האם צדקתם בתשובתכם.


In [ ]:
# הריצו את השורות הבאות
age = 17
balaganist = True
have_chartreuse = True
have_fernet = True
have_lime = True
have_sugar = True
degrees_of_cup_in_celsius = 0
is_closed = False

In [ ]:
is_problematic = age < 18 or balaganist
print(is_problematic)

In [ ]:
have_ingredients = have_chartreuse and have_fernet and have_lime and have_sugar
print(have_ingredients)

In [ ]:
cup_is_fine = -273.15 < degrees_of_cup_in_celsius and degrees_of_cup_in_celsius < 4
# טריק! אפשר גם לרשום:
# cup_is_fine = -273.15 < degrees_of_cup_in_celsius < 4
print(cup_is_fine)

In [ ]:
can_drink_industry_sour_cocktail = (not is_problematic) and have_ingredients and cup_is_fine and not is_closed
print(can_drink_industry_sour_cocktail)

מה קיבלתם?
שנו עד 2 משתנים למעלה כדי לקבל תוצאה אחרת.
מצאו 2 תשובות אפשריות.

בואו נמשיך:


In [ ]:
parent_name = 'David'
parent_age = 52

child_name = 'Havatzelet'
child_age = 25

average_max_lifespan_in_israel = 82.4

In [ ]:
parent_name == "David" and parent_age > 52

In [ ]:
'a' == 'b' and 'c' == 'c'

In [ ]:
parent_name == 'David' and parent_name == 'david'

In [ ]:
parent_name == 'David' or parent_age > 53

In [ ]:
'd' in str(parent_age) or 'd' in parent_name

In [ ]:
child_age * 2 > parent_age or child_name in parent_name

In [ ]:
not (child_name == parent_name) or 2 ** 5 == 1

In [ ]:
child_age >= 0 and average_max_lifespan_in_israel > child_age * 2

In [ ]:
not ('y' not in parent_name and 'y' not in child_name) or child_age > parent_age or child_age < 0 or parent_age / 1 == parent_age * 1

קיפיק הצב

קיפיק הצב הוא הלקוח היחיד שאוכל כמה כדורי גלידה, שאחד מהם בטעם כוכבי־על (superstars).
לגלידרייה שלכם נכנס לקוח, שמעוניין לקנות גלידה ממגוון הטעמים שיש במרכולתכם.
קבלו את הטעמים שהוא רוצה להזמין כקלט. אם הלקוח ירצה יותר מטעם אחד, הוא יפריד את הטעמים בפסיק.
בדקו האם מדובר בקיפיק הצב.

לדוגמה, אם הלקוח יזין שהוא מעוניין להזמין superstars, לא מדובר בקיפיק הצב מכיוון שההזמנה כוללת כדור אחד בלבד.
אם הלקוח יזין שהוא מעוניין להזמין pineapple, nettles, לא מדובר בקיפיק הצב מכיוון שההזמנה לא כוללת כדור בטעם המועדף על קיפיק.
אם הלקוח יזין שהוא מעוניין להזמין superstars, creme-brulee, pineapple, נוכל להסיק שמדובר בקיפיק הצב.