#!/usr/bin/env python # coding: utf-8 # # AddisCoder 2023: Week 2 # AddisCoder 2023: Week 2 # # July 25, 2023 # # Taught by Alex Krentsel. # Start with slides! # ## Quiz Problem Review # # The three most missed problems were #13, #20, and #21. Let's solve them together! # In[13]: # Question #13: What is the printed output of the following code snippets? If there is an infinite loop, write "Infinite". # In[14]: # 13a num = 0 while num < 6: if num % 2 == 0: print(num) num += 1 # In[ ]: # 13b num = 0 if num % 2 == 0: while num < 6: print(num) num += 1 # In[16]: # 13c num = 0 if num % 2 == 0: while num < 6: print(num) num += 1 # In[1]: # Question #20: Write a function `countCharacters(word)` that returns the number of times each character appears in the word. def countCharacters(word): characters = {} for char in word: if char in characters: characters[char] += 1 else: characters[char] = 1 return characters countCharacters("hello") # In[2]: # Question #21: Use a forloop to create a new list that contains the original values doubled. # Example: lst = [1, 2, 3, 4] --> [2, 4, 6, 8] def listDouble(lst): doubled = [] for num in lst: doubled.append(num * 2) return doubled listDouble([1, 2, 3, 4]) # ## Dictionaries # # Just like real-world dictionaries, these are used for _lookup_. You have some key (ex: a word) and you want to find the associated value (ex: a definition). Let's walk through [the slides](https://docs.google.com/presentation/d/1q6DfEr3GAKmFrZvWtA2mMIJcXK0bC5IfKMlmYjM_BSw/edit#slide=id.g25985ca9100_0_63) first. # In[3]: # For creating dictionaries, use curly braces: gradebook = {} print(type(gradebook)) print(gradebook) # In[4]: # We add key:value pairs to our dictionary using square brackets on the *left* of the equals sign. print(gradebook) print("Adding new key:value pair.") gradebook["alex"] = 95 print(gradebook) # In[5]: # You can get the value associated with a key by using brackets *not* to the left of an equal sign: print(gradebook["alex"]) # In[6]: # What happens if you try to lookup a key that doesn't exist in the dictionary? Error! print(gradebook) print("Daniel's score:", gradebook["daniel"]) # In[9]: # To avoid this issue, we can check if a dictionary contains something using `in` if "daniel" in gradebook: print("Daniel's score:", gradebook["daniel"]) else: print("daniel is not in the dictionary") # In[12]: # To iterate over dictionary keys, use the forloop syntax. It works for dictionaries automatically! for key in gradebook: print("name:", key, ", grade:", gradebook[key]) # In[8]: # Common pattern when building dictionaries as counters: counter_dict = {} word = "horse" if word in counter_dict: counter_dict[word] = counter_dict[word] + 1 else: counter_dict[word] = 1 print(counter_dict) # ## Function Trickiness # # We saw some common mistakes with functions on the exam and when walking around during lab. Let's clarify them here. # In[7]: # (1) Defining vs Calling Functions # Defining a function: def invert_string(s): new_string = "" for i in range(len(s) - 1, -1, -1): new_string = new_string + s[i] return new_string # Running this block _creates_ the function, but nothing actually gets run because the function hasn't been called. # In[9]: # Calling a function: print(invert_string("hello")) # Running this block actually runs the function and prints the output. # In[16]: # (2) Return vs Print # An "expression" is any statement that evaluates to a value. For example, `1 + 1` is an expression that evaluates to `2`. # Functions are also expressions. For example, `len("hello")` is an expression that evaluates to `5`. def fun_func(): return 5 # The `return` statement tells Python what value the function should evaluate to. In this case, the function evaluates to `5`. print(fun_func()) # In[18]: # Not all functions evaluate to something! You can tell because they have no `return` statement. For example: def void_func(): x = 1 + 1 # This function doesn't return anything. It just runs some code. If we try to print the output of this function, we get `None`. print(void_func()) # In[19]: # void_func() isn't very useful, but the more common case is when you want to print something inside a function. For example: def print_func(): print("hello") # This function doesn't return anything. It just prints something. If we try to print the output of this function, we get `None`. print(print_func()) # In[22]: # So, we use `print` to print things to the console, and we use `return` to return values from functions. # So often times, there's two ways to write a function if you want to show something on # the screen: one that returns a value, and one that prints a value. def return_sum(a, b): return a + b print(return_sum(1, 2)) # In[23]: def print_sum(a, b): print(a + b) print_sum(1, 2) # In[24]: # Notice: these both do the same thing in the end, but in different ways. # In[29]: # (3) function decomposition: breaking larger problems down in a collection of smaller functions # Example: write a function that takes a string and returns the number of vowels in the string. # Step 1: write a function that takes a string and returns True if the string is a vowel, False otherwise. def is_vowel(char): if char == "a" or char == "e" or char == "i" or char == "o" or char == "u": return True else: return False # Step 2: write a function that takes a string and returns the number of vowels in the string. def count_vowels(s): num_vowels = 0 for char in s: if is_vowel(char): num_vowels += 1 return num_vowels # Step 3: test your function print(count_vowels("hello")) # ### Default Parameters # In[25]: # We've learned how to specify the arguments that a function should take: def greet(name, greeting): print(greeting + " to you, " + name + "!") greet("Alex", "Hello") # In[26]: # In cases where you use the same argument value over and over, it can get annoying to type each time. greet("Daniel", "Hello") greet("Heather", "Hello") greet("Tony", "Hello") greet("Jelani", "Selam") # In[28]: # Python allows us to specify a _default value_ for an argument. # If the caller doesn't specify a value for that argument, the default value is used instead. def greet(name, greeting="Hello"): print(greeting + " to you, " + name + "!") greet("Alex") greet("Heather") greet("Tony") # If the caller specifies a value for that argument, the default value is ignored. greet("Jelani", "Selam") # In[ ]: