CSE 8A stepik

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

or

True if either or both expressions evaluate to True , False otherwise >>> True or True True >>> True or False True >>> False or True True >>> False or False False

or

True if either or both expressions evaluate to True , False otherwise >>> True or True True >>> True or False True >>> False or True true >>> False or False False

> >= < <=

True if inequality holds False otherwise

> >= < <=

True if inequality holds, False otherwise

==

True if the values are equal, False otherwise

!=

True if the values are not equal, False otherwise

bracket lookup expression

string[integer], index can only be integer values, not floats.

Suppose we run the following code. What will be printed? Note: the end = " " at the end of each print statement simply keeps the output on one line, separated by a single space, rather than printing each on a new line. def f(s): print(s, end = ' ') s = "I'm sure if I study hard, I'll do well!" print(s, end = ' ') s = "I am getting prepared for the final!" f(s) print(s)

I am getting prepared for the final! I'm sure if I study hard, I'll do well! I am getting prepared for the final!

in operator: to check if a particular key is in a dictionary

"TAs" in class_dict evaluates to True . Similarly, "vuvuzelas" in class_dict evaluates to False. Note that the in operator on a dictionary will only check for keys, not values. So, 10 in class_dict

operators

+, -, < , and ==

NOT FLOATING

10 +2//3 10

lst.insert(pos, elem) Inserts the specified element (elem) at the specified position (pos)

>>> l = [1,2,3,4,5] >>> l.insert(3,0) >>> l [1, 2, 3, 0, 4, 5] The insert method in the above example inserted the element 0 at the index 3 (zero-based indexing) and thus the list now contains the element 0 at the index 3.

pop lst.pop(pos) Removes and returns the element at the specified position. The pos parameter is optional. If it is not specified then the default value of pos is -1 and it removes the last element

>>> l = [1,2,3,4,5] >>> l.pop(3) 4 >>> l [1, 2, 3, 5] >>> l.pop() 5 >>> l [1, 2, 3]

What's a reference?

A reference is a name that refers to a value's specific location in computer's memory. Variables do not store list values directly; they store references to lists

dictionary of colors

Below is a colors dictionary that uses the names of the colors, which are strings, as keys that are mapped to their RGB tuple values. colors = {'red': (255, 0, 0), 'green': (0, 255, 0), 'blue': (0, 0, 255), 'yellow': (255, 255, 0), 'violet': (238, 130, 238), 'orange': (255, 165, 0), 'indigo': (75, 0, 130)} If we wanted to create a rainbow stripe, we can do so by using the color dictionary we created. This is much more easier to visualize than if we saw a 2D list of RGB tuples. rainbow = [[colors['red'], colors['orange'], colors['yellow'], colors['green'], colors['blue'], colors['indigo'], colors['violet']]]

functions and built-in

Python and many other programming languages give us lots of functionality through functions. Python defines a few functions for working with numbers that are built-in.

references and objects lst1 = [1, 2, 3] lst2 = lst1 lst3 = [1, 2, 3] lst1[1] = 1 lst2[0] += 1 print(lst1, end = ", ") print(lst3, end = ", ") lst4 = lst2 lst4[0] += 1 print(lst4, end = ", ") print(lst1, end = ", ") print(id(lst4) == id(lst1), end = ", ") print(id(lst2) == id(lst3)) Note: the end = ", " at the end of each print statement simply keeps the output on one line, separated by commas, rather than printing each on a new line.

[2, 1, 3], [1, 2, 3], [3, 1, 3], [3, 1, 3], True, False

Data processing

def find_numbers(reference): result = [] for person in directory: # loops through every dictionary if person['first_name'] == reference: result.append(person['phone_number']) return result Our function is now completely written, and we can use this function as follows. We can see that there are two phone numbers for 'Jennifer' because there are people with the first name Jennifer: Jennifer Wilson and Jennifer Davis. >>> find_numbers('Jennifer') [8585343213, 8585342230] >>> find_numbers('John') [2092284400] >>> find_numbers('Michael') []

Naming our parameters and arguments the same names

def foobar(num1,num2): return num1 + num2 num1 = 1 num2 = 100 print(foobar(num1,num2)) our argument num1 (which used to be named x) is passed into our parameter num1. Similarly, our argument num2 (which used to be named y) is passed into our parameter num2. Note that the argument num1 is not the same variable as the parameter num1

continue

for ... if a <b: continue a +=1 if a<b, skips a+=1 and starts from "for" loop again.

The range() function can also be called with two or even three arguments as follows:

for i in range(3, 6): print(i) Will print: 3 4 5

for loop for the keys of the dictionary

for key in class_dict: print(key) The above code would output: instructors TAs tutors students

floating to int

int() Ex: >>>int(2.0) 2 int(3.5) 3

not

inverts the boolean value that follows >>> not True False >>> not False True

function call

is written as: . The function's name (ex: max) . followed by arguments separated by commas in parentheses (in this case, (4, 5))

while True: name = input('Please enter your name: ') print('You entered ' + name) print('Program ended')

it will keeps printing the two lines of body. As the condition is set as True and it never turns into False, the while loop asks you to enter your name and shows it indefinitely until you hit control + C to manually exit the program. Note that you cannot see the last line of the code print('Program ended') executed, because the while loop never ends.

lists as values

keys must be immutable. While this is true, there is no such requirement on values! We can use mutable objects like lists as values,

[[P(0,0), P(0,1), P(0,2), P(0,3), P(0,4)], [P(1,0), P(1,1), P(1,2), P(1,3), P(1,4)], [P(2,0), P(2,1), P(2,2), P(2,3), P(2,4)]] We can then replace all P(coordinate) with the color at that particular pixel. Recall from the previous steps that the tuple, (255, 255, 255), is white and (0,0,0) is black. Our resulting 2D list of tuples would be the following. [[(0,0,0), (255,255,255), (0,0,0), (255,255,255), (0,0,0)], [(255,255,255), (0,0,0), (255,255,255), (0,0,0), (255,255,255)], [(0,0,0), (255,255,255), (0,0,0), (255,255,255), (0,0,0)]] Since the pixel at coordinate (0,0) is black, we replaced P(0,0) with (0,0,0). Moving on, we replaced P(0,1) to (255,255,255) because the pixel at coordinate (0,1) is white.

like a chess piece for 3x5

Which of the following datatypes are mutable?

list and dict, immutable are int, floats, booleans, strings, and tuples. Immutable are harder to change.

Write a program that reads a string from input and prints "Hello, <name>!" where <name> is filled in with the string that was read in.

name = input() print("Hello, " + name + "!")

lst = [13, 12, 17, 19, 33, 0] sum_of_elements = 0 for elem in lst: sum_of_elements += elem print(sum_of_elements)

output: 94

for i in range(3, 10, 3): print(i)

print: 3 6 9

and

rue if both expressions evaluate to True , False otherwise

while True: <Statement>

this will makes the loop run infinitely, hence infinite loop. <Statements> will be executed repeatedly until the users manually terminates the program or your program crashes.

one- by- one error

use index <= len(my_list) instead of index < len(my_list) We would have gone through the loop body one more time than we should have if we used <= because we would have been off by one from the correct number of times we should have executed the loop.

>>> max(4,5) 5

we could describe or document the function max by saying max(n,m)

Order of mulitple operators(*,+, etc)

1. () 2. **: exponentiation 3. &, /, //, %: multiplication, division, integer division, modules 4. +. - Those in the same row have the same precedence and are evaluated from left to right Ex: >>>5 + 7 % 2 *3 8 the operators % and * will be evaluated first since they have a higher precedence when compared to the operator +. As the two operators % and * are the same precedence level, they will be evaluated from left to right. That is, % will be evaluated first and then * will be evaluated. The way the expression will be evaluated is shown below.

Which among the following would throw an error when executed on a python shell?

1. 5 * "20" 2020202020 2. "Hey " +"there!" "Heythere!" 3. "Hello" * 3 HelloHelloHello 4. "10" * "2" Answer: 4

1. def red_filter(img): 2. for row in range(len(img)): 3. for col in range(len(img[0])): 4. pix = img[row][col] 5. img[row][col] = (pix[0],0,0) 6. return img

1. The above function takes in one input parameter, img which is the image represented as a 2D list. 2. The outer for loop will go through each index of img which represents the rows of the image. 3. The inner for loop will go through each index of img[0], which represents the columns of the image. 4. We assign the tuple pix to the RGB component, img[row][col], that we want to access. 5. We assign new pixel values as follows: the Red component is set to be the same value as in the original image and the Green and Blue components are set to be zero. 6. The function returns the modified image as a 2D list.

def make_breakfast(): fry_eggs() toast_bread() def fry_eggs(): print("Sizzle sizzle") return def toast_bread(): wait_for_toaster() return def wait_for_toaster(): print("Ding ding!") return make_breakfast() What happens when we call make_breakfast()

1.make_breakfast() is called. make_breakfast() gets added to the call stack, and we begin executing make_breakfast(). Call Stack: -make_breakfast() 2. fry_eggs() is called. fry_eggs() gets added to the the top of the call stack, and we begin executing fry_eggs(). make_breakfast() is paused until fry_eggs() is complete. Call Stack: -fry_eggs() -make_breakfast() 3. fry_eggs() prints and returns. fry_eggs() prints "Sizzle sizzle" and returns. fry_eggs() is removed from the call stack, and the new topmost call, make_breakfast(), resumes execution from where it was paused. Call Stack: -make_breakfast() 4. toast_bread() is called. toast_bread() gets added to the the top of the call stack, and we begin executing it. make_breakfast() is paused until toast_bread() is complete. Call Stack: -toast_bread() -make_breakfast() 5. wait_for_toaster() is called. wait_for_toaster() gets added to the the top of the call stack, and we begin executing it. toast_bread() is paused until wait_for_toaster() is complete. Call Stack: -wait_for_toaster() -toast_bread() -make_breakfast() 6.wait_for_toaster() prints and returns. wait_for_toaster() prints "Ding ding!" and returns. wait_for_toaster() is removed from the call stack, and the new topmost call, toast_bread(), resumes execution from where it was paused. Call Stack: -toast_bread() -make_breakfast() 7.toast_bread()returns. toast_bread() returns. toast_bread() is removed from the call stack, and the new topmost call, make_breakfast(), resumes execution from where it was paused. Call Stack: -make_breakfast() 8.make_breakfast()returns. make_breakfast() returns. The call stack is now empty, and the program has completed running. Call Stack: (empty)

The following function has been written to remove the duplicate strings from a given list of strings and return a new list of strings all converted to lower case. def remove_duplicates(lst): new_lst = [] for elem in lst: if elem not in new_lst: new_lst.append(elem.lower()) return new_lst

>>> lst = ['hELLo', 'no', 'yes', 'maybe', 'no', 'yes'] Then the new_lst returned will be free of duplicates and in lower case as follows: ['hello', 'no', 'yes', 'maybe'] Now, we want to modify the code so that it can match duplicates irrespective of whether they are in upper case or lower case. So, if we had an input as follows: >>> lst = ['hELLo', 'no', 'yes', 'maybe', 'NO', 'yEs'] Then we want to modify the above function so that the new_lst returned for the above lst is also free of duplicates even though 'no', 'yes' and 'NO'. 'yEs' are in different cases. ['hello', 'no', 'yes', 'maybe']

str(v): takes an integer and turns it into a string

>>> str(123) '123'

num = 1 while num < 0: # line A num += 1 # line B How many times is line A executed and how many times is line B executed?

A: 1 B: 0

upper_bound = 10 num = 2 while num < upper_bound: # line A num *= 2 # line B

A: 4 B: 3

We return None temporarily from this function to validate that we have created our function correctly and we named our parameters well

Aka scaffolding Ex: def find_element(word, word_list): return None student = 'Chris' student_list = ['Alice', 'Chris', 'Hannah', 'Jack']

Syntactic sugar

Doing something that isn't strictly necessary that makes the program easier, for programmers to read and use. empty_2D = [[0,1], [0,1], [0,1]]

1st task of finding mode: recording the number of occurrences.

Each key will be a number in the list and each value will be the count of that number. nums = [5, 5, 6, 4, 7, 8, 5, 6] # A list of numbers for which we want to find the mode counts = {} # Create an empty dictionary for num in nums: # loop through each number in nums if num in counts: # Check if num is a key in counts counts[num] += 1 # increment the count of nums by 1 else: counts[num] = 1 # Set the count of num to 1 print(counts)

Key value pair

Every element in a dictionary is a key-value pair and a dictionary contains a collection of these key-value pairs. A key-value pair is some key with its associated value.

not

Inverts the boolean value that follows >>> not True False >>> not False True

use // instead of /

It removes anything after the decimal place >>> 5 // 2 2 >>> 5 // 2.0 2.0 >>> 5.0 // 2 2.0 >>> 5.0 // 2.0 2.0

def local(): print('The value of x is:',x) x = 10 local() Here is the output: The value of x is: 10

Since x is a global variable, local function can access x and prints out its value. (Here, local function does not have a local variable named x, so it automatically looks for a global variable x.)

List concatenation and list replication

Similar to Strings, we can perform concatenation of two different lists using the + operator in order to create a combined list. And if we want to replicate the list a specific number of times then we can use the * operator along with an integer that represents how many times you want the list to be replicated.

len(s)

Takes a string s and returns the number of characters in the string

def find_element(word, word_list): print('word:', word) print('word_list:', word_list) return None student = 'Chris' student_list = ['Alice', 'Chris', 'Hannah', 'Jack'] print('function returns:', find_element(student, student_list)) Here is the output of the code: word: Chris word_list: ['Alice', 'Chris', 'Hannah', 'Jack'] function returns: None

The current version of our code prints the given student name and the list that were passed as parameters/arguments correctly.

Negative indexes

The integer value -1 refers to the last index in a string, the value -2 refers to the second-to-last index in a string, and so on.

split str.split(sep)

The split method returns a list of strings appearing between instances of sep in the string (It uses sep as the delimiter or separator). >>>"1:2:3".split(":") ['1', '2', '3'] >>> "apple banana orange".split(" ") ['apple', 'banana', 'orange'] >>> "1 2 3 4 5".split(" ") ['1', '2', '3', '4', '5']

def assign_x(num): x = num x = 10 assign_ x(8) print('The value of x is:', x)

The value of x is: 8 x is not 10 as we supposed. The value of x hasn't been changed although print function was called after assign_x(8). This is because x in assign_x function was treated as a local variable, which exists only in the local scope of assign_x function

pop()

This method removes the key-value pair from the dictionary and returns its value. The input parameter to the method should be the key present in the dictionary. Let's delete the two newly added key-value pairs which give the number of head tutors and the number of sections for this class from the above dictionary. We need to provide the keys 'head_tutors' and 'sections' one after the other to delete them from the dictionary. >>> class_dict {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600, 'head_tutors': 3, 'sections': 4} >>>class_dict.pop('head_tutors') 3 >>> class_dict {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600, 'sections': 4} >>>class_dict.pop('sections') 4 >>> class_dict {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600}

Creating 2D lists, and using for loops on 2D lists

To create a 2D list, we simply create a list as normal, then insert more lists as elements in the first list.

deleting key-value pairs

To delete the 'head tutors': 3 key-value pair we just added, we can run the line del class_dict["head tutors"]. Then, calling print(class_dict) will display this: {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600}

for loops with range()

When we want to iterate through a range of values, we take the help of the function range().

Some functions take multiple arguments. For example, the range() function. When we make a call like range(-10,10), we are using two arguments, the first of which specifies a starting integer, and the second of which specifies the stopping integer. Arguments are separated by a ,(comma).

You may also recall that range() can take a third argument which specifies the step. For example, to get every even number between 5 and 0 in decreasing order, we might call range(5,0,-1)

list_2D = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] for i in range(len(list_2D)): for j in range(len(list_2D[i])): list_2D[i][j] += 1 print(list_2D)

[[2, 3, 4, 5], [6, 7, 8, 9], [10, 11, 12, 13]]

key uniqueness

all keys in a dictionary must be unique.

The last index of a string

always length of string -1, or use index -1 >>> course = "CSE 8A!" >>>course[len(course)-1] '!' >>> course[-1] '!'

Write a function called is_less_than_10 that takes an integer and returns a boolean value, True if the integer is less than 10, otherwise False (see the sample inputs for some examples). You can pick everything about the parameter name and how you write the body of the function, but it must be called is_less_than_10.

def is_less_than_10(a): if(a < 10): return(True) else: return(False)

int to floating

float(4) 4.0

for loops with lists

for x in [5, 2, 3, 1]: print(x) will print: 5 2 3 1

Slicing

integer a : b a is the starting index (inclusive) and b is the ending index (exclusive) >>> "hello world"[0:5] 'hello'

1.5 In this code challenge, the input is two strings that are expected to be strings of digits. They will be stored in the variables numstr1 and numstr2 as strings. Your task is to define a variable called sum_of_ints that has the sum of the numbers represented by those digits.

sum_of_ints = int(numstr1) + int(numstr2) Because numstr 1 and numstr2 are already defined in the question

Incremental coding

t is important that you start writing from a short code snippet, add a few lines at each step and keep your code working every time you modify your code, instead of writing an entire code at once and then testing it all at once

We can avoid KeyError like above by utilizing the get method in order to get the value returned according to the specified key. For any valid index i, the command directory[i].get(key) returns the requested value that corresponds to key as follows. >>> directory[4].get('first_name') 'John' >>> directory[5].get('last_name') 'Miller' >>> directory[6].get('phone_number') 8585342230 >>> directory[7].get('state') 'GA'

If the command is used with a key that does not exist, then it returns None. >>> print(directory[0].get('zip_code')) None

Here is the code to adjust brightness of an image. diff = 50 for r in range(len(img)): for c in range(len(img[r])): pixel = img[r][c] pixel = (pixel[0] + diff, pixel[1] + diff, pixel[2] + diff) pixel = (min(pixel[0], 255), min(pixel[1], 255), min(pixel[2], 255)) img[r][c] = pixel

If the variable img is now given as the following 2D list, img = [[(10,123,71), (203,253,1), (232,50,156)]] what will be the result after running the code above? [[(60,173,121), (253,255,51), (255,100,206)]]

Color is represented with the RGB model (Red, Green, Blue model) . We represent each of these colors with a number between 0-255. Zero means the color is completely "off" or not present and 255 means the color is completely "on" or present in its full intensity

If we wanted to represent the color red, we would use (255, 0, 0) because it turns red completely on and turns off all green and blue. We would do the same if we wanted green (0, 255, 0) or blue (0, 0, 255). The color (255, 255, 255) represents white and (0,0,0) represents black.

import random random_num = random.randint(1, 10) print(random_num)

Notice that the first statement is import random. Since we provided the bounds 1 and 10 to random.randint(), random_num will be any number between 1 to 10.(both inclusive)

Methods Which of the following methods are string methods?

lower() find() index() join() split() islower()

Library

when working with the random library, we used a statement at the top of our program, which was import random. This statement tells Python to allow you to use any functions inside the random library.

iterative development

when you develop the program, even though it may meet the basic functionality, there is a scope for refining the code written to improve it like when you add if cases if length of list = 0 when lst[0] **2

For loop

when you want to iterate (i.e., repeat) over a block of code a specific number of times. It iterates over a sequence, also known as an iterable value or iterable object.

if <condition>: <body>

where <body> is only evaluated if <condition> is True, otherwise the program continues running and evaluating the code following the if statement.

break

while i in range(7): print(n) if n== 5: break n+=1 will print 0 1 2 3 4 6

user input validation

while loops that in the process of reading some user input, checking that it meets some criteria, and if not, repeating the process until valid input is provided by the user.

img = [[(0,0,0), (255,255,255)], [(255,0,0), (0,0,255)], [(0,255,0), (100,100,100)] [(0,0,0), (50,50,100)]]

width = 2, height = 4

def local(): x = 10 local() print('The value of x is:',x) the result has error as follows. NameError: name 'x' is not defined

This is because x defined in the local scope of local function cannot be used in the global scope.

and

True if both expressions evaluate to True , False otherwise >>> True and True True >>> True and False False >>> False and True False >>> False and False False

How might we go about printing, say, the 3rd student's grade on the 4th exam?

We can do: temp = grades_2D[2] print(temp[3]) This will print out 80 Or we can use grades_2D[2][3] to retrieve the item at index 3 in the list at index 2 in our list of lists, grades_2D

Tuples

We can represent a color with a new type of data called a tuple. A tuple is an immutable collection of objects: immutable meaning that it cannot be modified once it is created. You can imagine tuples to be like immutable lists. In Python, a tuple is represented similarly to a list except with round brackets or parenthesis () rather than square brackets []. red = (255,0,0) Similar to lists, we can access values in a tuple from indexing. To get the first value in red, we can index the 0th index which will print out 255. Note that indexing here is the same as lists with the square brackets []. red = (255,0,0) print(red[0])

Updating Key-Value Pairs

We can update an existing pair with the same syntax as adding a pair, using dictionary[key] = value. For example, after changing the value associated with key 'instructors' , if we want to change the value associated with the key 'TAs' to 5, we can run the line class_dict['TAs'] = 5. Then, calling print(class_dict) would display: {'instructors': 7, 'TAs': 5, 'tutors': 35, 'students': 600}

Instead of num1 = ... num2 = ... num3 = ... num4 = ... answer1 = num1 * num1 + num2 * num2 answer2 = num3 * num3 + num4 * num4

We can use: def sum_of_squares(n1, n2): return n1 * n1 + n2 * n2 sum_of_squares is the function name n1 and n2 are the parameters or argument names of the function return n1 * n1 + n2 * n2 is the body of the function In addition, return and def are examples of keywords. def tells Python that this line(and potentially the next few lines) will describe a function return tells Python to evaluate the expression after it and make that be the result of the current function call It's also required that all the lines that are part of the function body be indented (in this case by 2 spaces). If there's more than 1 line, they must be indented the same amount. >>> sum_of_squares(4, 5)41>>> sum_of_squares(1, 2)5

>>> our_image[0][0][2] = 255 Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> our_image[0][0][2] = 255 TypeError: 'tuple' object does not support item assignment

We can't mutate an element of a tuple because tuples are immutable. But we CAN reassign a pixel with a new tuple. our_image[0][0] = (0,0,225)

A local variable only exists during a function call

We learned that local variables that had been created by a function call are forgotten when the function returns. If you call the same function again, the local variables in this call will not remember the values stored in them from the last function call. Let's think about the following example.

let us modify the above function so that the red filter is applied to only the specified region. We will call the new function custom_red_filter

We need the function to take in three more parameters as inputs: top_left, height and width We need to modify the range inputs of the outer for loop to go over only the specified region. The range function's starting point from where we need to iterate would be the row index specified by the top_left tuple which is given by top_left[0] . The iteration should stop once we reach the specified height so the range function's ending point would be top_left[0] + height. We need to modify the range inputs of the inner for loop to go over only the specified region. The range function's starting point from where we need to iterate would be the column index specified by the top_left tuple which is given by top_left[1] . The iteration should stop once we reach the specified width so the range function's ending point would be top_left[1] + width. defcustom_red_filter(img, top_left, height, width): for row in range(top_left[0], top_left[0]+height): for col in range(top_left[1], top_left[1]+width): pix = img[row][col] img[row][col] = (pix[0],0,0) return img

my_list = [1, 6, -8, 2, 11] contains_negative = False # whether we've found a negative number index = 0 # index to use to iterate through my_list # if we haven't found a negative number yet and still # haven't reached the end of my_list, check the next element while not contains_negative and index < len(my_list): if my_list[index] < 0: contains_negative = True index += 1

We use the index variable to keep track of the current index in my_list that we're going to check, and we use contains_negative to store whether or not we have found a negative number in my_list. The loop body checks whether or not the element at my_list[index] is negative or not, and updates contains_negative accordingly. Then, it increments index so in the next (potential) iteration of the loop, the next index of my_list will be checked The loop continues iterating until the loop condition is False, which happens when either contains_negative is True or index >= the length of my_list This loop will keep iterating until contains_negative is updated to be True when -8 at index 2 is determined to be negative. Once contains_negative changes to True, index is then incremented and we check the loop condition again. The condition will evaluate to False because not contains_negative evaluates to False, and so we exit the loop.

Fill in the blanks given the code snippet below. print_left_half should print the left half of the columns in img. Please provide your answer for <fill_me_in> without any spaces. def print_left_half(img): for row in range(len(img)): for col in range(<fill_me_in>): print(img[row][col])

fill_me_in = len(img[row])//2

Fill in the blanks given the code snippet below. Please provide your answer for <fill_me_in_1> and <fill_me_in_2> without any spaces. colors = ['black', 'white', 'brown'] animals = ['dog', 'cat'] for elem1 in <fill_me_in_1>: for elem2 in <fill_me_in_2>: print(elem1 + " " + elem2) The above code snippet should print the following. black dog black cat white dog white cat brown dog brown cat

fill_me_in_1 = colors fill_me_in_2 = animals

To evaluate sum_of_squares(4, 5), Python:

evaluates the body of the sum_of_squares function, using the values of the arguments (4 and 5) for the parameter names (n1 and n2), when the expression after the return has a final value, that value is the value of the whole function call sum_of_squares(4, 5) -> return 4 * 4 + 5 * 5 -> return 16 + 25 -> return 41 -> 41

Add a new declaration for a variable named is_enough_time that stores a boolean value (True or False) determining if number_of_work_hours is less than or equal to number_of_paid_hours. At the end of your program, it should print is_enough_time. (The code for printing this is already provided)

number_of_work_hours = int(input()) number_of_paid_hours = int(input()) # add the declaration of is_enough_time here is_enough_time = (number_of_work_hours <= number_of_paid_hours) print(is_enough_time)

Your task is to return a tuple with the 3 integers in the order of red, green, and blue.

# Complete your function def create_pixel(red, green, blue): return(red, green, blue) Input 255 0 0 output: (255. 0, 0)

Q1. Print the details of the student with the student_id = 'A16790513'

# Using the given key directly print(student_data['A16790513']) # Using the get method print(student_data.get('A16790513')) Since student_data is a dictionary we can access the contents by providing the key directly within square brackets or by using the get method of dictionaries. Both the above statements will print the same details as given below: {'first_name': 'Regina', 'last_name': 'Sanford', 'pa': 88, 'rq': 90, 'lab': 80, 'midterm': 93, 'final': 95}

Q2. Print the marks obtained by the student with the student_id = 'A16393543' in the reading quiz

# Using the given keys directly print(student_data['A16393543']['rq']) # The above is same as doing: # student_details_dict = student_data['A16393543'] # rq_grade = student_details_dict['rq'] # print(rq_grade) # Successively using the get method print(student_data.get('A16393543').get('rq')) # The above is same as doing: # student_details_dict = student_data.get('A16393543') # rq_grade = student_details_dict.get('rq') # print(rq_grade)

has 2 words, print the length of the longer word

# define longer_length here if len(str1)>len(str2): longer_length = len(str1) else: longer_length = len(str2)

"What is the call stack right now?" is printed in func_E() if we start by calling func_A()? def func_A(): func_D() func_B() return def func_B(): return def func_C(): func_B() func_E() return def func_D(): func_C() return def func_E(): print("What is the call stack right now?") return

- functions in the call stack, with the most recently executed on top - "-----------------------" - functions not in the call stack, in any order e c d a ---- b

tuples as keys

. For instance, if we wanted to map some latitude and longitude coordinates to a city, we can map some tuple with the format, (latitude, longitude), as a key to a string city. Notice that the type of keys are tuples and the values are strings. cities = {(32.7157, 117.1611): 'San Diego', (37.7749, 122.4194): 'San Francisco', (40.7128, 74.006): 'New York', (30.2672, 97.7431): 'Austin'}

choose all that are correct about tuples

. Values in tuples can be indexed using square brackets. . values in tuples are immutable .Tuples are created using round brackets.

Choose all that are correct about images and colors.

. We represent images as 2D lists of tuples. . An image is a grid of pixels. . We use tuples to represent color.

in and not in operator

>>> "a" in "apple" True >>> 'b' in 'apple' False

num = 10 while True: num = num - 1 if num == 2: break print(num)

2

for x in [5, 2, 3, 1]: print(x)

5 2 3 1

a while loop with a break statement in if: while True: <Statement(s) #1> if <Break Condition>: break <Statement(s) #2>

<Break Condition>: any boolean expression that represents either True or False. <Statement(s) #1> and <Statement(s) #2> will be implemented repeatedly until <Break Condition> becomes satisfied at some point. Once <Break Condition> is met, the while loop is stopped without executing <Statement(s) #2> Step 1. Check whether the exit condition of the while loop is True, which is always the case for infinite loops. Continue to Step 2. Step 2. Execute <Statement(s) #1>. Step 3. Check if <Break Condition> is True. If so, end the while loop and skip to Step 6. Otherwise, continue to Step 4. Step 4. Execute <Statements #2>. Step 5. Go to Step 1. Step 6. Exit the loop.

for <variable> in <sequence>: <body of the for loop>

<sequence> is an iterable object (e.g., list, string) <variable> is a variable name of our choosing. the variable will be set to each value of the sequence one by one in order, and the loop body will run for each one. We call this assignment of the variable and evaluation of the body an iteration of the loop.

Python does not allow us to add strings and numbers together, only pairs of numbers or pairs of strings:

>>> "abc" + 123 Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: can only concatenate str (not "int") to str >>> 123 + "abc" Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for +: 'int' and 'str'

The != operator will evaluate to True if the two strings are different and False if the two strings are the same.

>>> "apple" != "apple" False >>> "apple" != "banana" True

two strings only equal only if all characters in the two strings are equal including their case (lower or upper case.)

>>> "apple" == "Apple" False >>>"banana" == "BANANA" False

In python, we can compare strings using the == and != operators. Both of these operators can be used to compare two strings and will evaluate to a Boolean. The == operator will evaluate to True if the two strings are the same and False if they are different.

>>> "apple" == "apple" True >>> "apple" == "banana" False

slicing doesn't cause an out of bounds error because slicing doesn't look for the character in the ending index

>>> "hello world"[6:11] 'world'

concatenating or appending strings

>>> "this is a " + "sentence"' this is a sentence'

Similarly, you cannot use the string replication operator with both the operands as strings.

>>> 'CSE' * '8A' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't multiply sequence by non-int of type 'str'

not in operator is the opposite to the in operator. Notice that the results are the opposite from in. Since the character 'a' is in "apple", it evaluated to False. Since "b" is not in 'apple' it evaluated to True.

>>> 'a' not in "apple "False >>> "b" not in 'apple' True

This is true for integers, except in the case of using the / operator for division, this will always return a floating point number so that your answer will not lose precision, otherwise an operation such as 5/2 would evaluate to 2.

>>> 5 + 5 10 >>> 5 - 5 0 >>> 5 * 5 25 >>> 5 / 5 1.0 >>> 5 / 2 2.5

If you are calculating a numerical value and only using the data type floating-point, your answer will also be a floating-point number. If you are using both integers and floating-points numbers, the result will be of the data type floating-point.

>>> 5 + 5.0 10.0 >>> 5 - 5.0 0.0 >>> 5 * 5.0 25.0 >>> 5 / 5.0 1.0

index out of bounds

>>> course = "CSE 8A!" >>>course[7] Traceback (most recent call last): File "<pyshell#5>", line 1, in <module>course[7] IndexError: string index out of range

since the date type of the entire directory is a list, we can use the append method to add a dictionary about info of a person.

>>> directory.append({'first_name': 'Maria', 'last_name': 'Garcia', 'phone_number': 8058938000, 'state': 'NV'}) We can confirm that the directory is updated as follows. >>> directory [{'first_name': 'James', 'last_name': 'Smith', 'phone_number': 5106423175, 'state': 'CA'}, {'first_name': 'Jennifer', 'last_name': 'Wilson', 'phone_number': 8585343213, 'state': 'OR'}, {'first_name': 'Robert', 'last_name': 'Jones', 'phone_number': 9498245011, 'state': 'NY'}, {'first_name': 'Mary', 'last_name': 'Willaims', 'phone_number': 3108254321, 'state': 'TX'}, {'first_name': 'John', 'last_name': 'Brown', 'phone_number': 2092284400, 'state': 'CA'}, {'first_name': 'Patricia', 'last_name': 'Miller', 'phone_number': 9518271012, 'state': 'FL'}, {'first_name': 'Jennifer', 'last_name': 'Davis', 'phone_number': 8585342230, 'state': 'CA'}, {'first_name': 'Linda', 'last_name': 'Johnson', 'phone_number': 4153537800, 'state': 'GA'}, {'first_name': 'Maria', 'last_name': 'Garcia', 'phone_number': 8058938000, 'state': 'NV'}]

let's try accessing a specific key-value pair. Since directory[i] is a dictionary for any valid index i, we are able to access each item in the dictionary by adding brackets with a key inside as follows.

>>> directory[0]['first_name'] 'James' >>> directory[1]['last_name'] 'Wilson' >>> directory[2]['phone_number'] 9498245011 >>> directory[3]['state'] 'TX' directory[i][key], where i is a valid index among 0,1,...,7 or -1,-2,...,-8 and key is chosen among 'first_name', 'last_name', 'phone_number', and 'state'. However, using an inadequate key leads to KeyError as seen in the following example. >>> directory[0]['zip_code'] Traceback (most recent call last): File "<pyshell#19>", line 1, in <module> directory[0]['zip_code'] KeyError: 'zip_code'

we can slice multiple dictionaries

>>> directory[2:5] [{'first_name': 'Robert', 'last_name': 'Jones', 'phone_number': 9498245011, 'state': 'NY'}, {'first_name': 'Mary', 'last_name': 'Willaims', 'phone_number': 3108254321, 'state': 'TX'}, {'first_name': 'John', 'last_name': 'Brown', 'phone_number': 2092284400, 'state': 'CA'}]

directory[i] can extract the dictionary at the index i as long as i is a valid index. Using an index out of range will result in IndexError as seen in the following example.

>>> directory[8] Traceback (most recent call last): File "<pyshell#18>", line 1, in <module> directory[8] IndexError: list index out of range

lst.append(elem) Adds the specified element (elem) to the end of the list

>>> l = [1, 2, 3, 4, 5] >>> l.append(0) >>> l [1, 2, 3, 4, 5, 0]

lst.index(elem) Returns the position of the first occurrence of the specified element (elem).

>>> l = [1,2,3,4,5,3,3] >>> l.index(3) 2

reverse lst.reverse() Reverses the order of the elements in the list.

>>> l = [4,7,2,0,9] >>> l.reverse() >>> l [9, 0, 2, 7, 4]

len()

>>> len("hello") 5 >>> s1 = 'cse 8a!' >>> len(s1) 7 >>> len('') 0

a method that gives the count of the string given as a parameter in the string s:

>>> s.count("l") 2 >>> s.count("h") 1

len() works on list too

>>> some_numbers = [46, 12, 3, 9] >>>len(some_numbers) 4 >>>some_primes = [2, 3, 5, 7, 11, 13, 17, 19] >>>len(some_primes) 8 Lists can be empty, in which case len will report that the length is 0: >>> len([]) 0

in and not in

>>> wages = [40.25, 51.5, 35.4, 42.34] >>> 35.4 in wages True >>> 38 in wages False >>> 38 not in wages True

boolean values can be stored in variables just like strings and numbers

>>> x = 10 >>>is_greater_than_10 = (x > 10) >>>is_greater_than_10 False >>> w = 22 >>>is_equal_to_22 = (w == 22) >>>is_equal_to_22 True >>> name = "Jose" >>>form_submission_name = "Joe" >>>is_same_person = (name == form_submission_name) >>>is_same_person False

we can write it as comma-separated expressions in between square brackets []. Note that the values in a list are allowed to be expressions (just like function arguments or operands in an arithmetic/logical expression):

>>> x = 9 >>> [x, x + 3, 7][9, 12, 7]

strings are a datatype for storing text and can be created by writing some characters in between single or double quotes:

>>>"CSE8A"'CSE8A' >>>'CSE8A''CSE8A'

int(s): Takes a string s made up of numeric characters and produces an integer. Reports an error if s is not a string made up of digits.

>>>int("123")1 23 >>> int("this is just text") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'this is just text'

More examples of range()

>>>list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> list(range(0, 30, 5)) [0, 5, 10, 15, 20, 25] >>> list(range(0, 10, 3)) [0, 3, 6, 9] >>> list(range(0, -10, -1)) [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] >>>list(range(0)) [] >>> list(range(1, 0)) []

Formatting words

>>>number_of_tutors = 36 >>>number_of_tas = 9 >>>number_of_staff = number_of_tas + number_of_tutors >>>number_of_staff 45

integer a: prints from a(inclusive) until the end

>>>shopping_list[1:] ['eggs', 'bread', 'apples', 'bananas']

: integer a print from the start of the lisit to a (exclusive)

>>>shopping_list[:-1] ['milk', 'eggs', 'bread', 'apples']

The bracket lookup expression, a new kind of expression, takes in a number for the index of an element to look up.

>>>some_numbers = [46, 12, 3, 9] >>>some_numbers[0] 46 >>>some_numbers[1] 12 >>>some_numbers[2] 3

replicating strings

A string can be replicated multiple times using the * operator. >>> 'ha' * 10' hahahahahahahahahaha'

def mystery(lst): for i in range(2): for j in range(3): print(lst[i][j]) Select all correct options from the list

An error will occur if lst has less than 2 rows and 3 columns. The function will only print the values in lst within the first two rows and first 3 columns.

python floating-point number vs integers

An integer is a type of data that does not have a decimal point. A floating-point number is a data type that is used to represent non-whole numbers. Ex: 1 is an integer, 1.0 is a floating-point number

Difference between an argumant and parameter

Arguments exist outside the function call, but inside, parameters are used. This isn't always true, since parameter and argument are relative to context.

>>> our_image [[(240, 240, 0), (200, 200, 0), (240, 240, 0), (200, 200, 0)], [(160, 240, 0), (120, 200, 0), (160, 240, 0), (120, 200, 0)], [(240, 240, 0), (200, 200, 0), (240, 240, 0), (200, 200, 0)], [(160, 240, 0), (120, 200, 0), (160, 240, 0), (120, 200, 0)]] To [[(240, 240, 0), (200, 200, 0), (240, 240, 0), (200, 200, 0)], [(160, 240, 0), (120, 0, 0), (160, 0, 0), (120, 200, 0)], [(240, 240, 0), (200, 0, 0), (240, 0, 0), (200, 200, 0)], [(160, 240, 0), (120, 200, 0), (160, 240, 0), (120, 200, 0)]]

Basically makes the center of 2x2 red, but retain the colors of others. a tuple called top_left which specifies the row index followed by column index (in zero based indexing) of the top left corner of the region where the red filter needs to be applied an integer height that specifies the height of the region where the red filter needs to be applied an integer width that specifies the width of the region where the red filter needs to be applied. For example, in the above figure, the value of top_left would be (1,1) since the region starts from row index 1 and column index 1 as per zero based indexing, the value of height would be 2 and the value of width would be 2 since the region spans two pixels in height and in width.

To create a dictionary, we use curly braces {} and provide some key-value pair(s) separated by commas. Each key-value pair is created in a dictionary using this syntax key:value.

Below we have created a dictionary and assigned it to the variable class_dict . This dictionary contains the number of people in this class by their role. class_dict = {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600} we have 4 key-value pairs: 'instructors': 2, 'TAs': 10, 'tutors': 35, and 'students': 600

num = int(input("Please enter a number between 1 and 10: ")) # get input, convert to int while num < 1 or num > 10: # if num is not between 1 and 10 num = int(input("Please enter a number between 1 and 10: ")) # ask again and update num # once we get here, it means that num now has a valid input value!

Case 1: User enters a valid number between 1 and 10 on the first tryFirst, let's imagine that when the first line is run, the user enters the number 4. What will happen? The while loop condition will be checked: num < 1 or num > 10 ---> 4 < 1 or 4 > 10 ---> False or False ---> False. The expression evaluates to False, so we never enter the loop body, and just move on with whatever code comes after the loop. This is the behavior we would expect since the user did indeed meet the criterion of providing a number between 1 and 10. Case 2: User enters an invalid number a couple times before giving a valid number Imagine the user first enters the number 77. The while loop condition will evaluate to True since 77 is greater than 10 Next, we enter the while loop body and ask the user to provide us with new input. Imagine the user now gives us the number -13. (Notice that we're storing the input in the same variable that we're using in the condition. If we instead stored the new input in a new variable, then num would never change, and we would never exit the loop!). Now we return to the loop condition. -13 is less than 1, so we enter the loop again and ask the user for input again. Imagine this time, they provide the number 9. We return to the loop condition again, which evaluates to False (the user provided valid input), so we exit the loop

another kind of date beyond numbers, strings, and booleans that come up often in programming is the collections of data. A way of represent collections of date is with lists.

Ex: >>>some_numbers = [46, 12, 3, 9] >>>some_numbers [46, 12, 3, 9]

lst = [1, 2, 3, 4] for n in lst: factorial = 1 for j in range(1, n + 1): factorial *= j print('Factorial of the element at index ' + str(n) + ' is: ' + str(factorial))

Factorial of the element at index 1 is: 1 Factorial of the element at index 2 is: 2 Factorial of the element at index 3 is: 6 Factorial of the element at index 4 is: 24

reduce brightness diff = 70 for r in range(len(img)): for c in range(len(img[r])): pixel = img[r][c] pixel = (pixel[0] - diff, pixel[1] - diff, pixel[2] - diff) img[r][c] = pixel

For each pixel, the code subtracts R, G, B components all by diff. However, the code above is not completed yet. What is the flaw of this code? The R, G, B components of a pixel can be negative

when we iterate over a list, such as lst = ['a','b','c'] using a loop such as for element in lst , we iterate over each individual element of the list. When we work with 2D lists, this works exactly the same way, except that each element is a list!

For example list_2D = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for lst in list_2D: print(lst) Will print: [1, 2, 3] [4, 5, 6] [7, 8, 9]

update keys values

For example, assume that we would like to update the phone number of the dictionary at index 1. Then, the following ways update the phone number. >>> directory[1]['phone_number'] = 8585343213 >>> directory[1].update({'phone_number': 8585343213})

Some functions can even be called with no arguments.

For example, calling print() with no arguments (nothing between the parenthesis) will result in a new line being printed and nothing else. We can create our own function that requires no arguments quite easily. For example, here is a function that requires no arguments and simply returns 1. def return_one(): return 1

text

In Python (and many other programming languages) we can create text data by writing some characters in between single or double quotes: >>>"CSE8A"'CSE8A' >>>'CSE8A''CSE8A' We call these strings and they are a datatype for storing text. So we've seen two types of data so far: integers and strings.

Many functions have optional arguments, which have a default value if not specified. We don't have the knowledge yet to write our own, but be aware that they exist.

In the case of range(), if the step isn't specified, it will default to 1.

A variable CAN'T be both local and global, even if a variable of the same name appeared in each other's scope.

In the example above, when x=10 is implemented, x is a global variable. However, when assign_x(8) is called, a new local variable named x is created and assigned with num. Python has its own way to tell apart the global x and the local x. After assign_x(8) is returned, the data of the local variable x is removed. When the last line with print function is called, x is the global one, which is why our result showed that the value of x is 10.

arguments, return value, function call, a use of a function

In the example, we'd call 4 and 5 the arguments of max, and the produced value 5 the return value of that function call. The syntax max(4, 5) is a function call or a use of a function. A function call is written as:

total_sum = 0 for i in range(5): total_sum += i # same as total_sum = total_sum + i

In the first iteration, i is equal to 0. After the body of the loop is evaluated, total_sum has a value of 0. In the second iteration, i is equal to 1. After the body of the loop is evaluated, total_sum has a value of 1. In the third iteration, i is equal to 2. After the body of the loop is evaluated, total_sum has a value of 3. In the fourth iteration, i is equal to 3. After the body of the loop is evaluated, total_sum has a value of 6. In the fifth iteration, i is equal to 4. After the body of the loop is evaluated, total_sum has a value of 10. There are no more values to iterate over in the sequence range(5), so the loop is done being evaluated. The resulting value of total_sum is 10.

Terminal

In the terminal, enter python, then enter a number like 4 after ">>>" Example: >>>4 4 >>> 4 * 8 - 230 >>> 4 * (8 - 2)24 We can nest the parentheses and expressions as much as we like, and Python will calculate the answer for us: >>> 4 * (8 - 2) + 3 * (99 / (2 + 1)) 123.0

num1 = 5 num2 = 50 print(foobar(num2,num1))

In this case, which is even harder to look at, the function call still works exactly the same as above and in the previous step. It is more important than ever to keep arguments and parameters separate, however. This time, our argument num2 is passed into our parameter num1, and our argument num1 is passed into our parameter num2.

The above for loop will print the following when executed: Number 0 Number 1 Number 2 Number 3 Number 4

In this example, range(5) results in five iterations through the code in the body of the loop, with x being set to 0, then 1, then 2, then3, and then 4. The end point in a range is never part of the generated sequence. In this example, range(5) generates a sequence with values 0, 1, 2, 3, and 4. The end point (i.e., 5) is not part of the generated sequence.

for x in range(5): print("Number " + str(x))

In this example, range(5) results in five iterations through the code in the body of the loop, with x being set to 0, then 1, then 2, then3, and then 4. The end point in a range is never part of the generated sequence. In this example, range(5) generates a sequence with values 0, 1, 2, 3, and 4. The end point (i.e., 5) is not part of the generated sequence.

Two References Pointing to Two Separate Objects

In this example, we have created two lists, list1 and list2. Since the two lists are created separately, list1 and list2 contain separate references to two different lists. Although the values in the list are the same, their memory addresses are different. list1 = [1, 2, 3] list2 = [1, 2, 3] list1[0] = 5 print("list1 =", list1) print("list2 =", list2) This shows that list1 and list2 contain references to separate objects.

>>> s = "hello!" >>> s.upper() 'HELLO!'

In this example, we say that upper is a method, and the syntax s.upper() is a method call or use of a method. As the name suggests, it converts the string stored in s to upper case.

values()

It returns a collection of values in the dictionary, and accordingly, using a for loop with the values() method enables to handle every value in the dictionary. class_dict = {'instructors': 2, 'TAs':10, 'tutors':35, 'students': 600} for num in class_dict.values(): print(num) Here is the output. 2 10 35 600

There's a related method called join that does the opposite of splitting: str.join(lst)

It takes a list of strings and returns a string made by concatenating the elements of lst with this string in between. >>>":".join(["1","2","3"]) '1:2:3' >>> " ".join(["apple", "banana", "orange"]) 'apple banana orange'

How do we add the sum of a 2D list, similar to 1D list

Keep in mind, i iterates over the rows of this 2D list, while j iterates over the columns. Of course, we can also think of this as i iterates over the lists inside the list of lists, while j iterates over the individual elements of each inner list. Notice that these nested loops will iterate over every possible combination of i and j

Key immmutability

Keys need not be strings, but they should be some immutable datatype. This means keys can be integers, strings, or even tuples, but not lists. Keep in mind though, values can be anything (including lists and other mutable datatypes).

update()

Let's add two more key-value pairs which gives the number of head tutors and the number of sections for this class to this dictionary. We can use the update() method to add the key-value pair as follows. As you can see below, we have used another dictionary containing the two key-value pairs as the input parameter for the update() method. >>>new_entries_dict = {'head_tutors': 3, 'sections': 4} >>>class_dict.update(new_entries_dict) >>> class_dict {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600, 'head_tutors': 3, 'sections': 4} Alternatively, you can also use a list of two-value tuples as the input parameter to the update() method. >>>new_entries_list = [('head_tutors', 3), ('sections', 4)] >>>class_dict.update(new_entries_list) >>> class_dict {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600, 'head_tutors': 3, 'sections': 4}

For example, suppose we have an email address, which is [email protected]. For this email address, notaperson is the username and is specific to the owner of the account. ucsd.edu is the domain name and is shared by all people with ucsd.edu email addresses. This organization lends itself well to dictionaries, especially when you consider that usernames don't have to be unique! Just because there is [email protected] doesn't mean that [email protected] doesn't exist for example. The reason this lends itself well to dictionaries is that there will likely be many usernames associated with each domain name.

Let's create a dictionary using domain names as keys and a list of usernames as values. emails = {"ucsd.edu" : ["annie","joseph","savitha"], "gmail.com" : ["ben10","annie","dio"], "aol.com" : ["joseph", "hotmail", "coda"]} Notice that "annie" and "joseph" are usernames that are associated with different domain names. So, [email protected] and [email protected] both exist.

Characteristics of local/global variables

Local and global scopes have different characteristics. Your code in the global scope cannot access any local variable. Actually, a local variable can be used only in the local scope that it belongs to, and the local variable cannot be accessed by other local scopes. However, your code inside functions can access global variables, because they are global. :) Further, as we've already seen, the same name can be used for variables from different scopes.

for the above code, can we use first_ name as keys?

No. We cannot create the dictionary of dictionaries as specified above since the first_name is not unique

while True: name = input('Please enter your name: ') if name == 'stop': break print('You entered ' + name) print('Program ended')

Please enter your name: Gerald You entered Gerald Please enter your name: Sorin You entered Sorin Please enter your name: Yeohee You entered Yeohee Please enter your name: Annie You entered Annie Please enter your name: Winny You entered Winny Please enter your name: stop Program ended As expected, the loop keeps taking input and printing the name until you type 'stop', which turns the condition of the break statement from False into True.

student_data = { 'A16771125': {'first_name': 'Timothy', 'last_name': 'Mccarthy', 'pa': 93, 'rq': 61, 'lab': 90, 'midterm': 95, 'final': 74}, 'A16560701': {'first_name': 'Regina', 'last_name': 'Pierce', 'pa': 51, 'rq': 66, 'lab': 47, 'midterm': 97, 'final': 93}, 'A16891123': {'first_name': 'Blaine', 'last_name': 'Simmons', 'pa': 81, 'rq': 73, 'lab': 94, 'midterm': 78, 'final': 84}, 'A16600612': {'first_name': 'Clementine', 'last_name': 'Pierce', 'pa': 96, 'rq': 98, 'lab': 88, 'midterm': 99, 'final': 92}, 'A16280707': {'first_name': 'Baxter', 'last_name': 'Gonzalez', 'pa': 100, 'rq': 100, 'lab': 94, 'midterm': 95, 'final': 97}, 'A16740228': {'first_name': 'Yuhan', 'last_name': 'Wang', 'pa': 98, 'rq': 73, 'lab': 96, 'midterm': 84, 'final': 87}, 'A16790513': {'first_name': 'Regina', 'last_name': 'Sanford', 'pa': 88, 'rq': 90, 'lab': 80, 'midterm': 93, 'final': 95}, 'A16393543': {'first_name': 'Rohit', 'last_name': 'Singh', 'pa': 98, 'rq': 80, 'lab': 80, 'midterm': 83, 'final': 85}, }

Q1. Write a function that will return the average of the five grade components of the student with a given student_id as the input parameter. def compute_average(sid): # Accessing each grade component pa_grade = student_data[sid]['pa'] rq_grade = student_data[sid]['rq'] lab_grade = student_data[sid]['lab'] midterm_grade = student_data[sid]['midterm'] final_grade = student_data[sid]['final'] # Summing up the grades of each component sum_of_grades = pa_grade + rq_grade + lab_grade + midterm_grade + final_grade # Calculating the average of grade components average = sum_of_grades / 5 return average >>> print(compute_average('A16771125')) 82.6 >>>print(compute_average('A16600612')) 94.6

my_list = [1, 6, 8, 2, 11]

Since we don't have any negative numbers, the loop will instead exit when index is no longer smaller than the length of the list (index < len(my_list) evaluates to False). This is why we need this second loop condition. If we didn't have it, the loop would continue and try to access an index that's out of bounds of the list.

a continue statement in a while loop: while <Exit Condition>: <Statement(s) #1> if <Continue Condition>: continue <Statement(s) #2>

Step 1. Check whether <Exit Condition> is True. If it is True, It continues to Step 2. Otherwise, skip to Step 6. Step 2. Execute <Statements #1>. Step 3. Check if <Continue Condition> is True. If so, skip to Step 1. Otherwise, continue to Step 4. Step 4. Execute <Statements #2>. Step 5. Go to Step 1. Step 6. Exit the loop.

Break statement in while loop: while <Exit Condition>: <Statement(s) #1> if <Break Condition>: break <Statement(s) #2>

Step 1. Check whether <Exit Condition> is True. If it is True, continue to Step 2. Otherwise, skip to Step 6. Step 2. Execute <Statement(s) #1>. Step 3. Check if <Break Condition> is True. If so, end the while loop and skip to Step 6. Otherwise, continue to Step 4. Step 4. Execute <Statement(s) #2> .Step 5 Go to Step 1. Step 6. Exit the loop.

syntax error

Syntax errors are unique compared to other errors because they will not appear in IDLE's shell. IDLE has a handy feature where syntax errors will appear in a popup window when you attempt to run module. IDLE also highlights the source of the error, making them easier to find. A common error is unexpected EOF while parsing, which generally occurs due to a lone parenthesis, quote, or bracket.

input(v)

Takes a string argument or no argument (something called overloading), and waits for the user to give some input and reads it up until they press enter (or there's a new line in the input), and returns the result as a string.

print(v)

Takes any value v and prints it out. If v is a string, it prints the string without surrounding quotes.

total_sum = 0 for i in range(5): total_sum += i # same as total_sum = total_sum + i

The above for loop would iterate a total of 5 times In the first iteration, i is equal to 0. After the body of the loop is evaluated, total_sum has a value of 0. In the second iteration, i is equal to 1. After the body of the loop is evaluated, total_sum has a value of 1. In the third iteration, i is equal to 2. After the body of the loop is evaluated, total_sum has a value of 3. In the fourth iteration, i is equal to 3. After the body of the loop is evaluated, total_sum has a value of 6. In the fifth iteration, i is equal to 4. After the body of the loop is evaluated, total_sum has a value of 10. There are no more values to iterate over in the sequence range(5), so the loop is done being evaluated. The resulting value of total_sum is 10.

The call stack

The call stack is a mechanism that allows IDLE to keep track of its location in a program with multiple functions. Generally, a call stack works as follows. When a function is called, it is added to the call stack, and begins executing. Any functions that are called by another function are added to the top of the stack, and begin executing immediately, pausing the execution of the function that called them. When a given function is finished, it is taken off the top of the stack and the next function on the stack continues executing.

0th base indexing

The first position will be the 0th index and will increase by 1 for each next position

Two References Pointing to the Same Object

The following is an example of two references pointing to the same object. The first line creates the list object and list1 now stores the reference to the newly created list object. The second line copies list1's reference and stores it into list2. In this case, list1 and list2's references are pointing to the same object. list1 = [1, 2, 3] list2 = list1 print("Before modification...") print("list1 =", list1) print("list2 =", list2) list2[0] = 5 print("After modification...") print("list1 =", list1) print("list2 =", list2) The above code prints the following. When we update the value at index 0 for list2, notice that list1 has also been updated. This happened because list1 and list2 contain references to the same list object. Try this out in IDLE and modify the elements in list1 and list2. What happened? Are the two lists always the same? Before modification... list1 = [1, 2, 3] list2 = [1, 2, 3] After modification... list1 = [5, 2, 3] list2 = [5, 2, 3]

for day in ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']: if day in ['Sun', 'Sat']: continue print('I work on ' + day)

The for loop iterates over every day in the list of the days of the week and prints out the day. However, the loop skips the printing part when it is either Sunday or Saturday using the continue statement. Note that the print statement is executed only for weekdays as shown below. I work on Mon I work on Tue I work on Wed I work on Thu I work on Fri

Modifying the function to handle edge cases

The given height is out of bounds which means the given height parameter when added to the row index given in the top_left tuple is greater than the total number of rows present in the 2D list. The given width is out of bounds which means the given width parameter when added to the column index given in the top_left tuple is greater than the total number of columns present in the 2D list. If height or width or the elements of the tuple top_left are negative, it is considered as invalid input. def custom_red_filter(img, top_left, height, width): # Checking if any of the input parameters are negative if top_left[0] < 0 or top_left[1] < 0 or height < 0 or width < 0: return "Invalid input" # Checking if the height and width are out of bounds elif (top_left[0] + height) > len(img) or (top_left[1] + width) > len(img[0]): return "Input parameter out of bounds" for row in range(top_left[0], top_left[0]+height): for col in range(top_left[1], top_left[1]+width): pix = img[row][col] img[row][col] = (pix[0],0,0) return img

items()

The items() method comes in handy when we want to access every key-value pair. It returns a collection of every pair in the dictionary, where each pair is a tuple of a key and a value. class_dict = {'instructors': 2, 'TAs':10, 'tutors':35, 'students': 600} for num in class_dict.items(): print(num) The output of this for loop is ('instructors', 2) ('TAs', 10) ('tutors', 35) ('students', 600)

Dictionary methods for repetitive access of contents: key(), values(), items()

The keys() method returns a collection of keys in the dictionary that the method is called upon. Therefore, we can use a for loop and the keys() method to access every key as follows: class_dict = {'instructors': 2, 'TAs':10, 'tutors':35, 'students': 600} for member in class_dict.keys(): print(member) The output is given as instructors TAs tutors students

Example: n = 0 while n < 10: print(n) if n == 5: break n = n + 1

The while loop is repeated until either <Exit Condition> or <Break Condition> is met. In the example above, <Break Condition> is satisfied earlier, and therefore, the output is as follows. 0 1 2 3 4 5

defcustom_red_filter(img, top_left, height, width): for row in range(top_left[0], top_left[0]+height): for col in range(top_left[1], top_left[1]+width): pix = img[row][col] img[row][col] = (pix[0],0,0) return img

The outer for loop goes from top_left[0] which is 0 to top_left[0] + height which is 0+2 = 2. So the outer for loop range would be 0 to 2 (not inclusive). This means that the outer for loop runs for two iterations covering two rows: row index 0 and row index 1 (since range starts from 0 and goes till 2 which is the end point and the end point specified in range function is not inclusive. The inner for loop goes from top_left[1] which is 1 to top_left[1] + width which is 1+1 = 2. So the inner for loop range would be 1 to 2 (not inclusive). This means that the inner for loop runs for one iteration covering one column: column index 1 (since range starts from 1 and goes till 2 which is the end point and the end point specified in range function is not inclusive) So we can see in the final output that the pixel at (row index 0, column index 1) and pixel at (row index 1, column index 1) is only modified to have the blue and green components to be 0 while retaining the red component.

n = 0 while n < 10: print(n) if n == 15: break n = n + 1

The output of this case is as follows because <Break Condition> never becomes True while <Exit Condition> is True. In this case, the loop ends because the <Exit Condition> becomes False. 0 1 2 3 4 5 6 7 8 9

Start, stop and step arguments in range()

The range() function can also be called with two or even three arguments as follows: for i in range(3, 6): print(i) will print: 3 4 5

def assign_x(num): x = num print('The value of x is:', x) x = 10 assign_x(8) print('The value of x is:', x)

The value of x is: 8 The value of x is: 10

california = {"population" : 39512223, "capital" : "Sacramento", "landlocked" : False} This contains info on the population, capital, and whether it is surrounded on all sides by land. Take note of the fact that the values are different data types! Python dictionaries have no requirement for values to be the same data type

This dictionary is good, but it's more helpful to create a dictionary of dictionaries.

lst = [13, 12, 17, 19, 33, 0] sum_of_elements = 0 for elem in lst: sum_of_elements += elem print(sum_of_elements)

This for loop iterates over each element in the list and adds it to the variable sum_of_elements which holds the total sum of all the elements in the list.. output: 94

def square(lst): result = [] for a in lst: result = result + [a ** 2] return result

This function would not be working if result was not initially set as an empty list [] if the number of iterations in the for loop was written wrongly (e.g., range(lst) instead of lst) if the number was not squared properly (e.g., a * 2 instead of a ** 2) if the list concatenation was not properly implemented (e.g., result = result + (a ** 2) instead of result = result + [a ** 2]) if the return statement is missing or if we return the wrong data (e.g., return lst instead of return result)

print("Student 1's Grades: ") for exam_no in range(len(student1)): print("Exam " + str(exam_no + 1) + ": " + str(student1[exam_no])) print("Student 2's Grades: ") for exam_no in range(len(student2)): print("Exam " + str(exam_no + 1) + ": " + str(student2[exam_no])) # repeat for all five students . . .

This would be difficult for alot of students. Instead we can use this grades = [student1, student2, student3, student4, student5] for lst in grades: print("Student's Grades: ") for exam_no in range(len(lst)): print("Exam " + str(exam_no + 1) + ": " + str(lst[exam_no])) The first for loop for lst in grades iterates over the list of lists, then the second for loop for exam_no in range(len(lst)) iterates over the individual grades in each student's list of grades, printing them out as above. Let's get a little practice with iterating over 2D lists.

random.randint(start,end)

To randomly choose a number within a bound, you can use random.randint(start,end) which returns some randomly picked integer N where start <= N <= end.

import random print(random.randint(5,0))

Traceback (most recent call last): File "C:/Users/josep/Desktop/bugtest.py", line 2, in <module> print(random.randint(5,0)) File "C:\Users\josep\AppData\Local\Programs\Python\Python38\lib\random.py", line 248, in randint return self.randrange(a, b+1) File "C:\Users\josep\AppData\Local\Programs\Python\Python38\lib\random.py", line 226, in randrange raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width)) ValueError: empty range for randrange() (5, 1, -4) but it says the error originates in line 226 of random.py? Do I have to go into that file to fix the code?". Although the error is caused in that line, the real source of the error comes from line 2 in our code, where we run print(random.randint(5,0)), since we cannot give random.randint() a range in reverse order. The correct code would be print(random.randint(0,5)) . When troubleshooting errors thrown from libraries, look at the first line in the traceback that is from your code, rather than the library. This is the source of the error.

tupeles as values

Tuples can also be used as values. Instead of creating a dictionary mapping latitude and longitude coordinates to a city, we can do the reverse by mapping a city to a coordinate. Notice that the type of the keys are strings and the values are tuples. coordinates = {'San Diego': (32.7157, 117.1611), 'San Francisco': (37.7749, 122.4194), 'New York': (40.7128, 74.006), 'Austin': (30.2672, 97.7431)}

How to find out if references point to the same object?

Use id() list1 = [1, 2, 3] list2 = [1, 2, 3] print(id(list1)) print(id(list2)) The following is the output of the above code. Notice that the ids of list1 and list2 are different. This is because list1 and list2 contain references that point to separate objects. Separate objects should have separate id values. Also notice that when you try to run the above code on your machine, the id's are not the same every time the program executes. These id values are only assigned during program execution and are reassigned when you run the program again. 65011816 30072968

To begin using any modules, you will need an import statement to load the module.

Use: import random at the beginning of your python file to import the random module

partially increase the brightness of an image. We want the 800x 800 square at the top right corner has to be brighter that the other part.

What should be wrriten for FILL_ME_0, FILL_ME_1, FILL_ME_2, FILL_ME_3, respectively, in the following code for the regional brightness adjustment? diff = 50 for r in range(FILL_ME_0, FILL_ME_1): for c in range(FILL_ME_2, FILL_ME_3): pixel = img[r][c] pixel = (pixel[0] + diff, pixel[1] + diff, pixel[2] + diff) pixel = (min(pixel[0], 255), min(pixel[1], 255), min(pixel[2], 255)) img[r][c] = pixel right answer: 0, 800, len(img[0])-800, len(img[0])

A local variable that is created in a local scope cannot be accessed by the global scope or the other local scopes.

What's printed out def assign_x(): x = 1 modify_x() print(x) def modify_x(): x = 2 x = 0 assign_x() Prints: 1

passing arguments to functions

When you call a function, like print() , len(), or one you define yourself, you pass in values between the parenthesis, which are called arguments. Arguments can be any object, such as a list, integer, or string. For example, when we call len() on a list, the list is the argument. For example: a = [1,2,3] len(a) a is the agument to the function len()

if <condition 1>: <body 1> elif <condition 2>: <body 2>

Whenever using "elif", we always need an if clause first, followed by as many elif clauses as we would like.

Write a while loop that iterates through a list, nums, and determines whether or not it contains a value whose absolute value is greater than 10. Use the boolean variable abs_more_than_10 to store whether or not the list contains a value whose absolute value is greater than 10.

abs_more_than_10 = False # Do not edit the above line. Add your code below index = 0 while not abs_more_than_10 and index < len(nums): if(abs(nums[index])) > 10: abs_more_than_10 = True index += 1

def assign_x(num, first_call): if first_call == False: print('The value of x is at the second call:', x) x = num assign_x(8, True) assign_x(9, False)

assign_x function is slightly modified so that it takes another parameter first_call, which is a boolean variable that indicates if it is the first call of assign_x function. Our example calls assign_x function twice. The first call assigns num=8 and first_call=True. In this call, the local variable x is set as x=8. The second call of assign_x function now assigns num=9 and first_call=False. Since the condition of if statement is satisfied for this second call, print function has to be implemented. However, we have error as UnboundLocalError: local variable 'x' referenced before assignment This is because even though the local variable x had been assigned as x=8 in the previous function call, the value of x assigned in the previous call is already forgotten when that call was returned! Note that x created in the second function call is a newly created variable although it is in the same local scope of assign_x function with the same name as the previous local variable x.

The program below has bugs. It is supposed to print a sentence about each author that was born after 1900. Fix it so the output is correct. You may want to use test cases or print statements to better locate the bugs. Sample Input: Sample Output: Osamu Dazai was born in 1909 Haruki Murakami was born in 1949

author_dict = {"Ryunosuke Akutagawa": "1892", "Natsume Soseki": "1867", "Osamu Dazai": "1909", "Haruki Murakami": "1949"} for author in author_dict.items(): value = author[1] if int(value) >= 1900: print( author[0] + " was born in " + value)

>>>1/3 0.3333333333333333 >>> 1/10 0.1 but if we try to do arithmetic, something odd happens: >>> 1/10 + 2/10 0.30000000000000004

because Python (along with many other languages) uses floating-point numbers for arithmetic with non-whole numbers.

acess and update data

because dictionary is a list, therefore we can extract each element in the list using indexing with brackets. >>> directory[0] {'first_name': 'James', 'last_name': 'Smith', 'phone_number': 5106423175, 'state': 'CA'} If the last element of the directory is requested, then we can use the following ways. >>> directory[7] {'first_name': 'Linda', 'last_name': 'Johnson', 'phone_number': 4153537800, 'state': 'GA'} >>> directory[-1] {'first_name': 'Linda', 'last_name': 'Johnson', 'phone_number': 4153537800, 'state': 'GA'} >>> directory[len(directory)-1] {'first_name': 'Linda', 'last_name': 'Johnson', 'phone_number': 4153537800, 'state': 'GA'}

Continue statement

break statements let users to have a control to stop loops under a certain condition even when the loop exit condition remains True. However, what if we want to continue repeating the loop after skipping some statements? The continue statement in Python returns to the beginning of the loop to continue with the next iteration. The continue statement skips all the following statements in the current iteration of the loop and starts evaluating the loop condition for the next iteration of the loop.

get()

can access dictionaries in a similar fashion except that it does not result in KeyError. Used as dicitonary.get(key) >>> class_dict.get('instructors') 2 However, when we try to access a key that does not exist, nothing is returned and the next prompt shows up right away. >>> class_dict.get('pets') >>> The get() willreturn none if the key is non-existent.

code example with a for loop and a break statement that counts numbers in a list until zero as a stop sign. num_list = [-25, -12, 3.7, 5.2, 0, 2, 4.5, 0, 1] count = 0 for num in num_list: if num == 0: break count = count + 1 print(count)

count = 4

a method to access contents in dictionary

class_dict = {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600} If the number of instructors in the class is inquired, for instance, then the number can be accessed by the following: >>>class_dict['instructors'] 2 What happens if your code tries to access a key not included in the dictonary? It results in an error. >>> class_dict['pets'] Traceback (most recent call last): File "<pyshell#21>", line 1, in <module> class_dict['pets'] KeyError: 'pets'

we can use print() on dictionaries just like int, string, or list datetypes

class_dict = {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600} If we run print(class_dict), we would get the output: {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600}

in a list, we can use [] to obtain an element at a particular index: numbers = [2, 5, 1, 6, 10] numbers[3] We can do that too in dictionaries, but we use a key instead of an index.

class_dict = {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600} num_tutors = class_dict['tutors'] print(num_tutors) Prints: 35 quotes in class_dict['tutors'] because 'tutors' is a string.

print keys

class_dict = {'instructors': 2, 'TAs':10, 'tutors':35, 'students': 600} for member in class_dict: print(member) Here is the output of the keys printed. instructors TAs tutors students

print value(of keys)

class_dict = {'instructors': 2, 'TAs':10, 'tutors':35, 'students': 600} for member in class_dict: print(class_dict[member]) and the output is as follows. 2 10 35 600

def find_element(word, word_list): for idx in range(len(word_list)): if word_list[idx] == word: print('condition is true! idx:', idx) return [idx] return None student = 'Chris' student_list = ['Alice', 'Chris', 'Hannah', 'Jack', 'Chris] print('function returns:', find_element(student, student_list))

condition is true! idx: 1 function returns: [1] Even though 'Chris' appears twice in the list, only the first index is returned. The reason is because once we execute a return statement, the remaining iterations of the for loop, if any, are not executed

continue and break

continue and break statement can be in while and for loops

A list of programming languages named language_list is given to you as a list of strings. Write a for loop with a break statement and print out the index of an element in language_list that is the same as 'Python'. Please note that you don't have to declare language_list, as it is already given.

count = 0 for a in language_list: if language_list[count] == "Python": break count += 1 print(count)

Write a function called chain_words(str) which takes in one parameter which is a string that holds multiple words separated by spaces. Your function should return a string with the words chained together with an - (hyphen). You can first split the words at spaces and then join the words with - (hyphen). You can achieve this by using split and join methods respectively. Sample Input 1: hello world Sample Output 1: hello-world Sample Input 2: Connect the words in this sentence Sample Output 2: Connect-the-words-in-this-sentence

def chain_words(str): new = str.split(" ") return "-".join(new)

Write a function combined_cases(day1_cases, day2_cases) which take in two input parameters which are two dictionaries that represent the COVID-19 cases on one specific day in different states in the USA. Your function should return a dictionary that contains the sum of the cases of the two days in the given states. For example: If the following two dictionaries are given as input: day1_cases = {'Texas': 10678, 'Florida': 7459, 'Illinois': 12601} day2_cases = {'Texas': 13379, 'Florida': 7925, 'Illinois': 11301} Then your function must return: {'Texas': 24057, 'Florida': 15384, 'Illinois': 23902}

def combined_cases(day1_cases, day2_cases): for element1 in day1_cases: for element2 in day2_cases: if element1 == element2: day1_cases[element1] += day2_cases[element2] return day1_cases

The following function contains_2(lst) is partially complete. Replace each CHANGEME such that the function returns True once it finds a 2 in lst, or False if there is no 2 in lst. You can assume lst is a list of integer values.

def contains_2(lst): for a in lst: if a == 2: return True return False

{"all":1, "is":1, "well":2, "that":1, "ends":1}. Your function should count the total number of words in that dictionary (including duplicates). For this example, your function should return 6. Another example: if the sentence is "I scream you scream we all scream for ice cream", the word_freq dictionary (i.e., input parameter to the function) will contain {"I":1, "scream":3, "you":1, "we":1, "all":1, "for":1, "ice":1, "cream":1} and your function should return 10.

def count_total_words(word_freq): result = 0 for word in word_freq.values(): result += word return result

Write a function exclaim that takes a string and a integer, and produces that string with a number of exclamation marks after it equal to the given integer. You only need to consider cases where the number is 0 or greater (no negative numbers). For example, exclaim("Hey", 4) should produce "Hey!!!!"

def exclaim(a, b): if b>0: return a + "!" *b else: return a exclaim('Hey', 4) exclaim('Hey', 0) exclaim('!',2) exclaim('Ah', 1)

We can define functions that work with strings (and any other datatype we see in the future), too.

def fill_in(adjective, noun): return "The " + adjective + " " + noun + " wasn't very inspired." >>> fill_in("first", "example") "The first example wasn't very inspired." >>> fill_in("third", "sequel") "The third sequel wasn't very inspired."

Let's use the above idea to help with refining the function as required. The idea we will implement in the code is to use the in operator instead of the == operator so that even if the search word is partially present in the list then it should return its index as well.

def find_element(word, word_list): idx_list = [] for idx in range(len(word_list)): if word.lower() in word_list[idx].lower(): idx_list.append(idx) return idx_list

adding an username to 'ucsd.edu' domain name

emails["ucsd.edu"].append("yeohee") Remember, emails["ucsd.edu"] will retrieve the value associated with the key "ucsd.edu", which is a list! So, we can use the append method directly on this list to add an element to it

Iteration 1: Handling case insensitive searches.

def find_element(word, word_list): idx_list = [] for idx in range(len(word_list)): if word_list[idx].lower() == word.lower(): idx_list.append(idx) return idx_list >>> student_list = ['Alice', 'Chris', 'Hannah', 'Jack', 'Chris'] >>> student = 'chris' >>> print(find_element(student, student_list)) [1, 4] >>> student = 'CHRIS' >>> print(find_element(student, student_list)) [1, 4] >>> student = 'ChRis' >>> print(find_element(student, student_list)) [1, 4]

to fix the above use idx_list before the for loop and append it everytime the for loop enters an index to return

def find_element(word, word_list): idx_list = [] for idx in range(len(word_list)): if word_list[idx] == word: print('condition is true! idx:', idx) idx_list.append(idx) print('index list:', idx_list) return None student = 'Chris' student_list = ['Alice', 'Chris', 'Hannah', 'Jack', 'Chris'] print('function returns:', find_element(student, student_list)) condition is true! idx: 1 index list: [1] condition is true! idx: 4 index list: [1, 4] function returns: None

Most of the time, parameters and variable arguments will have different names.

def foobar(num1,num2): return num1 + num2 x = 1 y = 100 print(foobar(x,y)) The arguments are the variables x and y, and the parameters are num1 and num2. It is relatively straightforward to follow that the argument x is passed into the parameter num1 when foobar() is called, and similarly y is passed into num2.

Implement a function insert_pair that takes in a dictionary, key, and value and adds the new key and value pair to dictionary. Your function should return the resulting dictionary. For example, if dictionary = {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600}, key = 'head tutors', and value = 2. Your function should return the following dictionary. {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600, 'head tutors': 2}

def insert_pair(dictionary, key, value): # Complete the function dictionary[key] = value return dictionary

Given a dictionary of dictionaries as the input parameter, write a function called is_above_85 that will return the list that contains the student ids of those students who received above 85 in both the midterm and the final. For example : The first sample input (for better readability) is as given below: { 'A16771125': {'first_name': 'Timothy', 'last_name': 'Mccarthy', 'pa': 93, 'rq': 61, 'lab': 90, 'midterm': 95, 'final': 74}, 'A16560701': {'first_name': 'Regina', 'last_name': 'Pierce', 'pa': 51, 'rq': 66, 'lab': 47, 'midterm': 97, 'final': 93}, 'A16600612': {'first_name': 'Clementine', 'last_name': 'Pierce', 'pa': 96, 'rq': 98, 'lab': 88, 'midterm': 99, 'final': 92} } Your output should be: ['A16560701', 'A16600612']

def is_above_85(input): result = [] for dic in input.keys(): if input[dic]['midterm'] > 85 and input[dic]['final'] > 85: result.append(dic) return result

Q2. Write a function that will return the list that contains the student ids of those students who received above 90 in the PAs. The input parameter is the dictionary of dictionaries.

def is_pa_above_90(student_data): # Creating an empty list to store the student ids stu_list = [] # Iterating over each dictionary key for stu_id in student_data.keys(): # Checking if the pa grade is above 90 if student_data[stu_id]['pa'] > 90: # Append to the list if the grade is above 90 stu_list.append(stu_id) else: continue return stu_list >>> print(is_pa_above_90(student_data)) ['A16771125', 'A16600612', 'A16280707', 'A16740228', 'A16393543']

Another a local variable cannot be used in another local scope

def local(): x = 10 def local2(): print(x) local() local2() This has an error, because x was assigned in local function and local 2 function cannot see the value of x.

write a code that takes in input of a state, if any dictionary has that state name in it, return its first name + last Sample Input: CA Sample Output: ['James Smith', 'John Brown', 'Jennifer Davis']

def lookup_state(state): result = [] for dic in directory: if dic['state'] == state: (indent after if) result.append(dic['first_name'] + ' ' + dic['last_name']) return result

mplement negate_checkered that takes in an image in the form of a 2D list of tuples. Your function should replace all black pixels to white and all white pixels to black. Your function should return the updated image.

def negate_checkered(list): for i in range(len(list)): for j in range(len(list[i])): (r,g,b) = list[i][j] if (r,g,b) == (255,255,255): list[i][j] = (0,0,0) elif (r,g,b) == (0,0,0): list[i][j] = (255,255,255) return listw

Implement num_positives that takes in a 2D list of integers and returns the number of positive numbers in the 2D list. Sample Input 1: [[1, -3], [5, 2], [-9, -2]] Sample Output 1: 3 Sample Input 2: [[-1, -10, -20], [-40, -60, -3]] Sample Output 2: 0 Sample Input 3: [[1, 10, 20], [40, 60, 3]] Sample Output 3: 6

def num_positives(list): count = 0 for i in range(len(list)): for j in range(len(list[i])): if list[i][j] > 0: count+=1 return count

Case where a parameter can also be an argument

def print_and_return(param): print(param) return In print_and_return(), param is, of course, a parameter for the function print_and_return() . However, param is also an argument for the print() function call within print_and_return(). Though it may get a little confusing, it is important to separate what is inside a function call from what is outside of the function call,

emails = {"ucsd.edu" : ["annie","joseph","savitha"], "gmail.com" : ["ben10","annie","dio"], "aol.com" : ["joseph", "hotmail", "coda"]} Write a function named print_emails that takes as a parameter a dictionary of lists where all values are lists of strings and prints all the emails contained within in the form [email protected]. Sample Input: emails = {"ucsd.edu" : ["annie","joseph","savitha"], "gmail.com" : ["ben10","annie","dio"], "aol.com" : ["joseph", "hotmail", "coda"]} Sample Output: [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]

def print_emails(emails): # your code here. Remember to use print()! for pair in emails.items(): key = pair[0] for value in emails[key]: print(value +'@' + key)

Write a function called print_numbers that has a list of integers called my_list as its parameter. Using a continue statement and a for loop, the function prints every number in my_list except for multiples of 3.

def print_numbers(my_list): for a in my_list: if a % 3 == 0: continue print(a) input: 2 5 36 53 31 output: 2 5 5 3 31

This employees dictionary contains employee IDs and the corresponding employee name. Each key is an employee ID and each value is a name. Notice that compared to lists which have indexes that start at 0, dictionary keys can be any integer.

employees = {2201: 'Joseph Warmus', 548 : 'Annie Wai'}

For this challenge, define a function called quieter_please that takes in one string argument and checks if the string is all uppercase. If it is all upper case, convert the string to all lowercase and return this lowercased string. If the argument string is not all uppercase, return this same string, unmodified. Note: In Step 1, we learned about the upper() method, which produces a new string with all letters converted to uppercase. There is also a lower() method, which will produce a new string with all letters converted to lowercase.

def quieter_please(s): if s.isupper(): return s.lower() else: return s

how to change the whole pixel(3-tuple) to red

def red_filter_pixel(pixel_tup): new = pixel_tup pixel_tup = (new[0], 0, 0) return pixel_tup

Parameters and arguments are very closely related concepts, and you may hear the terms being used interchangeably. It is important to understand the difference to gain a full understanding of how function calls work, however. By definition, a parameter is a variable that an argument is stored in when a function is called. In other words, when you call a function, you pass in an argument which is stored in the parameter that was outlined when the function was defined. Let's get a better understanding of this concept through an example.

def return_plus_one(param): return(param + 1) let call this function a = 5 return_plus_one(a) When we call the function return_plus_one(), we use the variable a as an argument. An argument can be any object, which includes (but isn't limited to) an int, float, string, list, or boolean. Anything that can be stored in a variable can be used as an argument.

adding key-value pairs

dictionary[key] = value. Let's add a new key-value pair to the example dictionary from above. class_dict["head tutors"] = 3 Now, calling print(class_dict) will display this: {'instructors': 2, 'TAs': 10, 'tutors': 35, 'students': 600, 'head tutors': 3}

print out all the items in a particular domain in the standard email format (such as [email protected])

domain = "gmail.com" for username in emails[domain]: print(username + "@" + domain)

if <condition 1>: <body 1> else: <body 2>

else are different from if and elif clauses in that they don't have a boolena condition and act as a last resort when the preceding if and elif clause conditions evaluate to False. An else clause is always the last and there's only one of it.

sample input : -9 8 Sample output: 9

first numbers is stored in first and second number is stored in second, Write a variable declaration for larger_magnitude that contains the absolute value of the number that's furthest from 0. if abs(first) > abs(second): larger_magnitude = abs(first) else: larger_magnitude = abs(second)

But, what if we want to make every pixel at the bottom row to have B component as 225?

for column in range(4): print(our_image[2][column]) Now, instead of printing each pixel, let's save it to a temporary variable temp_pixel. for column in range(4): temp_pixel = our_image[2][column] Then for each iteration, temp_pixel is assigned with a tuple that has the color information of the corresponding pixel. To be specific, column is 0 at the initial iterationtemp_pixel is (240,0,0) column is 1 at the next iterationtemp_pixel is (240,80,0) column is 2 at the next iterationtemp_pixel is (240,160,0) column is 3 at the next iterationtemp_pixel is (240,240,0) For every iteration, temp_pixel[0], temp_pixel[1], temp_pixel[2] indicate the R component, G component, B component, respectively. Therefore, we can create a new tuple (temp_pixel[0], temp_pixel[1], 255) for each iteration and assign the newly created tuple back to the pixel our_image[2][column]. for column in range(4): temp_pixel = our_image[2][column] our_image[2][column] = (temp_pixel[0], temp_pixel[1], 255)

Codes for when you need a lot of copies, but you don't want to repeat the for loops 100 times.

for i in range(n): for j in range(len(cases)): print(cases[j]) where n is the number of copies she needs. This code contains a nested for loop because it's a loop inside a loop.

How to change the red component of every pixel be 0 0,a,b

for row in range(3): for column in range(4): print(our_image[row][column]) Here, we can apply the strategy from the previous step as follows: for row in range(3): for column in range(4): temp_pixel = our_image[row][column] For each iteration, we would like to make a new tuple (0, temp_pixel[1], temp_pixel[2]), as we want to make the R component 0. Thus, the code is completed as for row in range(3): for column in range(4): temp_pixel = our_image[row][column] our_image[row][column] = (0, temp_pixel[1], temp_pixel[2])

while loops

give us the ability to repeat executing blocks of code indefinitely until an exit condition is reached.

student1 = [100,80,95,84] student2 = [68,99,70,95] student3 = [40,100,95,80] student4 = [65,70,68,80] student5 = [70,79,85,96] grades = [student1,student2,student3,student4,student5]

grades_2D = [[100,80, 95, 84], [68, 99, 70, 95], [40, 100,95, 80], [65, 70, 68, 80], [70, 79, 85, 96]] To get the first student's grades, we can use grades_2D[0], which will give us [100,80,95,84]

for i in range(n): for j in range(len(cases)): print(cases[j])

he outer for-loop is just to repeat our inner for-loop for n times, while the inner for-loop is the one that iterates through cases and prints out the elements.

Now consider the following code where we define list2 = list1. We should expect the id's of list1 and list2 to be the same here because list1 and list2 contain references that point to the same object.

list1 = [1, 2, 3] list2 = list1 print(id(list1)) print(id(list2)) The following is the output of the above code. As expected, the id's of list1 and list2 are the same. This is how you can check whether references point to the same object or to different objects. If the ids are the same, the variables contain references to the same object. 56230024 56230024

Add sum for 2D list

list_2D = [[0,1,2], [3,4,5], [6,7,8]] total = 0 for i in range(len(list_2D)): for j in range(len(list_2D[i])): total += list_2D[i][j] print(total) Of course, we can also use for loops to iterate over items of a list directly, though this may make some tasks more difficult or impossible. This works just fine for this particular task though, as you can see. total = 0 for lst in list_2D: for element in lst: total += element print(total)

10.2 Nested for loops, 2D lists, tuples, and images.

lst1 = [10, 20, 30, 40] lst2 = [1, 2, 3] result = [] for i in range(len(lst1)): for j in range(len(lst2)): result.append(lst1[i] + lst2[j]) print(result) will print: [11, 12, 13, 21, 22, 23, 31, 32, 33, 41, 42, 43]

functions

max, min, abs, or len

**

means exponent Ex: 3**3 = 3^3 = 27

5.4 debugging

n error message is those red lines of code that IDLE's shell will display when Python attempts to run code and fails. Error messages are printed when Python encounters an error that prevents it from running code. These error messages contain some useful information including the file in which the error occurred, the line number in which the error occurred, and the exception that has occurred. An exception is simply a fancy term for an error detected during execution, and contains information about the type of error that occurs

num = 25 while num >= 0: num = num - 6

num is -5 this while loop would be equivalent to having an indefinite of numbr of nester if statements checking the same conditions and substracting 6 if True: num = 25 if num >= 0: num = num -6 if num >= 0: num = num - 6 if num >= 0: num = num - 6 . . .

prints the greennest greens

print(our_image[0][3]) print(our_image[1][3]) print(our_image[2][3]) which prints the following output. (0, 240, 0) (120, 240, 0) (240, 240, 0) However, instead of manually repeating to type print() multiple times, we can use a for loop. for row in range(3): print(our_image[row][3])

an image 3x4 in step 1, then you want to only get the red componenenst.

print(our_image[2][0]) print(our_image[2][1]) print(our_image[2][2]) print(our_image[2][3]) which prints the following output. (240, 0, 0) (240, 80, 0) (240, 160, 0) (240, 240, 0) However, instead of manually repeating to type print() multiple times, we can use a for loop. for column in range(4): print(our_image[2][column])

while some_condition: # statements to execute go here in the loop body

some_condition: can be any boolean expression( an expression that evaluates to True or False) A while loop will first check that some_condition is True and if so, then execute the loop body. Once the loop body completes, some_condition is checked again, and if it's True, it will enter the body again. This process repeats until the evaluation of some_condition is False.

dictionary of dictionary

states = {"California" : {"population" : 39512223, "capital" : "Sacramento", "landlocked" : False}, "Oregon" : {"population" : 4217737, "capital" : "Salem", "landlocked" : False}, "Nevada" : {"population" : 3080156, "capital" : "Carson City", "landlocked" : True}} print(states["Nevada"]["capital"]) will print out Carson City, pretend it's like 2d dictionary. When we access the value of this dictionary with states[i][j] , i is the key to the specific state dictionary we are looking at, and j is the key to the information we are looking for.

a column of students ids, names, and grades for some different sections. We pick the unique key, or the student ID, and use a dictionary for the value.

student_data = { 'A16771125': {'first_name': 'Timothy', 'last_name': 'Mccarthy', 'pa': 93, 'rq': 61, 'lab': 90, 'midterm': 95, 'final': 74}, 'A16560701': {'first_name': 'Regina', 'last_name': 'Pierce', 'pa': 51, 'rq': 66, 'lab': 47, 'midterm': 97, 'final': 93}, 'A16891123': {'first_name': 'Blaine', 'last_name': 'Simmons', 'pa': 81, 'rq': 73, 'lab': 94, 'midterm': 78, 'final': 84}, 'A16600612': {'first_name': 'Clementine', 'last_name': 'Pierce', 'pa': 96, 'rq': 98, 'lab': 88, 'midterm': 99, 'final': 92}, 'A16280707': {'first_name': 'Baxter', 'last_name': 'Gonzalez', 'pa': 100, 'rq': 100, 'lab': 94, 'midterm': 95, 'final': 97}, 'A16740228': {'first_name': 'Yuhan', 'last_name': 'Wang', 'pa': 98, 'rq': 73, 'lab': 96, 'midterm': 84, 'final': 87}, 'A16790513': {'first_name': 'Regina', 'last_name': 'Sanford', 'pa': 88, 'rq': 90, 'lab': 80, 'midterm': 93, 'final': 95}, 'A16393543': {'first_name': 'Rohit', 'last_name': 'Singh', 'pa': 98, 'rq': 80, 'lab': 80, 'midterm': 83, 'final': 85}, }

cases = [12508, 9969, 310595, 57409] n = 3 for i in range(n): sum = 0 for j in range(len(cases)): sum += cases[j] print('sum is: ' + str(sum))

sum is: 390481 sum is: 390481 sum is: 390481

Regional Brightness Adjustment We would like to increase the brightness of an image as we did in the step 1, except that we want to keep the pixels at the first 100 rows, the last 100 rows, the first 100 columns, and the last 100 columns unchanged.

the are unchanged is like a border What should be written for FILL_ME_0, FILL_ME_1, FILL_ME_2, FILL_ME_3, respectively, in the following code for the regional brightness adjustment? diff = 50 for r in range(FILL_ME_0, FILL_ME_1): for c in range(FILL_ME_2, FILL_ME_3): pixel = img[r][c] pixel = (pixel[0] + diff, pixel[1] + diff, pixel[2] + diff) pixel = (min(pixel[0], 255), min(pixel[1], 255), min(pixel[2], 255)) img[r][c] = pixel What should be written for FILL_ME_0, FILL_ME_1, FILL_ME_2, FILL_ME_3, respectively, in the following code for the regional brightness adjustment?: 100, len(img)-100, 100, len(img[0])-100

variable declaration or variable initialization

the first time we create a variable with = Ex: >>>x=10 and because variable declaration by itself doesn't print anything, we need to print it using: >>>x

len()

the len() function accurately returns the number of key-value pairs in class_dict. We can see that the dictonary class_dict consists of the following 4 key-value pairs: 'instructors': 2 'TAs': 10 'tutors': 35 'students': 600

An object

the value that the reference refers to. an object is simply a collection of data

Break statements

they can used to indicate such stop signals, i.e, in what conditions the loop can be ended regardless of whether the loop exit condition is satisfied.

2nd task: find the key with the most counts.

to iterate through every key and value in the dictionary and find the maximum value and its corresponding key. max_key = 0 # initialize the key that corresponds to the max value max_value = 0 # initialize the max value for pair in counts.items(): # pair is a tuple key = pair[0] value = pair[1] if value > max_value: # If value is greater than the current max value max_value = value # Update the new max_value max_key = key # update the new max_key print("mode =", max_key) prints: mode = 5

Dictionary of dictionries

values in dictionaries can be mutable objects. Lists are a very common example of a mutable object, but we can use any mutable object as a value, including dictionaries!

9.1 More dictionaries

we want to find the mode: mode is the number that appears most often in a set of numbers. we can find mode in 2 tasks: find out the number of occurrences for each number, and use that information to find the number that occurs most often.

Each row includes a name, a phone number, and a state name. To describe this data, we can consider the first name, last name, phone number, and the state as keys and the corresponding data as values. Therefore, each row can be represented using a dictionary, and the first row, for example, is shown as follows. {'first_name': 'James', 'last_name': 'Smith', 'phone_number': 5106423175, 'state': 'CA'}

{'first_name': 'James', 'last_name': 'Smith', 'phone_number': 5106423175, 'state': 'CA'} {'first_name': 'Jennifer', 'last_name': 'Wilson', 'phone_number': 5307521011, 'state': 'OR'} {'first_name': 'Robert', 'last_name': 'Jones', 'phone_number': 9498245011, 'state': 'NY'} {'first_name': 'Mary', 'last_name': 'Willaims', 'phone_number': 3108254321, 'state': 'TX'} {'first_name': 'John', 'last_name': 'Brown', 'phone_number': 2092284400, 'state': 'CA'} {'first_name': 'Patricia', 'last_name': 'Miller', 'phone_number': 9518271012, 'state': 'FL'} {'first_name': 'Jennifer', 'last_name': 'Davis', 'phone_number': 8585342230, 'state': 'CA'} {'first_name': 'Linda', 'last_name': 'Johnson', 'phone_number': 4153537800, 'state': 'GA'} In order to have the information of everyone in the directory as a single data structure altogether, the dictionaries can be all included in a list by putting them in brackets and separating by commas as follows. directory = [{'first_name': 'James', 'last_name': 'Smith', 'phone_number': 5106423175, 'state': 'CA'}, {'first_name': 'Jennifer', 'last_name': 'Wilson', 'phone_number': 5307521011, 'state': 'OR'}, {'first_name': 'Robert', 'last_name': 'Jones', 'phone_number': 9498245011, 'state': 'NY'}, {'first_name': 'Mary', 'last_name': 'Willaims', 'phone_number': 3108254321, 'state': 'TX'}, {'first_name': 'John', 'last_name': 'Brown', 'phone_number': 2092284400, 'state': 'CA'}, {'first_name': 'Patricia', 'last_name': 'Miller', 'phone_number': 9518271012, 'state': 'FL'}, {'first_name': 'Jennifer', 'last_name': 'Davis', 'phone_number': 8585342230, 'state': 'CA'}, {'first_name': 'Linda', 'last_name': 'Johnson', 'phone_number': 4153537800, 'state': 'GA'}] hen, we can check that directory is indeed a list of dictionaries by using the type function. >>> type(directory) <class 'list'> >>> type(directory[0]) <class 'dict'> Also, we can use the len function to confirm that the number of people saved in the directory is 8. >>> len(directory) 8 What happens if we apply the len function to not only the entire list but to each dictionary? It will return the number of key-value pairs, which is 4 in this case because each dictionary has 4 items -- first name, last name, phone number, and state. >>> len(directory[0]) 4


Ensembles d'études connexes

Anatomy & Physiology - Bone Markings

View Set

Presidential and Radical Reconstruction Quiz

View Set

Producer, Consumer and Decomposer

View Set

Nursing Application: LifeSpan and Drug Therapy Unit 2 Edapt

View Set

Chapter 7: Auditing, Testing, and Monitoring

View Set

Connect: the Conceptual Framework

View Set