De Morgan’s Law in Python

Introduction to De Morgan’s Law

  • Rule for handling logical expressions.
  • Allows you to simplify conditions.

The Two Key Parts of De Morgan’s Law

  • Negating AND:
    • not (A and B) becomes not A or not B
  • Negating OR:
    • not (A or B) becomes not A and not B

Applications in Code

  • Simplifies conditional logic.
  • Example:
is_raining = True
is_cold = False

if not (is_raining and is_cold):
    print("It's either not raining or not cold.")

if not is_raining or not is_cold:
    print("It's either not raining or not cold.")

De Morgan's Law Example in Python

De Morgan's Law Example in Python



    



Python Function Explanation

  • What the function does:
    • Creates a function called run_example with two inputs: is_raining and is_cold.
    • Starts with an empty message called output.
  • First Check:
    • It checks if both raining and cold are not happening at the same time.
    • If that’s true, it adds “Original: It’s either not raining or not cold.” to output.
  • Second Check:
    • It checks if either it’s not raining or it’s not cold.
    • If that’s true, it adds “Simplified: It’s either not raining or not cold.” to output.
  • Final Step:
    • It returns whatever is in the output.

      DeMorgran’s Law Game

  • The game asks the player to solve logic puzzles using De Morgan’s Laws.
  • It has 3 levels, each with a different puzzle.
  • The player inputs either “True” or “False” as their answer.
  • Random truth values (True or False) are generated for A, B, X, Y, and Z.
  • Level 1: Solve not (A and B) using the law: not A or not B.
  • Level 2: Solve not (A or B) using the law: not A and not B.
  • Level 3: Solve not (X and Y or Z) using the law: (not X or not Y) and not Z.
  • The game checks if the player’s answer matches the correct answer.
  • If the player answers correctly, they move to the next level. If wrong, the game ends.
  • The game continues until the player passes all levels or gets an answer wrong.
import random
import ipywidgets as widgets
from IPython.display import display, clear_output

def random_truth_value():
    return random.choice([True, False])

def check_answer(correct_answer, player_answer):
    return correct_answer == player_answer

def play_level(expression, correct_answer):
    print(expression)
    player_answer = input("Your answer (True/False): ").strip()
    
    if player_answer not in ["True", "False"]:
        print("Invalid input! Please enter True or False.")
        return False
    
    player_answer = player_answer == "True"
    
    if check_answer(correct_answer, player_answer):
        print("Correct!\n")
        return True
    else:
        print(f"Incorrect! The correct answer was {correct_answer}. Game Over.\n")
        return False

def main():
    clear_output()
    print("Welcome to the De Morgan's Law Game!")
    
    # Level 1
    A = random_truth_value()
    B = random_truth_value()
    expression = f"Level 1: Solve this expression using De Morgan's Law: not (A or B)\nA = {A}, B = {B}"
    correct_answer = (not A) and (not B)
    
    if not play_level(expression, correct_answer):
        return
    
    # Level 2
    X = random_truth_value()
    Y = random_truth_value()
    expression = f"Level 2: Solve this expression using De Morgan's Law: not (X and Y)\nX = {X}, Y = {Y}"
    correct_answer = (not X) or (not Y)
    
    if not play_level(expression, correct_answer):
        return
    
    print("Congratulations! You passed all levels.")


play_button = widgets.Button(description="Play")


def on_play_button_clicked(b):
    main()


play_button.on_click(on_play_button_clicked)


display(play_button)

Truth Table Explanation

Explanation of the Code:

Headers: The list headers contains column names like A && B, !(A && B), etc., which represent the expressions you’re evaluating.

Values: itertools.product([True, False], repeat=2) generates all combinations of True and False for A and B, i.e., (True, True), (True, False), etc.

Logic Calculation: For each row, the following expressions are computed:

  • A && B: AND operation between A and B
  • !(A && B): Negation of the AND operation
  • !A || !B: De Morgan’s equivalent of !(A && B)
  • A || B: OR operation between A and B
  • !(A || B): Negation of the OR operation
  • !A && !B: De Morgan’s equivalent of !(A || B)
import itertools


headers = ['A', 'B', 'A AND B', 'NOT (A AND B)', 'NOT A OR NOT B', 'A OR B', 'NOT (A OR B)', 'NOT A AND NOT B']


values = list(itertools.product([True, False], repeat=2))


def print_truth_table():

    print(f"{' | '.join(headers)}")
    print("-" * 80)
    
  
    for A, B in values:
        a_and_b = A and B
        not_a_and_b = not (A and B)
        not_a_or_not_b = not A or not B
        a_or_b = A or B
        not_a_or_b = not (A or B)
        not_a_and_not_b = not A and not B
        
       
        print(f"{A:<5} | {B:<5} | {a_and_b:<9} | {not_a_and_b:<12} | {not_a_or_not_b:<13} | {a_or_b:<7} | {not_a_or_b:<12} | {not_a_and_not_b:<13}")


print_truth_table()

A | B | A && B | !(A && B) | !A || !B | A || B | !(A || B) | !A && !B
-------------------------------------------------------
1     | 1     | 1       | 0         | 0          | 1       | 0         | 0         
1     | 0     | 0       | 1         | 1          | 1       | 0         | 0         
0     | 1     | 0       | 1         | 1          | 1       | 0         | 0         
0     | 0     | 0       | 1         | 1          | 0       | 1         | 1         

Popcorn Hack #1

Check Number: Evaluates if number is less than 0. Output: Logs whether the number is negative or non-negative.

def check_number():
    try:
        number = float(input("Please enter a number: "))
        if number < 0:
            print("The number is negative.")
        else:
            print("The number is non-negative.")
    except ValueError:
        print("Invalid input! Please enter a valid number.")

check_number()

Popcorn Hack #2

Check Scores: Confirms if both scores are at least 70. Output: Prints if the student passed both subjects.

def check_scores(score1, score2):
    if score1 >= 70 and score2 >= 70:
        print("The student passed both subjects.")
    else:
        print("The student did not pass both subjects.")


score1 = float(input("Enter the first score: "))
score2 = float(input("Enter the second score: "))

check_scores(score1, score2)

Popcorn Hack #3

Check Vowel: Checks if char is in the string ‘aeiou’. Output: Prints whether the character is a vowel or not.

def check_vowel(char):
    vowels = 'aeiou'
    if char.lower() in vowels:
        print(f"The character '{char}' is a vowel.")
    else:
        print(f"The character '{char}' is not a vowel.")


char = input("Enter a character: ")


if len(char) == 1:
    check_vowel(char)
else:
    print("Please enter a single character.")

Homework

  1. Create a Truth Table
    • Develop a truth table for a given logical expression.
  2. Create a Game Using De Morgan’s Law
    • Design a simple game that uses De Morgan’s Law to simplify yes or no functions.

Summary of “3.5 Python Boolean Hacks”

De Morgan’s Law in Python

Key Concepts:

  • Negating AND: not (A and B) becomes not A or not B.
  • Negating OR: not (A or B) becomes not A and not B.

Code Applications: Simplifies conditional logic in code, e.g., checking if it’s not raining or not cold.

De Morgan’s Law Game

A game with three levels where players solve logic puzzles using De Morgan’s Laws.

  • Truth Table: Generates truth tables to evaluate logical expressions.

Python Boolean Hacks

  • Check Number: Determines if a number is negative.
  • Check Scores: Checks if both scores are 70 or above.
  • Check Vowel: Identifies if a character is a vowel.

Homework

  • Create a Truth Table: Develop a truth table for a given logical expression.
  • Design a Game Using De Morgan’s Law: Create a game that uses De Morgan’s Law to simplify yes or no functions.