# Loops Week 10 --- ## Review  <!-- .element: style="height:450px" --> -- What is an algorithm? A step-by-step procedure <!-- .element: class="fragment green" --> -- What is the first index of a list? 0 <!-- .element: class="fragment green" --> -- What is wrong with this code? ```py [] my_list = 5, 8, 13 ``` Missing brackets <!-- .element: class="fragment green" --> -- What is wrong with this code? ```py [2] my_list = [5, 8, 13] print(my_list[3]) ``` No index 3 <!-- .element: class="fragment green" --> --- ## `while` Loops <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width:100px;fill:currentColor"><path d="M9,4H15V12H19.84L12,19.84L4.16,12H9V4Z" /></svg> -- I want to say "Hello!" four times ```py print("Hello!") print("Hello!") print("Hello!") print("Hello!") ``` <!-- .element: class="fragment" --> -- What about 400 times? -- ```py print_count = 0 while print_count < 4: print("Hello!") print_count += 1 ``` -- Each time through the loop is called an **iteration** ```py [3-4] print_count = 0 while print_count < 4: print("Hello!") print_count += 1 ``` <!-- .element: class="fragment" --> -- When repeating code, how do I know when to stop? A condition <!-- .element: class="fragment green" --> -- ```py [2] print_count = 0 while print_count < 4: print("Hello!") print_count += 1 ``` -- ```py [2] while True: print("Hello!") ``` Infinite loop <!-- .element: class="fragment red" --> -- ```py [] should_keep_going = True while should_keep_going: response = input("Do you quit yet?") if response.lower() == "yes": should_keep_going = False ``` -- What is wrong with this code? ```py [] print_count = 0 while print_count < 4: print("Hello!") ``` Condition never changes <!-- .element: class="fragment red" --> -- The "while" loop is the most basic Any loop can be a while loop <!-- .element: class="fragment" --> --- ## `for` Loops <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width:100px;fill:currentColor"><path d="M9,4H15V12H19.84L12,19.84L4.16,12H9V4Z" /></svg> -- Consider this loop: ```py groceries = ["apple", "banana", "coffee"] index = 0 while index < len(groceries): item = groceries[index] print(f"- {item}") ``` -- Is there a simpler way? -- ```py [2-3] groceries = ["apple", "banana", "coffee"] for item in groceries: print(f"- {item}") ``` -- The "for" loop uses a list One loop iteration for each list item <!-- .element: class="fragment" --> The condition is "when the list is done" <!-- .element: class="fragment" --> -- How many times does this loop run? ```py for _ in []: print("Hello, World!") ``` 0 <!-- .element: class="fragment green" --> -- What if I want to run a loop x times? You can use the `range()` function ```py for _ in range(10): print("Hello, World!") ``` <!-- .element: class="fragment" --> -- What does the `range()` function do? It creates a sequence of numbers <!-- .element: class="fragment" --> -- ```py numbers = range(5) for n in numbers: print(n) ``` ``` 0 1 2 3 4 ``` <!-- .element: class="fragment" --> -- Technically, range does not create a list ```py type([0, 1, 2]) # <class 'list'> type(range(3)) # <class 'range'> ``` <!-- .element: class="fragment" --> But we can treat it like one for loops! <!-- .element: class="fragment" --> -- A for loop is _syntactic sugar_ Any for loop can be a while loop! <!-- .element: class="fragment" --> -- ```py for _ in range(3): print("Hello, World!") ``` ```py i = 0 while i < 3: print("Hello, World!") i += 1 ``` <!-- .element: class="fragment" --> -- ```py students = ["Levi", "Nolan", "Tim", "Skyler"] for student in students: print(student, "is smart") ``` ```py students = ["Levi", "Nolan", "Tim", "Skyler"] i = 0 while i < len(students): print(students[i], "is smart") i += 1 ``` <!-- .element: class="fragment" --> -- ```py word = "hello" for index in range(len(word)): print(f'Letter "{word[index]}" is index {index}') ``` ```py word = "hello" index = 0 while index < len(word): print(f'Letter "{word[index]}" is index {index}') index += 1 ``` <!-- .element: class="fragment" --> -- When should you use each one? - For loops are good for lists <!-- .element: class="fragment" --> - While loops are for everything else <!-- .element: class="fragment" --> When in doubt, use "while" <!-- .element: class="fragment" --> -- This requires a while loop: ```py should_keep_going = True while should_keep_going: response = input("Do you quit yet?") if response.lower() == "yes": should_keep_going = False ``` --- ## Exercise <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width:100px;fill:currentColor"><path d="M9,4H15V12H19.84L12,19.84L4.16,12H9V4Z" /></svg> -- Create a loop that computes a factorial 3! = 3 * 2 * 1 = 6 ```py user_number = int( input("Enter a number: ") ) factorial = 1 # TODO compute factorial print("Factorial of", user_number, "is", factorial) ``` -- ```py user_number = int( input("Enter a number: ") ) factorial = 1 n = user_number while n > 1: factorial *= n n -= 1 print("Factorial of", user_number, "is", factorial) ``` Now convert to "for" loop! <!-- .element: class="fragment" --> --- ## Modules <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width:100px;fill:currentColor"><path d="M9,4H15V12H19.84L12,19.84L4.16,12H9V4Z" /></svg> -- Modules contain pre-written code we can use Modules are just other Python files <!-- .element: class="fragment" --> -- Import a module with the `import` keyword: ```py import random ``` -- Now you can use it! ```py random.random() random.randint(0, 100) random.choice(["heads", "tails"]) ``` ---  <!-- .element: style="height:600px" -->