<jupyter_start><jupyter_text>More Control Flow- [Download the lecture notes](https://philchodrow.github.io/PIC16A/content/basics/control_flow.ipynb). In "For-Loops and Comprehensions," we introduced the for-loop -- the simplest way to iterate through data. In this lecture, we'll add `while` loops for iteration, as well as `if` statements for conditional branching. 1. Iteration (repeating an operation)2. Branching (performing different operations depending on conditions)We'll move quickly through this material, since these concepts should be familiar from your experience with PIC10A -- only the syntax changes. Two important pieces of syntax: 1. The declaration of both loops and conditionals must end with a colon `:`. 2. **Whitespace matters.** The body of a loop or branching statement **must be indented**, else Python will throw a syntax error.   Iteration with While-LoopsA *while-loop* will repeat a given sequence of commands as long as a boolean (logical) condition evaluates to `True`. The first time that that condition evaluates to `False`, the loop will halt -- no more iterations will take place. The primary application of while-loops is to iterate when you are not sure how many iterations are required. Unlike for-loops, it is necessary to initialize the variable of iteration prior to beginning the loop. Make sure that the loop will indeed terminate!<jupyter_code>done = False
i    = 1

while not done:
    i   += 1
    done = i > 5

i<jupyter_output><empty_output><jupyter_text>Remember also that the full body of the loop executes *after* checking the condition. For example, consider the following attempt to find the largest power of 3 less than 10,000:<jupyter_code># largest power of 3 less than 10,000 -- failed

x = 1
while x < 1e5:
    x *= 3
x # oops!<jupyter_output><empty_output><jupyter_text>This function fails because the multiplication occurs after the condition `x < 1e5` is checked. So, instead we have to do this:<jupyter_code># largest power of 3 less than 10,000

x = 1
while 3*x < 1e5:
    x *= 3
x # ok!<jupyter_output><empty_output><jupyter_text>Branching with If-StatementsIf-statements allow you to perform different blocks of code based on logical tests. Any expression that evaluates to `True` or `False` (i.e. a boolean) can be used. Some useful examples of boolean expressions.<jupyter_code>"Janeway" in ["Kirk", "Janeway", "Picard"]
2 >= 1
# boolean and
(2 >= 1) and (2 <= 4) 
# boolean or
(2 >= 1) or (2 <= 0)<jupyter_output><empty_output><jupyter_text>Now we can try an example of if-statements.<jupyter_code>x = 1
if x < 0:
    print("x is a negative number")
elif x == 0:
    print("x is zero")
else:
    print("x is a positive number")
# ---<jupyter_output>x is a positive number<jupyter_text>Branching is often particularly powerful within loops.<jupyter_code># print odd numbers 1-9

for i in range(10):
    if i % 2 == 1:
        print(i)
# ---<jupyter_output>1
3
5
7
9<jupyter_text>`break` and `continue`Having equipped ourselves with `if` statements, we can now explore two additional constructs for use in `while` loops: `break` and `continue`. Roughly, `break` can be used to halt an entire `while` loop, while `continue` can be used to halt a single iteration and move on to the next one.     Schematic working of break and continue.Let's first try using `break` to check whether a number is a power of 3:<jupyter_code>x = 1

possible_pow = 28

while x < 1e5:
    x *= 3
    if x == possible_pow:
        print(str(possible_pow)  + " is a power of 3")
        break
# ---<jupyter_output><empty_output><jupyter_text>Suppose that we want to print out every number 1 through 10, *except for* multiples of 4. The `continue` statement will prematurely end the current iteration and begin a new one, allowing us to exclude those multiples.<jupyter_code>i = 0
while i < 10:
    i += 1
    
    # skip multiples of 4
    if i % 4 == 0:
        continue
        
    print(i)
# ---<jupyter_output>1
2
3
5
6
7
9
10
{'fraction_non_alphanumeric': 0.0858293480996728, 'fraction_numerical': 0.023156305059149257, 'mean_word_length': 4.062420382165605, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 34, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '459886', 'license': 'MIT', 'n_tokens_mistral': 1272, 'n_tokens_neox': 1184, 'n_words': 546, 'path': 'content/basics/control_flow.ipynb', 'repo_name': 'mm5110/PIC16A', 'size': '3973'}