Python Cool Tricks - How to use logical and arithmetic operators together
1. Connection between logical (boolean) and arithmetic operators
When boolean values (or boolean expressions within parentheses) are used in an arithmetic expression, Python converts them to integers, and the False value to 0 and the True value to 1. The reverse is also true: when integers are used in a boolean expression, Python converts them to logical constants (eg x has an integer value, and in the logical expression after the if statement, Python converts it into a logical value and examines whether it is True in the branching statement if x: pass). Based on this, it is possible to write a very short infinite loop, which does nothing useful and will never end, unless you break it with <Ctrl>+<C> or <Ctrl>+<F6>: while 1: pass.
Note: When converting integer to boolean, all values greater than 0 will be True, and the value 0 will be False!
All logical functions can be represented using basic arithmetic operations!
not
x=False, y=not(x), y is True or x=True, y=not(x), y is False.
But how are things arithmetically?
The integer variable x takes only the values 0 or 1 and it is necessary that when x is equal to 0 the value of y is 1, and when x is equal to 1 that y is 0. One solution is:
if x==1: y = 0
else: y = 1
Another solution is:
y = 1
if x: y = 0
And the best solution is:
y = 1-x
Note: The need to use the if-else statement is gone!
In case x is a logical variable and has only False or True values, the solution is:
y = True
if x: y = False
Or :
y = bool(1-(x==True))
Note: The need to use the if-else statement is gone!
But it can also be done without using a logical constant:
y = bool(1-int(x))
And it can be even shorter:
y = bool(1-(x))
The expression (x) is actually an abbreviated expression (x==True), but Python also allows without parentheses:
y = bool(1-x)
So:
def not1(x): # Logical negation
return bool(1-(x==True))
def not2(x): # Logical negation
return bool(1-x)
and
Logical operator AND implemented using basic arithmetic operators:
def round_int(x): # Rounding a real number to an integer
if x>=0: x = x + 0.499999999999999
else: x = x - 0.499999999999999
return int(x) # Converting x to an Integer (Trimming Decimals)
def and1(x, y): # Logical function AND
if x==True: x1 = 0.5 # 0.0 + 0.0 = 0.0
else: x1 = 0.0 # 0.0 + 0.5 = 0.5
if y==True: y1 = 0.5 # 0.5 + 0.0 = 0.5
else: y1 = 0.0 # 0.5 + 0.5 = 1.0
r = round_int(x1 + y1) # A real number is rounded
if r==0: b = False
else: b = True
return b
def and2(x, y): # Logical function AND
return bool(round_int((x==True)/2 + (y==True)/2))
def and3(x, y): # Logical function AND
return bool(round_int(x/2 + y/2))
Note: The need to use the if-else statement is gone!
or
Logical operator OR implemented using basic arithmetic operators:
def or1(x, y): # Logical function OR (inclusive OR)
if x==True: x1 = 0.51 # 0.0 + 0.0 = 0.0
else: x1 = 0.0 # 0.0 + 0.51 = 0.51
if y==True: y1 = 0.51 # 0.51 + 0.0 = 0.51
else: y1 = 0.0 # 0.51 + 0.51 = 1.02
r = round_int(x1 + y1) # A real number is rounded
if r==0: b = False
else: b = True
return b
def or2(x, y): # Logical function OR (inclusive OR)
return bool(round_int((x==True)/1.99 + (y==True)/1.99))
def or3(x, y): # Logical function OR (inclusive OR)
return bool(round_int(x/1.99 + y/1.99))
Note: The need to use the if-else statement is gone!
xor
Python does not have a built-in XOR operator. It is easily implemented using the logical operators NOT, AND and OR:
def xor(x, y):
return (x or y) and (not(x and y))
Logical operator XOR implemented using basic arithmetic operators:
def xor1(x, y): # Logical function exclusive OR
if x==True: x1 = 1 # abs(0 - 0) = 0
else: x1 = 0 # abs(0 - 1) = 1
if y==True: y1 = 1 # abs(1 - 0) = 1
else: y1 = 0 # abs(1 - 1) = 0
r = abs(x1 - y1)
if r==0: b = False
else: b = True
return b
def xor2(x, y): # Logical function exclusive OR
return bool(abs((x==True) - (y==True)))
def xor3(x, y): # Logical function exclusive OR
return bool(abs(x - y))
def xor4(x, y): # Logical function exclusive OR
return bool((x+y)%2)
def xor5(x, y): # Logical function exclusive OR
return bool((x-y)%2)
Note: The need to use the if-else statement is gone!
You must be asking yourself: What should I do with this?
This was all just to better understand the relationship between logical and arithmetic operators.
Now you will see on a simple example how logical and arithmetic operators can be used together. Of course, without using if-else statements!
2. Application of logical and arithmetic operators together
In the simple example that follows, my intention was not to make the best animation of the ball's movement.
The point is to see how the movement of the ball can be controlled, without using if-else statements.
Complete ball motion animation code:
import turtle as tu
DWcol = ['White', 'Pink', 'Red', 'Orange', 'Yellow', 'SandyBrown', 'Lime',
'Aqua', 'DeepSkyBlue', 'Violet'] # the color of the ball
BGcol = "black" # background color
x_min = -300 # the smallest value for x within the drawing window
y_min = -300 # the smallest value for y within the drawing window
x_max = 300 # the largest value for x within the drawing window
y_max = 300 # the largest value for y within the drawing window
# definition screen for drawing
tu.screensize(canvwidth=x_max-x_min, canvheight=y_max-y_min, bg=BGcol)
# set the coordinates of the drawing window
tu.setworldcoordinates(x_min, y_min, x_max, y_max)
def DrawBall(D, col): # draw a ball of diameter D and color col
tu.color(col) # set the draw color to col
tu.pendown() # put down the drawing pen
tu.begin_fill()
tu.circle(D) # draw a circle of diameter D with color col
tu.end_fill() # fill the circle with color col
tu.penup() # pick up the drawing pen
#tu.bgcolor(BGcol) # the background is always black
tu.hideturtle() # hide the drawing pointer
tu.tracer (100, 99) # ball speed (every 100, 99 will not be displayed)
D = 10 # diameter of the ball in pixels
PS = 50 # the thickness of the edge of the ball
T = 500 # the time the ball is displayed before being deleted in ms
tx = 11 # x-axis movement (acceleration/deceleration of the ball)
ty = 4 # y-axis movement (acceleration/deceleration of the ball)
x = 100 # x coordinate of the starting position of the ball
y = 40 # y coordinate of the starting position of the ball
dx = 1 # 1: direc. from left to right, -1: dir. from right to left
dy = 1 # 1: direc. from bottom to top, -1: dir. from top to bottom
x_min += abs(D-PS//2) # correction because the lot is drawn from below
x_max -= abs(D-PS//2) # correction because the lot is drawn from below
y_min += 0 # there is no corr. because the lot is drawn from below
y_max -= abs(D-PS//2)+D//2 # correction because the lot is drawn from below +
# correction due to the title of the turtle window
tu.pensize(PS) # set the thickness of the edge of the ball
tu.goto(x, y) # move the plot to position x,y
for i in range(10000):
DrawBall(D, DWcol[i%len(DWcol)]) # draw a ball in the drawing color
tu.delay(T) # wait T milliseconds
tu.goto(x, y) # move the plot to position x,y
DrawBall(D, BGcol) # erase the ball by drawing a ball of the backgr. color
if (x>x_max) or (x<x_min): dx = -dx # x off screen - change direction
if (y>y_max) or (y<y_min): dy = -dy # y off screen - change direction
x += dx*tx # The x coord. is increased or decr. (this determines dx) by tx
y += dy*ty # The y coord. is increased or decr. (this determines dy) by ty
tu.goto(x, y) # move the plot to position x,y
#print('x =', x, ', y =', y) # displays the current x,y coor. of the ball
Controlling the movement of the ball is done using if-else statements:
if (x>x_max) or (x<x_min): dx = -dx # x off screen - change direction
if (y>y_max) or (y<y_min): dy = -dy # y off screen - change direction
If instead of controlling the movement of the ball using if-else statements, we enter the following code:
# x off screen - change direction
dx = -(x>x_max) + dx*(dx==-1) + (x<x_min) + dx*(dx==1)
# y off screen - change direction
dy = -(y>y_max) + dy*(dy==-1) + (y<y_min) + dy*(dy==1)
This code can be even shorter:
dx += -2*dx*(x>x_max) -2*dx*(x<x_min) # x off screen - change direction
dy += -2*dy*(y>y_max) -2*dy*(y<y_min) # y off screen - change direction
Feel free to change the values of variables in the program to get various new effects!
This is a simple example, but in a situation where a large number of if-else statements are used, it is better to use logical and arithmetic operators.
You can find useful information about Python tricks (and other things) on the site: