The possible Boolean values are True
and False
. Python has three logical operators, which manipulate Boolean values: not
, and
and or
. The formal logical meaning of these was introduced in class and in our mathematical text.
It is important to note that in programming that the in a two part expression such as P and Q
, the second part Q
is only evaluated if necessary to determine the truth of the whole expression.
P
and Q
are values which are either True
or False
and n
is an integer.
Operator | Syntax | Example expression |
not
|
not P
|
not n==0 (same as n!=0 )
|
and
|
P and Q
|
n!=0 and abs(2/n)>1 (This will run fine, the second expression is only evaluated if n!=0 is true.)
|
or
|
P or Q
|
n==0 or abs(5/n)<2 (This will run fine, the second expression is only evaluated if n=0 is false.)
|
Here are some examples of running the example expressions:
n=5
print("When n is", n, "the value of not n==0 is", not n==0)
n=0
print("When n is", n, "the value of not n==0 is", not n==0)
n=3
print("When n is", n, "the value of n!=0 and abs(2/n)>1 is", n!=0 and abs(2/n)>1)
n=-1
print("When n is", n, "the value of n!=0 and abs(2/n)>1 is", n!=0 and abs(2/n)>1)
n=0
print("When n is", n, "the value of n!=0 and abs(2/n)>1 is", n!=0 and abs(2/n)>1)
n=2
print("When n is", n, "the value of n==0 or abs(5/n)<2 is", n==0 or abs(5/n)<2)
n=-12
print("When n is", n, "the value of n==0 or abs(5/n)<2 is", n==0 or abs(5/n)<2)
n=0
print("When n is", n, "the value of n==0 or abs(5/n)<2 is", n==0 or abs(5/n)<2)
Note that in the expressions for and
and or
, in the case when \(n\) is zero, the second expressions are not evaluated. You can tell they are not evaluated because evaluating these expressions results in an error such as:
n=0
abs(5/n)
The following example decides if a number is both even and positive. It either prints out that the number is both even and odd, or explains why this statement is not true.
def even_and_positive(n):
if n%2==0 and n>0:
print(n, "is both even and positive.")
return
if not n%2==0:
print(n, "is not both even and positive because it is odd.")
return
print(n, "is not both even and positive because it is not positive.")
even_and_positive(10)
even_and_positive(5)
even_and_positive(-12)
even_and_positive(-7)
Remark (Empty return statement and None
): In the definition of the function even_and_positive(n)
you see two empty return statements. These just stop evaluation of the function. They actually return the None
object which just indicates that nothing was returned. So the line "return
" is the same as the line "return None
".
Remark (Operator Precedence): You'll notice a general lack of parentheses in the expressions above. Python evaluates numerical operations and comparisons before evaluating logical operators. This is explained in the section on Operator Precedence in the Python Reference. If you have concerns about the order in which an expression is evaluated, include parenthesis to ensure things are evaluated in the correct order.
Here is a problem similar to your homework:
The exclusive or logical operation takes as input Boolean values and returns True
or False
. It returns True
if one of the two expressions is true and the other is false (in any order). It returns False
if the two truth values match. Write a function named xor
which takes as input two boolean values P
and Q
and when evaluated as xor(P,Q)
returns the value of P xor Q
.
The following would be a correct answer to the problem:
def xor(P,Q):
return (P or Q) and not (P and Q)
Suppose truth_function
is a function which takes as input two boolean values P
and Q
and returns a new Boolean value. Then we can print out a truth table for truth_function
. Here is a function which does this:
def print_truth_table(truth_function):
print(" P | Q | ", truth_function.__name__,"(P,Q)", sep="")
for P in (True, False):
for Q in (True, False):
print(str(P).ljust(5), "|", str(Q).ljust(5), "|",str(truth_function(P,Q)).ljust(5))
Remarks: This function is somewhat more advanced than what we have done yet, and I would not expect you to write this on your own yet. Let me explain some things you have not seen.
In the first print
expression, you see truth_function.__name__
. This returns the name of the function truth_function
. For example, if we pass the xor
function defined above, then truth_function.__name__
is the string "xor"
. Typically the print function separates adjacent arguments (e.g., "x=" and x above) by a space. This can be changed with the special sep argument. Above the separator was changed to an empty string (which means no separator). You can learn more about the print()
function in the Python library documentation and the Python tutorial.
The second and third lines of the print_truth_table
function, you see for
loops. For example, the line "for P in (True, False):
" repeatedly runs the indented block below twice, first with P=True
and second with P=False
. This idea will be introduced when we discuss lists in Python.
The last print
expression is inside two loops, and so will be evaluated four times with all possible values of P
and Q
. The line is essentially the same as print(P,"|","Q","|",statement(P,Q))
except for some details about spacing. The table printed in this way looks ugly because "True" has four letters while "False" has five. If x
is any python object, str(x)
returns an expression for x
as a string of text. Then, str(x).ljust(5)
pads the string with spaces on the right if necessary for the string to have length at least \(5\). So str(True).ljust(5)
produces "True "
(with one extra space) while str(False).ljust(5)
produces "False"
. You can learn more about str() and ljust().
print_truth_table(xor)
Here are some truth tables for and
and or
.
def and_function(P,Q):
return P and Q
print_truth_table(and_function)
def or_function(P,Q):
return P or Q
print_truth_table(or_function)
implies(P,Q)
that takes as input two boolean values P
and Q
and returns the truth value of the statement "P
implies Q
".
iff(P,Q)
that takes as input two boolean values P
and Q
and returns the truth value of the statement "P
iff Q
".
P
and Q
and returns a boolean value. (Examples include xor
above, as well as implies
and iff
from the problems above.)tautology(tf)
that takes as input a \(2\)-input truth function tf
and returns True
if tf
is a tautology and returns False
otherwise. (That is, the function should return True
if tf
returns True
for all boolean inputs).
logically_equivalent(tf1, tf2)
that takes as input two \(2\)-input truth functions tf1
and tf2
and returns the boolean value of the statement "The two truth functions are logically equivalent."