1 05-Branches


Previous: 04-ExpressionsTypes.html

05-Branches/true.jgp

1.1 Screencasts

1.2 Reading

Extra reading 1:
* http://scipy-lectures.org/intro/language/control_flow.html
* https://automatetheboringstuff.com/2e/chapter2/
* https://books.trinket.io/pfe/03-conditional.html
* https://docs.python.org/3/tutorial/controlflow.html#if-statements
* https://python.swaroopch.com/control_flow.html
* https://www.learnpython.org/en/Conditions
* https://www.tutorialspoint.com/python3/python_decision_making.htm

1.3 Boolean algebra

1.4 Control flow

https://en.wikipedia.org/wiki/Control_flow
* Control flow (or flow of control) manipulates the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated.

1.4.1 Conditional branching

https://en.wikipedia.org/wiki/Control_flow#Choice
https://en.wikipedia.org/wiki/Conditional_(computer_programming)

1.5 if else

05-Branches/decision_making.png

1.5.1 Simple if

if expression
   statement-inside
statement-outside

1.5.1.1 if else

if expression
   statement-block1
else
    statement-block2

1.5.1.2 Nested if else

if expression
   if expression1
      statement-block1
   else
      statement-block2
else
   statement-block3

1.5.1.3 else-if ladder

The general form of else-if ladder is,

if expression 1
   statement-block1
elif expression2
   statement-block2
elif expression3
   statement-block3
else
   default-statement

1.5.1.4 General points to remember

1.5.2 Why use conditions?

With just the syntax/tools we have so far, you could program a mechanic or a physician:
05-Branches/start.gif
* Is this AI?
* Was it considered AI?
* What about now?

1.6 Conditional branching in Python

05-Branches/branching00.py
05-Branches/branching00_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
An if-else construct implements branching.
Below, if  x < 0 is true, the first branch executes,
outputting "Negative".
Else, the second branch executes,
outputting "Non-negative".

General form:
if [condexpr]:
   [substatements]
elif [condexpr]:
   [substatements]
else:
   [substatements]
"""

x: int = int(input())

if x < 0:
    print("Negative")
else:
    print("Non-negative")

++++++++++++++++
Cahoot-05.1
https://mst.instructure.com/courses/58101/quizzes/55394

05-Branches/branching01.py
05-Branches/branching01_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
elseif is optional, with any number of them being OK
else is optional, though it must be the last block
Conditional expression’s operators:
   (), ==, !=, , =, and, or, not
Precedence (high to low):
   (), not, * / % + -, < >=, == !=, and, or
"""

x: int = int(input())
y: int = int(input())
z: int = int(input())

if (y - z) < 10:
    print("Close")
if x < 10:
    print("Small")
    # Nested conditions
    if x > 8:
        print("nine")
elif x < 20:
    print("Med")
else:
    print("Large")

++++++++++++++++
Cahoot-05.2
https://mst.instructure.com/courses/58101/quizzes/55395

05-Branches/branching02.py
05-Branches/branching02_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

M: int = 5
N: int = 2
K: int = M % N

if K == 1:
    print("hello")
elif K == 2:
    print("world")
else:
    print("!")

1.7 Operators used in branching

1.7.1 Relational operators

05-Branches/image06.png
* The == operator is the “is equal” operator and != is the “is not equal” operator.
* Many times, those learning will make a mistake when trying to use the == or = operator
* They will use the = operator instead of the == operator.
* Thus, val = num will run but not compare the two values.
* It will set the value of the variable val to that of num and will return true.
* This is not the desired result.
* BE CAREFUL.

Assume variable A holds 10 and variable B holds 20:
05-Branches/image00.png

1.7.2 Logical operators in general

05-Branches/logop.jpg
05-Branches/image01.png
05-Branches/images02.png

1.7.3 Logical operators in Python3

and
or
not

How readable, thanks python!

1.7.4 Truth tables

05-Branches/image07.png 05-Branches/image08.png

05-Branches/image09.png 05-Branches/images04.png

Suppose that a=2, b=3, and c=6, then, what are the following?

( 7 == 5 )
( 5 > 4)
( 3 != 2 )
( 6 >= 6 )
( 5 < 5)
( a == 5 )
( a ∗ b >= c )
( b + 4 > a ∗ c )
( ( b=2) == a )

Not has only one operand, to its right, and inverts it, producing false if its operand is true, and true if its operand is false.
05-Branches/images03.png

What are the following?

! ( 5 == 5 )
! ( 6 <= 4 )
! true
! false

++++++++++++++++
Cahoot-05.3
https://mst.instructure.com/courses/58101/quizzes/55396

Ask: What is the maximum depth of if-nesting?
It’s 100s deep in many languages.

1.8 Examples

1.8.1 elif chains

05-Branches/branching03.py
05-Branches/branching03_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

month: int = int(input("Please enter the month as a number: "))
day: int = int(input("Please enter the day of the month as a number: "))

if month == 1:
    print("January")
elif month == 2:
    print("February")
elif month == 3:
    print("March")
elif month == 4:
    print("April")
elif month == 5:
    print("May")
elif month == 6:
    print("June")
elif month == 7:
    print("July")
elif month == 8:
    print("August")
elif month == 9:
    print("September")
elif month == 10:
    print("October")
elif month == 11:
    print("November")
else:
    print("December")

print(day)

1.8.2 Real diagnostic flowchart

05-Branches/branching04.py
05-Branches/power_chart.png
05-Branches/branching04_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

print("Help! My computer doesn't work!\n")
print("Does the computer make any sounds (fans, etc.) or show any lights? (y/n):")
choice: str = input()

if choice == "n":
    print("Is it plugged in? (y/n):")
    choice = input()
    if choice == "n":
        print(
            "Plug it in.",
            "If the problem persists,",
            "please run this program again.\n",
        )
    else:
        print('Is the switch in the "on" position? (y/n):')
        choice = input()
        if choice == "n":
            print(
                "Turn it on.",
                "If the problem persists,",
                "please run this program again.\n",
            )
        else:
            print("Does the computer have a fuse?  (y/n):")
            choice = input()
            if choice == "n":
                print("Is the outlet OK? (y/n):")
                choice = input()
                if choice == "n":
                    print(
                        "Check the outlet's circuit breaker or fuse.",
                        "Move to a new outlet, if necessary.",
                        "If the problem persists,",
                        "please run this program again.\n",
                    )
                else:
                    print("Please consult a service technician.\n")
            else:
                print(
                    "Check the fuse. Replace if necessary.",
                    "If the problem persists,",
                    "then please run this program again.\n",
                )
else:
    print("Please consult a service technician.\n")

1.8.3 Caesar extended

Last time, we did not have branches, but now we do!

1.8.3.1 Key generation (corrected bug from before)

05-Branches/branching_caesar_keygen.py
05-Branches/branching_caesar_keygen_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import random

print("Your randomly chosen Caesar cipher key is: ")
print(random.randint(1, 25))
print("\n Share securily with your communication partner, and don't tell anyone else\n")

1.8.3.2 Encryption and decryption (earlier bug fixed, missing features)

Note: Often there are MANY ways to write a correct program for the same goal.

1.8.3.2.1 Solution 1

With if statements, we now only need to have one copy of the code, rather than one program for encryption and one for decryption, as before:
05-Branches/branching_caesar_01.py
05-Branches/branching_caesar_01_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

print("You have to run this program, once for every character of your message")

key: int = int(input("\nEnter your Caesar key in numeric form (1-25): "))

mode: int = int(input("\nEnter 1 for encryption, and 0 for decryption: "))

encoded_char: int = int(
    input(
        "\nEnter Caesar encoded number corresponding to one character of your message:"
    )
)

print("\nThe translation of your character is:")

if mode == 1:
    # 26 is the symbol set size (# letters in alphabet)
    # negative mod is language dependent in behavior
    print((encoded_char + key) % 26)
else:
    print((encoded_char - key) % 26)

Ask:
* Does this work for small letters, big ones?
* Does it work for encryption and decryption?
* Does anything kind of input break it?

1.8.3.2.2 Solution 2

There was an alternative way to have accomplished this without branches/conditions, below:
Logic tricks like this are not always possible.
05-Branches/branching_caesar_02.py
05-Branches/branching_caesar_02_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

print("You have to run this program, once for every character of your message")

key: int = int(input("\nEnter your Caesar key in numeric form (1-25): "))

mode: int = int(input("\nEnter 1 for encryption, and -1 for decryption: "))

encoded_char: int = int(
    input(
        "\nEnter Caesar encoded number corresponding to one character of your message:"
    )
)

print("\nThe translation of your character is:")

# 26 is the symbol set size (# letters in alphabet)
# negative mod is language dependent in behavior
print((encoded_char + (key * mode)) % 26)

Ask:
* Does this work for small letters, big ones?
* Does it work for encryption and decryption?
* Does anything kind of input break it?
* Does this kind of math trick always let you avoid conditions/branches?

1.8.3.2.3 Solution 3

There was an alternative way to have accomplished a correct solution without modulus, below:
05-Branches/branching_caesar_03.py
05-Branches/branching_caesar_03_cfg.svg

#!/usr/bin/python3
# -*- coding: utf-8 -*-

print("You have to run this program, once for every character of your message")

key: int = int(input("\nEnter your Caesar key in numeric form (1-25): "))

mode: int = int(input("\nEnter 1 for encryption, and 0 for decryption: "))

encoded_char: int = int(
    input(
        "\nEnter Caesar encoded number corresponding to one character of your message:"
    )
)

print("\nThe translation of your character is:")

if mode == 1:
    # 26 is the symbol set size (# letters in alphabet)
    if (encoded_char + key) < 26:
        print(encoded_char + key)
    else:
        print((encoded_char + key) - 26)
else:
    # 26 is the symbol set size (# letters in alphabet)
    if 0 < (encoded_char - key):
        print(encoded_char - key)
    else:
        print((encoded_char - key) + 26)

Ask:
* Does this work for small letters, big ones?
* Does it work for encryption and decryption?
* Does anything kind of input break it?

Ask:
* Though one solution is not always better, often one can be.
* What is the best of the above three solutions here?
* How do we quantify best?
* Prettiest?
* Easiest to read?
* Easiest to understand?
* Shortest
* Fastest?
* Most computationally efficient?
* Least computationally efficient (sometimes that’s good)?

1.9 Language focus

To be stepped through in the python3-spyder IDE and/or python3-pudb debugger:
05-Branches/branching05_overview.py

1.10 Funny random point: static block depth

Next: 06-Loops.html