4  Boolean Variables and Conditional Execution

Jupyter Notebook

4.1 Boolean Variables

We have learned about three types of variables in Python: ints, floats, and strings. Another variable type is a boolean, which can be one of two values: True or False. You can assign a boolean variable in the same way that you assign numbers or string, using =

myBool = True

True must be capitalized so don’t try true or it won’t be a boolean

myBool = true

4.1.1 Boolean Logic

Often you will want to check to see if some condition is true. For example, maybe you want to know if the radius of a certain satellite’s orbit is bigger or smaller than Mercury’s orbit. To perform this check, there are several boolean operators that will return True or False. Take note of the boolean operators shown in the cell below along with the comments added to explain what they do.

r1 = 3.5e8
r2 = 2.7e6

r1 > r2 # Is r1 greater than r2
r1 < r2 # Is r1 less than r2
r1 >= r2 # Is r1 greater than or equal to r2
r1 <= r2 # Is r1 less than or equal to r2
r1 != r2 # Is r1 not equal to r2
r1 == r2 # Is r1 equal to r2
False

A word of caution about comparing Python floats using == is in order here. Python floats are stored as a 53-digit, base-2 binary number(that’s a mouthful). If you’re interested in what that means, we can talk more. If you’re not that interested, just know that when you define a float in Python, the number that is stored in the computer is not exactly the number that you think it is. This can cause problems when you are comparing two numbers that you think should be equal but actually aren’t equal in the computer.1 The code below illustrates this problem.

a = 0.1
b = 3 * a
c = 0.3
print(b==c)  # Are they the same number?  You would think they would
             # be right?
print(" {:.5f} ".format(b))     # They sure look the same.
print(" {:.5f} ".format(c))     # They sure look the same.
print(" {:.45f} ".format(b))  #b--- out to 45 decimal places
print(" {:.45f} ".format(c))  #c--- out to 45 decimal places
False
 0.30000 
 0.30000 
 0.300000000000000044408920985006261616945266724 
 0.299999999999999988897769753748434595763683319 

The first two print statements display the value of b and c to five decimal places. The second two print statements force Python to display the value of b and c out to 45 decimal places. Notice that the true value of b is not exactly equal to 0.3. This is why the statement print(b==c) returns False. The take home message here is that comparing two floats to see if they are equal is always a bad idea. A better way to check to see if two floats are equal (or close enough that we can say they are equal) is to check if the absolute value of their difference is very small, like this:

a = 0.1
b = 3 * a
c = 0.3
print(abs(b - c) < 1e-10)
True

4.1.2 Compound Comparisons (Logical Operators)

Comparisons like those shown above can be chained together to make compound comparisons using the and, or, and not operators.

Operator Description
and Tests for both being True
or Tests for either being True
not Tests for False

The and operator requires both inputs to be True in order to return True while the or operator requires only one input to be True in order to evaluate at True. The not operator is different in that it only takes a single input value and returns True if and only if the input is False. It is a test for False.

Truth tables are a good way to visualize the output from compound comparisons.

p q p and q p or q
True True True True
True False False True
False True False True
False False False False

As a simple example, suppose you know the density (\(\rho\)) and speed of light (c) for two materials and you’d like to know if both values are bigger for material 1 or material 2.

To Do:

  1. Predict the output for each compound comparison given below. Add your guess as a comment.
  2. Now add appropriately-placed print statements to check your guesses.
  3. Modify your guess as needed and discuss any questions with a neighbor.
c1 = 2.5e8
c2 = 2.48e8
ρ1 = 450
ρ2 = 580

c1 > c2 and ρ1 > ρ2
c1 < c2 and ρ1 < ρ2
c1 > c2 and ρ1 < ρ2
c1 < c2 and ρ1 > ρ2

c1 > c2 and not ρ1 > ρ2
c1 < c2 and not ρ1 < ρ2

c1 > c2 or ρ1 > ρ2
c1 < c2 or ρ1 < ρ2
True

4.1.3 Tests for Inclusion

You can check for inclusion using the Python in operator. This provides an easy way to see if a character (or word) is present in a long string. Let’s say you have a long string that contains the names of Jupyter’s moons (there are 79 of them!!) and you want to see if a certain moon is included in the list. The in statement let’s us quickly test to see if it is in the list. (see example below)

jupytermoons = "Metis,Adrastea,Amalthea,Thebe,Io,Europa,Ganymede,Callisto,Themisto,Leda,Himalia,Lysithea,Elara,Dia,Carpo,Euporie,Thelxinoe,Euanthe,Helike,Orthosie,Iocaste,Praxidike,Harpalyke,Mneme,Hermippe,Thyone,Ananke,Herse,Aitne,Kale,Taygete,Chaldene,Erinome,Aoede,Kallichore,Kalyke,Carme,Callirrhoe,Eurydome,Pasithee,Kore,Cyllene,Eukelade,Pasiphae,Hegemone,Arche,Isonoe,Sinope,Sponde,Autonoe,Megaclite"

"Cyllene" in jupytermoons
True

4.2 Conditions

Conditions allow the user to specify if and when certain lines or blocks of code are executed. Specifically, when a condition is true, the block of indented code directly below it will run.

4.2.1 if statement

The if statement is used to control when a block of code runs. Its usage is shown below ending in a colon and the block of code below indented with four spaces. Using the Tab key will also produce four spaces.

jupytermoons = "Metis,Adrastea,Amalthea,Thebe,Io,Europa,Ganymede,Callisto,Themisto,Leda,Himalia,Lysithea,Elara,Dia,Carpo,Euporie,Thelxinoe,Euanthe,Helike,Orthosie,Iocaste,Praxidike,Harpalyke,Mneme,Hermippe,Thyone,Ananke,Herse,Aitne,Kale,Taygete,Chaldene,Erinome,Aoede,Kallichore,Kalyke,Carme,Callirrhoe,Eurydome,Pasithee,Kore,Cyllene,Eukelade,Pasiphae,Hegemone,Arche,Isonoe,Sinope,Sponde,Autonoe,Megaclite"

if "Cyllene" in jupytermoons:
    found = True
    print("Found Cyllene in the list")
    
if "Matis" in jupytermoons:
    found = True
    print("Found Matis in the list")
Found Cyllene in the list

If the boolean statement after if is true, the indented code below it will run. If the statement is false, Python just skips the indented lines below. The end of an if code block is determined by the indentation; to signal the end of the block, simply step back the indentation.

4.2.2 else Statement

Sometimes there will be an alternate block of code that you want to run if the if statement evaluates to False. The else statement is used to specify this block of code, as shown below.

jupytermoons = "Metis,Adrastea,Amalthea,Thebe,Io,Europa,Ganymede,Callisto,Themisto,Leda,Himalia,Lysithea,Elara,Dia,Carpo,Euporie,Thelxinoe,Euanthe,Helike,Orthosie,Iocaste,Praxidike,Harpalyke,Mneme,Hermippe,Thyone,Ananke,Herse,Aitne,Kale,Taygete,Chaldene,Erinome,Aoede,Kallichore,Kalyke,Carme,Callirrhoe,Eurydome,Pasithee,Kore,Cyllene,Eukelade,Pasiphae,Hegemone,Arche,Isonoe,Sinope,Sponde,Autonoe,Megaclite"

if "Cyllene" in jupytermoons:
    found = True
    print("Found Cyllene in the string")
else:
    found = False
    print("Did not find Cyllene in the string")

    
if "Matis" in jupytermoons:
    found = True
    print("Found Matis in the string")
else:
    found = False
    print("Did not find Matis in the string")
Found Cyllene in the string
Did not find Matis in the string

Notice that the else statement must be followed by a colon and the block of code to be executed is indented, just as in the if block.

There is an additional statement called the elif statement, short for “else if”, which is used to add extra conditions below the initial if statement. The block of code below the elif statement only runs if the if statement is false and the elif statement is true. An example is given below.

jupytermoons = "Metis,Adrastea,Amalthea,Thebe,Io,Europa,Ganymede,Callisto,Themisto,Leda,Himalia,Lysithea,Elara,Dia,Carpo,Euporie,Thelxinoe,Euanthe,Helike,Orthosie,Iocaste,Praxidike,Harpalyke,Mneme,Hermippe,Thyone,Ananke,Herse,Aitne,Kale,Taygete,Chaldene,Erinome,Aoede,Kallichore,Kalyke,Carme,Callirrhoe,Eurydome,Pasithee,Kore,Cyllene,Eukelade,Pasiphae,Hegemone,Arche,Isonoe,Sinope,Sponde,Autonoe,Megaclite"

if "Matis" in jupytermoons:
    foundMatis = True
    print("Found Matis in the string")
elif "Cyllene" in jupytermoons:
    foundCyllene = True
    print("Found Cyllene in the string.")
else:
    foundCyl = False
    foundMatis = False
    print("Did not find Cyllene or Matis in the string")
Found Cyllene in the string.

It is worth noting that else statements are not required. If you leave the else statement off and the if statement is false, no code block will execute.

4.3 Flash Cards

  1. How do you check to see if one value is greater than or equal to another one?
  2. Which boolean operators should never be used to compare floats?
  3. What is the correct way to determine if two floats are equal to each other (or very close)?
  4. When will the statement p and q evaluate to True?
  5. When will the statement p or q evaluate to True?
  6. How do you check to see if a certain sequence of characters is present in a string?
  7. When constructing an if block how does Python know what code to execute if the condition is True?
  8. Recite Helaman 5:12.

4.4 Exercises

  1. (Escape Velocity) The escape velocity is the speed needed for an object to completely escape the gravitational pull of a planet. The expression for escape velocity is \[ v_\text{escape} = \sqrt{2 G M_p \over r}\] where \(G = 6.67 \times 10^{-11}\), \(M_p\) is the mass of the planet you are trying to escape from, and \(r\) is the radius of the planet.

    1. Construct an if-else code block that checks to see if a guessed speed is bigger or smaller than the escape velocity of Jupiter. The code block should print an appropriate message about the guessed velocity. Jupiter has a mass of \(M = 1.90 \times 10^{27}\) kg and a radius of \(r = 6.99 \times 10^7\) meters.
    2. Modify your guess until both branches of your if-else trigger.
    3. Repeat for Earth. Earth has a mass of \(M = 5.98 \times 10^{24}\) kg and a radius of \(r = 6.37 \times 10^6\) meters.

    ::: {.cell execution_count=11} {.python .cell-code} G = 6.67e-11 :::

  2. (Thermoelectrics) A thermoelectric is a material that converts thermal energy into electrical energy and much research is devoted to finding new materials that exhibit this behavior. Good thermoelectrics tend to be materials with high electrical conducitivity (\(\sigma > 7 \times 10^5~\Omega^{-1} \text{m}^{-1}\) ) and low thermal conductivity (\(\kappa< 2.0\) W/ m K ). Write an if-else code block that checks to see if a material’s electrical conductivity is above the threshold and its thermal conductivity is below the threshold. Then choose some values for the conductivities and test your if-else block.

    ::: {.cell execution_count=12} ``` {.python .cell-code} sigma = 0 # Electrical Conductivity kappa = 0 # Thermal Conductivity

    ``` :::

  3. Alloys are often represented by a string containing the elements in the alloy and the relative number of atoms for each element. For example, “Cu2Au” (Copper-2-Gold) means that the alloy is made of copper and gold and there are two copper atoms for every gold atom. Write some python code that calculates the total number of atoms in an alloy. The code should include a print statement to display the result. Then check your code on the alloys in the table below. You can assume that all elements have two-character symbols even though that isn’t true; we won’t consider any one-character symbols in this problem.

Hints:

  1. The possible lengths for the strings are 4 (one atom per element), 5 (one atom for one element and more for the other), or 6 (more than one atom for both elements).
  2. My code for this problem was about 15 lines long and it required a nested if-else block (an if-else inside of an if block).
  3. You may find the isdigit() function to be helpful. Do you remember how to use it and what it does?
Alloy
“Cr3Si” “Al2Cu” “NbPd3” “CaIn2” “Al3Zr4”
alloy = "CaIn2"  
  1. The quadratic equation has two solutions and they can be positive, negative, or complex. Often the complex and/or negative solutions are not relavant/meaningful. Write an if/elif/else block of code that checks what type of solutions will result and only displays the real, positive solution(s) if they exist. If there is no positive solution, the code should display a message indicating such. Then check your code with the values given below. As a reminder, here is the quadratic equation: \[ x = {- b \pm \sqrt{b^2 - 4 a c} \over 2a} \]

a = 2, b = 3, c = 8 (no real solutions)

a = 1, b = -3, c = 2 (two positive solutions)

a = 1, b = -3, c = -2 (one positive solution and one negative solution)

# Python code here.
  1. (Triangle Classification) There is a simple criteria to determine whether a triangle can be formed from a set of specified side lengths. The criteria states that the sum of any two sides must be larger than the third side. This criteria must be satisified for all possible combinations of two sides if the triangle is to be valid. If the triangle is valid, the angles can be found by first using the law of cosines to find the first two angles \[c^2 = a^2 + b^2 - 2 a b \cos(C)\] and then choosing the third angle so that the sum of the three angles add up to \(180^\circ\).

    1. Write some code that checks to see if a valid triangle can be formed from the given side lengths.
    2. If a triangle can be formed, use the law of cosines to calculate the triangle’s angles. Print the angles in degrees. Check your code for several choices of side lengths to verify that it is working.
    3. All valid triangles are classified according to the largest angle present (acute, obtuse, and right) and also according to their side lengths (scalene - no sides equal, isoscelese - two sides equal and equilateral - all sides equal). Modify your code to determine the classification of a triangle (i.e. obtuse scalene) and print that classification to screen.
from numpy import arccos,pi

#a = # Side length 1
#b = # Side length 1
#c = # Side length 1

  1. There is a library called Decimal that will fix a lot of these problems.↩︎