#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Felix Muzny 10/14/2022 DS 2000 Lecture 11 - iteration with lists of lists, lists and mutability (the final chapter of scope), functions and optional parameters, functions and functions as parameters Logistics: - Homework 5 is due *next* Friday 10/21 @ 9pm - Homework solutions -> will not be posting these online -> always happy to discuss in office hours -> will continue to bring up common mistakes in lecture - remote attendance (https://bit.ly/remote-ds2000-muzny) - how to call functions - nested loops & how does scope interact - when writing functions, gettin the docstring (function comment) to generate - using for loops to read files -> see read_data in this file -> https://course.ccs.neu.edu/ds2000/felix_lectures/earnings_lec10.py -> also these notes: https://course.ccs.neu.edu/ds2000/felix_lectures/lec7_lists_forloops.py Three ways to participate (please do one of these!) 1) via the PollEverywhere website: https://pollev.com/muzny 2) via text: text "muzny" to the number 22333 to join the session 3) via Poll Everywhere app (available for iOS or Android) Warm-up 1 - lists of lists & slicing --- Which of the following lines of code will get the first three elements from the 3rd row of a list of lists (in the variable ls)? A. ls[:3] B. ls[3:] C. ls[2][:3] <---- ls[row_index][col_index] D. ls[:3][2] E. ls[2][3] """ """ Warm-up 2 - lists of lists and loops --- What line of code should go in the marked spot to print out every item in a list of lists? """ ls = [[1, 2], [23, 24], [35, 36, 37]] # this loop doesn't use range for row in ls: # row = [1, 2] on the first iteration # this loop iterates by index for col_ind in range(len(row)): #HERE print(row[col_ind]) print() # here's an alternate version that uses # the range function in both loops # for row_ind in range(3) # range(3) -> [0, 1, 2] for row_ind in range(len(ls)): # row_ind = 0 on the first iteration for col_ind in range(len(ls[row_ind])): print(ls[row_ind][col_ind]) print() """ A. print(row[col_ind]) <--- B. print(col_ind) C. print(ls[row][col_ind]) # this uses row as an index, when it is actually a list D. print(ls[col_ind][row]) E. None of these """ # nested loops and scope # print(i) # ERROR, i not available yet for i in range(3): print("i value", i) # print(special_count) #ERROR, special_count not available yet # print(j) # ERROR, j not available yet for j in range(5): # i is accessible in all loops/conditionals # inside of the for i in range(3) loop print("j value", j) # print(special_count) # ERROR special_count = i + j # can access i here print(special_count) # python will let us, but can make confusing code # so be aware of this print(special_count) print() # python will let us, but can make confusing code # so be aware of this print(i) print(j) print() """ Academic Integrity --- This is not a fun topic, help me avoid having to address it any further. Homeworks: - done individually You all are beginning programmers. I know very well that it can often *feel* like there is only one correct solution to a problem. In reality, we expect to see a great deal of variation in programs that are submitted (variation beyond "surface level" traits like variable names) When we see two programs that are the same, this is equivalent to seeing two essays submitted in an English course that are word-for-word copies of one another. Check in with your DS 2001 section for policies about collaboration. """ """ List function — convert to ints --- Write a function, convert_int, that takes a list as a parameter and returns a new list with all the values in the original list converted to an integer. Assume that all values in the original list can be converted to ints. """ # This is a pure function (see below) def convert_int(ls): """ Converts all values in given list to integers and returns as a new list. Parameters ---------- ls : list list of values to be converted. Returns ------- new_ls : list corresponding list of ints. """ new_ls = [] for value in ls: new_ls.append(int(value)) return new_ls # This is a mutator function def convert_int_mutate(ls): """ Converts all values in given list to integers. Parameters ---------- ls : list list of values to be converted. Returns ------- None """ for i in range(len(ls)): ls[i] = int(ls[i]) print("convert int mutate test") ls = ["1", "3", "6"] print(ls) # notice no return saved convert_int_mutate(ls) print(ls) print() # print("convert int test") # as_ints = convert_int(ls) # print(as_ints) # as_ints2 = convert_int(ls2) # print(as_ints2) # print(convert_int([])) """ Lists and mutability (scope: the final chapter!) --- So far: when we've passed parameters into functions, we've passed *copies* of their *values*. Example: """ def increment(x): # x here only lives in increment x = x + 1 print("int in increment", x) # 8 return x def increment_first(ls): # print(main_ls) # ERROR, main_ls is not accessible ls[0] += 1 print("ls in increment_first", ls) def main(): print("pass by copy vs reference examples") # x only lives in main() x = 7 # increment(7) ans = increment(x) print("int in main", x) # 7 print() # now, we'll explore lists # when a list is passed to a function, we are not # passing a copy main_ls = [0] print("before increment_first", main_ls) increment_first(main_ls) print("ls in main", main_ls) print() main() """ Vocab --- pass-by-value: ints, floats, strings, booleans--make a copy, pass in that copy pass-by-reference: lists--tell the function where the list is stored in memory """ """ List functions - pure vs. mutator --- There are two kinds of list functions: pure: does NOT change the orignal list sorted_ls = sorted(ls) mutator: DOES change the orignal list ls.sort() """ print("sorted() example") ls2 = [43.0, -34.7, 17.0, 100.1] print(ls2) ls2_sorted = sorted(ls2) print(ls2) # unchanged print(ls2_sorted) print() print("ls.sort() example") ls2 = [43.0, -34.7, 17.0, 100.1] print(ls2) ls2.sort() print(ls2) # sorted order print() """ Optional parameters --- examples with python built-in functions (you've already used these a lot with matplotlib!) """ import matplotlib.pyplot as plt xs = list(range(0, 10)) ys = [1, 5, 6, 4, 2, -4, 3, 2, 5, 10] # color is an optional parameter plt.plot(xs, ys, "o", color="red") plt.show() """ Writing our own function with an optional parameter: General syntax: def function_name(positional, parameters, first, then = optional) write a function, generate_list, that generates a list of 10 random integers. Use optional parameters to define the lower and upper range of integers to be generated. """ import random # this example has no positinal parameters def generate_list(lower = 1, upper = 9): """ Generate a list of length 10 filled with random ints from a lower bound to an upper bound (1 - 9 by default). Parameters ---------- lower : int, optional Inclusive lower bound of integers to generate. The default is 1. upper : int, optional Inclusive upper bound of integers to generate. The default is 9. Returns ------- new_ls : list Generated list of ints. """ new_ls = [] for i in range(10): new_ls.append(random.randint(lower, upper)) return new_ls print("Generate list examples") print(generate_list()) print(generate_list(lower = -1000)) print(generate_list(upper = 1000)) print() """ Passing functions as parameters --- Using our function that we wrote from before (convert_int), write a new version that will convert everything from a list into a string. """ def convert_mutate(ls, cast = int): """ Converts all values in given list according to the given function. Changes to ints by default. Mutates the given list. Parameters ---------- ls : list list of values to be converted. cast : function, optional Function to be applied to every element in the list. The default is int. Returns ------- None. """ for i in range(len(ls)): ls[i] = cast(ls[i]) print("convert_mutate examples") ls3 = [43.2, 35.4] convert_mutate(ls3) print(ls3) convert_mutate(ls3, cast = str) print(ls3) convert_mutate(ls3, cast = float) print(ls3) # if we have time (we didn't, we'll start here on Tuesday) """ if __name__ == "__main__": --- Writing our very own modules! """ """ Next time: - dictionaries - writing our own modules """