Python - Basic - 2 - Jupyter Notebook (Student)
Python - Basic - 2 - Jupyter Notebook (Student)
We start with the While loop and provide you some additional useful tricks to apply in the For loop.
We spend a bit of time on casting objects from one type to the other and explain you what these
__double__ underscores are about.
Then we go through the overviews of list and dictionary operations. There is quite a lot you can do
with these 2 powerfull and common used objects.
Then list comprehension. This is a very powerful construct that allows you to create a new list from
another while applying a filter and an expression to each item. It is a for loop inside a list.
And finally the nameless lambda function, which comes in very handy in numerous applications.
Table of Contents
More on loops
While loop
Range
Enumerate
Casting
Dunder methods
Summary - More on loops
while
range
enumerate
casting
dunder methods
List operations
Summary - List operations
list operations
localhost:8890/notebooks/2022/22Aug/PRJ63504 Capstone (Python)/CADS/Python for Analytics (Basic)/MC/Day 2/Python_Day2_MC.ipynb 1/34
8/22/22, 9:19 PM Python_Day2_MC - Jupyter Notebook
RUN ME
Exercises - List operations
Exercise 1 - Month days
Exercise 2 - Get unevens
Exercise 3 - Sum top
Exercise 4 - Match ends
Dictionary operations
Summary - Dictionary operations
dictionary operations
RUN ME
Exercises - Dictionary operations
Exercise 1 - Numbers info
Exercice 2 - Cart checkout
Exercise 3 - Student Marks
List comprehension and lambda
List Comprehensions
Lambda
Summary - List comprehension and lambda
list comprehension
lambda
RUN ME
Exercises - List comprehension and lambda
Exercise 1 - Negative ints
Exercise 2 - Power odds
Exercise 3 - Word lengths
Exercise 4 - Celsius to Fahrenheit
Exercise 5 - Square odds lambda
Exercise 6 - Square odds lc
Exercise 7 - Extract A names lambda
Exercise 8 - Extract B names lc
Exercise 9 - Sort last
Exercise 10 - Coordinates
More on loops
While loop
The while loop continues iterating until it's condition stops being True.
In [ ]: # MC
# THREE basic requirements in a loop:
# 1) start point,
# 2) end point,
# 3) what keeps it going from start to end
i = 0
while i < 10:
i += 1
print(i)
Let's write a code that asks the user for integer numbers until the total is 50.
In [ ]: #### MC
total = 0
while total < 50:
x = int(input())
total += x
print("total:", total, "x:", x)
Notice the condition " total < 50". The loop keeps iterating until that condition stops being
True. The input() function asks the user for input. The int() function casts a string to a float.
This is called casting, we cast an object of one type to be of another type. Then we add the
resulting number x to the total . We repeat until the total is 50 or higher.
Now we want to check if the input string is convertible to an integer. Let's use dir(str) to see
which method we could use for that.
In [ ]: # MC
dir(str)
Question: Which string function can we use to check can cast a string (str) to an integer (int)?
Answer:
str.isnumeric,
str.isdigit,
str.isdecimal
all work
In [ ]: # MC
help(str.isnumeric)
In [ ]: ## MC
total = 0
while total < 50:
x = input()
if x.isnumeric():
total += int(x)
else:
print("{} is not a valid round number!".format(x))
print("total:", total, "x:", x)
Variable x is a string. If that string is numeric it can be casted to an integer. Else, we print that it
is not a valid round number.
Range
The for loop is used often in combination with range(). Let's have a look.
In [ ]: # MC
help(range)
In [ ]: # MC
range(5)
In [ ]: # MC
for i in range(5):
print(i)
In [ ]: # MC
for i in range(0, 11, 2):
print(i)
Enumerate
Sometimes you want to loop over a list of items and also use the index numbers. For this we can
use the enumerate function.
In [ ]: # MC
items = ["banana", "orange", "apple"]
In [ ]: # MC
list(enumerate(items))
In [ ]: # MC
list(enumerate(items, start=1))
In [ ]: # MC
for i, item in enumerate(items, start=1):
print(i, item)
Casting
We casted a str to an int. We can do this for any of types. If the obj is not castable then we will
get an Exception.
In [ ]: # MC
str(True)
In [ ]: # MC
int("10")
In [ ]: # MC
float("10.0")
In [ ]: # MC
tuple([1,2,3])
In [ ]: # MC
list((1,2,3))
In [ ]: # MC
dict([1,2,3])
In [ ]: # MC
dict([('a', 1), ('b', 2)])
Dunder methods
So what's with all the '__blah__'?
Object methods with two underscores are called "dunder methods". This stands for double
underscore. These tell Python what to do in certain operations, for example __eq__ is a function
to compare with another object and __add__ handles the + operation under the hood.
In [ ]: # MC
dir(list)
In [ ]: # MC
help(list.__add__)
In [ ]: # MC
list_1 = [1,2,3]
list_2 = [4,5,6]
list3 = list_1 + list_2
list3
In [ ]: # MC
list_1.__add__(list_2)
So dunder method __add__ implements what happens when the + operator is applied.
while
while i < 5:
i+=1
print(i)
range
range(5)
range(1,6)
range(0,11,2)
for i in range(5):
print(i)
enumerate
Returns a tuple containing a count (default start s with 0) and the values
obtained from iterating over iterable.
items = ['orange','apple','mango']
enumerate(items)
print(i,item)
casting
int("10")
float("10.2")
dunder methods
str.__add__
str.__eq__
List operations
The list is a very power object with many functionalities.
len( dict ) – Gives the total length of the dictionary. This would be equal to the number of
items in the dictionary.
list.clear() – Removes all elements of the list
list.copy() – Returns a shallow copy of the list
list.append( element ) – adds a single element to the end of the list. Common error:
does not return the new list, just modifies the original.
list.insert( index , element ) – inserts the element at the given index, shifting
elements to the right.
list.extend( list2 ) adds the elements in list2 to the end of the list. Using + or += on
a list is similar to using extend().
list.index( element ) – searches for the given element from the start of the list and
returns its index. Throws a ValueError if the element does not appear (use in to check
without a ValueError).
item in list – check if the item is in the list
list.remove( element ) – searches for the first instance of the given element and removes
it (throws ValueError if not present)
list.sort() – sorts the list in place (does not return it).
sorted( list ) – return sorted list but keeps the original order of the list
list.reverse() – reverses the list in place (does not return it)
list.pop( index ) – removes and returns the element at the given index. returns the
rightmost element if index is omitted (roughly the opposite of append()).
This is to give a overview, so that you know of the existence of these functionalities.
Do you need to learn these by heart? No. Because you can always look it up using help() or
dir() or the online python documentation.
In [ ]: # MC
numbers = [1,2,3,4]
numbers
In [ ]: # MC
len(numbers)
In [ ]: # MC
numbers.clear()
numbers
You can use the list.copy() method when you want to copy the list and make a new object out
of it.
In [ ]: # MC
numbers = [1,2,3,4]
numbers_2 = numbers
numbers_3 = numbers.copy()
In [ ]: print(id(numbers))
print(id(numbers_2))
print(id(numbers_3))
In [ ]: # MC
numbers.append(5)
Notice this doesn't return a object. This is an in-place operation. The original object is changed.
Now 5 is added to the list. Let's see what happened to variable numbers_2 and variable
numbers_3 .
In [ ]: # MC
print(numbers)
print(numbers_2)
print(numbers_3)
In [ ]: print(id(numbers))
print(id(numbers_2))
print(id(numbers_3))
In [ ]: # MC
## wrong way
new_numbers = numbers.append(6)
print("numbers", numbers)
print("new_numbers", new_numbers)
Notice that the value of new_numbers is None. This is what happens when you assign an in-
place operation to a variable.
In [ ]: # MC
## correct way
numbers.append(6)
new_numbers = numbers
print("numbers", numbers)
print("new_numbers", new_numbers)
We can also insert an item anywhere in the list. This is also an in-place operation.
In [ ]: numbers
In [ ]: # MC
numbers.insert(2, 100) # insert at index = 2
numbers
We can also extend a list with another list. Notice this in an in-place operation.
In [ ]: # MC
numbers.extend([10, 20, 30])
numbers
In [ ]: # MC
[1,2,3] + [4,5,6]
In [ ]: # MC
numbers.append([10, 20, 30])
numbers
In [ ]: # MC
numbers.index(10)
In [ ]: # MC
print(numbers)
print(numbers[0:numbers.index(10)])
In [ ]: # MC
200 in numbers
We can remove an item. It will remove the first occurence of that item.
In [ ]: # MC
print(numbers)
numbers.remove(6)
print(numbers)
In [ ]: # MC
# numbers = [1, 2, 200, 5]
print(numbers)
numbers.sort()
print(numbers)
We can also sort reversed by adding keyword argument reverse = True. The sorted() built-
in function returns a sorted list but it does not affect the original.
In [ ]: # MC
print(sorted(numbers, reverse=True))
numbers
In [ ]: # MC
numbers = [10, 20, 500, 60, 50]
numbers.reverse()
numbers
The pop() function returns the last items and removes it from the list.
In [ ]: # MC
while numbers:
print(numbers, numbers.pop())
A list can be casted to a bool, which happens if a list is evaluated like here in the while
statement.
In [ ]: # MC
bool([1,2,3])
In [ ]: # MC
bool([])
## check whether list is not empty or list is empty
list operations
The list is a powerful object with many functionalities. The list is a mutable
object.
numbers = []
numbers = [1,2,3,4]
numbers[0]
numbers[0] == 100
numbers.append(0)
numbers.extend([5,6,7])
numbers.remove(5)
numbers.copy()
numbers.clear()
numbers.index(5)
numbers.sort()
numbers.sort(reverse=True)
item = numbers.pop()
sorted(numbers, reverse=True)
5 in numbers
len(numbers)
RUN ME
Please run the below code snippet. It is required for running tests for your solution.
if got == expected:
prefix = ' OK '.center(max_width_print, '=')
else:
prefix = ' FAIL '.center(max_width_print, '=')
print(('%s\n got: %s \nexpected: %s' % (prefix, repr(got), repr(expected)
end = '\n\n')
define a function that inputs a string and returns the numbers of days in that month.
Hints:
help(str.index)
In [ ]: # MC
def month_days(month):
months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"]
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
i = months.index(month)
return days[i]
print("month_days", end = '\n\n')
test(month_days("January"), 31)
test(month_days("February"), 28)
test(month_days("September"), 30)
test(month_days("December"), 31)
define a function called remove_even that returns a list after removing the even numbers from
it.
help(str.append)
In [ ]: # MC
num = [7, 8, 120, 25, 44, 20, 27]
def remove_even(numbers_list):
new_numbers = []
for n in numbers_list:
if n % 2:
new_numbers.append(n)
return new_numbers
print("get_unevens", end = '\n\n')
test(remove_even(num), [7, 25, 27])
In [ ]: # MC
num = [7,8, 120, 25, 44, 20, 27]
def remove_even(number_list):
num1 = number_list.copy()
for i in number_list:
if i%2 == 0:
num1.remove(i)
return num1
print("get_unevens")
test(remove_even(num), [7,25,27])
Hints:
sorted(...)[:3]
In [ ]: # MC
numbers = [50, 23, 1, -50, 4, 400, 55, 32]
def sum_top(numbers_list):
return sum(sorted(numbers_list, reverse = True)[:3])
print("sum_top", end = '\n\n')
test(sum_top(numbers), 505)
Given a list of strings, return the count of strings which the string length is 2 or more and the first
and last chars of the string are the same.
In [ ]: # MC
text1 = (['aba', 'xyz', 'aa', 'x', 'bbb']) #3
text2 = (['', 'x', 'xy', 'xyx', 'xx']) #2
text3 = (['aaa', 'be', 'abc', 'hello']) #1
def match_ends(words):
counter = 0
for word in words:
if len(word) >= 2 and word[0] == word[-1]:
counter += 1
return counter
print('match ends', end = '\n\n')
test(match_ends(text1), 3)
test(match_ends(text2), 2)
test(match_ends(text3), 1)
In [ ]: # MC
## alternative
text1 = (['aba', 'xyz', 'aa', 'x', 'bbb'])
text2 = (['', 'x', 'xy', 'xyx', 'xx'])
text3 = (['aaa', 'be', 'abc', 'hello'])
def match_ends(words):
return len([word for word in words if (len(word) >= 2 and word.startswith(wor
print('match_ends', end = '\n\n')
test(match_ends(text1), 3)
test(match_ends(text2), 2)
test(match_ends(text3), 1)
Dictionary operations
localhost:8890/notebooks/2022/22Aug/PRJ63504 Capstone (Python)/CADS/Python for Analytics (Basic)/MC/Day 2/Python_Day2_MC.ipynb 16/34
8/22/22, 9:19 PM Python_Day2_MC - Jupyter Notebook
A dictionary is a collection of key-value pairs. It is used to look up things and a very common used
type. Notice the { } curly brackets and the "key": "value" notation. Notice the squared bracket for
looking up.
len(dict) – Gives the total length of the dictionary. This would be equal to the number of
items in the dictionary.
dict.clear() -- Removes all elements of dictionary dict
dict.copy() – Returns a shallow copy of dictionary dict
dict.update(dict2) – Adds dictionary dict2's key-values pairs to dict
dict.fromkeys() – Create a new dictionary with keys from seq and values set to value.
dict.get(key, default=None) – For key key, returns value or default if key not in
dictionary
dict.setdefault(key, default=None) – Similar to get(), but will set dict[key]=default if
key is not already in dict
dict.items() – Returns an iterator of dict's (key, value) tuple pairs
dict.keys() – Returns iterator of dictionary dict's keys
dict.values() – Returns list of dictionary dict's values
In [ ]: # MC
prices = {"apple": 1.5, "orange": 3.25}
prices["apple"]
In [ ]: # MC
len(prices)
In [ ]: # MC
prices_2 = prices
prices_3 = prices.copy()
print('before dict.clear()')
print(prices)
print(prices_2)
print(prices_3)
In [ ]: # MC
prices.clear()
print('after dict.clear()')
print(prices)
print(prices_2)
print(prices_3)
In [ ]: # MC
prices = prices_3
The dictionary is mutable like a list. This is how we can update the dictionary with a new value.
In [ ]: # MC
prices = {"apple": 1.5, "orange": 3.25}
# MC - something that does not exist can be directly input
prices["banana"] = 2.30
prices
To update one dictionary with the another dictionary we can use update method. Notice this is an
in-place operation.
In [ ]: # MC
prices.update({"mango":1.22, "durian":5.60})
prices
In [ ]: # MC
help(dict.fromkeys)
In [ ]: # MC
keys = ["Jeremy", "Narjes", "Amin"]
dict.fromkeys(keys, [])
In [ ]: # MC
prices = {"apple": 1.5, "orange": 3.25}
prices["orange"]
Stay calm.
In [ ]: # MC
prices["pineapple"]
In [ ]: # MC
prices.get('pineapple')
In [ ]: # MC
prices.get('pineapple', 1.0)
In [ ]: prices
In [ ]: # MC
print(prices)
print(prices.setdefault('pineapple', 1.0))
print(prices)
Let's say we have a dictionary of lists. We can use setdefault and append in one go.
In [ ]: # MC
fruits = {}
fruits.setdefault('pineapple', []).append(10)
fruits
In [ ]: # MC
prices.keys()
In [ ]: # MC
prices.values()
In [ ]: # MC
prices.items()
In [ ]: # MC
for fruit in prices:
print(fruit, prices[fruit])
The best way to loop over the key-value pairs is using prices.items()
In [ ]: # MC
for k, v in prices.items():
print(k,v)
dictionary operations
Dictionary. A collection of key-value pairs. Used to look up things. The dict class
provides many functionalities. The dict is a mutable object.
prices = {}
prices["mango"] = 2.0
prices.update({"strawberry":4.0, "melon":10.0})
prices["orange"]
prices.get("pineapple", 1.0)
prices.setdefault("pineapple", 1.0)
prices.keys()
prices.values()
prices.items()
for k in price:
print(k)
print(k,v)
prices.clear()
prices.copy()
len(prices)
RUN ME
Please run the below code snippet. It is required for running tests for your solution.
if got == expected:
prefix = ' OK '.center(max_width_print, '=')
else:
prefix = ' FAIL '.center(max_width_print, '=')
print(('%s\n got: %s \nexpected: %s' % (prefix, repr(got), repr(expected)
end = '\n\n')
Given a list of numbers return a dictionary with info about the numbers. The dictionary should
contain keys "len", "max", "min", "sum", "avg" with those measures as the respective values.
Round avg to 2 decimals.
Hints: sum()/len()
print("numbers_info")
test(info(numbers), {'avg': 11.0, 'len': 5, 'max': 25, 'min': 1, 'sum': 55})
In [ ]: # MC
numbers = [1, 4, 9, 16, 25]
def info(numbers):
result = {"len": len(numbers),
"max": max(numbers),
"min": min(numbers),
"sum": sum(numbers),
"avg": round(sum(numbers) / len(numbers),2)}
return result
print("numbers_info")
test(info(numbers), {'avg': 11.0, 'len': 5, 'max': 25, 'min': 1, 'sum': 55})
Compute the total price of this cart. By default everything cost RM 1, except when prices are
written.
In [ ]: total=0
## your code
print("cart_checkout")
test(total, 54.0)
In [ ]: # MC
total=0
for k,v in cart.items():
print(k, v)
total += v * prices.get(k, 1)
print("cart_checkout")
test(total, 54.0)
1. Write a function that add a mark to a student. Make sure the function can handle new
students!
2. Add 20 to Narjes, add 11 to Jeremy and add 5 to Darren
3. Compute the average mark of Jeremy. Round it to 2 decimals
In [ ]: grades = {
'Amin':[12, 14, 20],
'Jeremy':[5, 12],
'Narjes':[10]
}
# 1. Write a function that adds a grade to a student.
def add_grade(student_name, grade):
## your code here
In [ ]: # MC
grades = {
'Amin':[12, 14, 20],
'Jeremy':[5, 12],
'Narjes':[10]
}
# 1. Write a function that adds a grade to a student.
def add_grade(student_name, grade):
grades.setdefault(student_name, []).append(grade)
List Comprehensions
A list comprehension is a compact expression to create a new list out of another list while applying
filters and expressions. All in one line!
We want to create a new list with these numbers, but we only want the uneven numbers and we
want to square those.
Let's try.
In [ ]: # MC
newlist = [n for n in numbers]
newlist
In [ ]: # MC
newlist = [n for n in numbers if n%2!=0]
newlist
In [ ]: # MC
newlist = [n**2 for n in numbers if n%2!=0]
newlist
We looped over the numbers, applied a filter and applied an expression on each item n.
iterable: numbers
element: n
condition: n%2!=0
expression: n**2
Lambda
The lambda is a nameless function.
Sometimes your want to define a function for a single time usage. In that case a lambda function is
more elegant than predefining a whole named function, that you will only use once.
Lambda functions are mainly used in combination with the functions sort(), filter() and map().
Let's say we want to sort this list of tuples based in the total value of the tuple.
In [ ]: # MC
sorted(tuples)
In [ ]: # MC
help(sorted)
In [ ]: # MC
sorted(tuples, key=lambda x: sum(x))
We can also filter based on the last item, which is indicated by [-1]
In [ ]: # MC
sorted(tuples, key=lambda x: x[-1])
The filter() function applies a filter function on the list. The outcome of the filter function is a
boolean.
In [ ]: # MC
numbers = [1,2,3,4,5]
filter(lambda x: x%2==0, numbers)
In [ ]: # MC
list(filter(lambda x: x%2==0, numbers))
In [ ]: # MC
def power_2(x):
return x**2
list(map(lambda x: x**2, numbers))
In [ ]: # MC
list(map(lambda x: x**2, filter(lambda x: x%2==0, numbers)))
list comprehension
A compact way to process all or part of the elements in a sequence and return a
list with the results.
numbers = [1,2,3,4,5]
lambda
RUN ME
Please run the below code snippet. It is required for running tests for your solution.
if got == expected:
prefix = ' OK '.center(max_width_print, '=')
else:
prefix = ' FAIL '.center(max_width_print, '=')
print(('%s\n got: %s \nexpected: %s' % (prefix, repr(got), repr(expected)
end = '\n\n')
Write a list comprehension to create a new list that contains only the negative numbers as integers
and store it as newlist.
In [ ]: # MC
numbers = [34.6, -203.4, 44.9, -68.3, -12.2, 44.6, 12.7]
newlist = [int(n) for n in numbers if n < 0]
# TEST
print("negative_ints")
test(newlist, [-203, -68, -12])
Write one line of Python that takes this list and makes a new list that only has the odd elements
and power it with 3.
Hints: x**3
In [ ]: numbers = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
result = ##
print("power_odds")
test(result, [1, 729, 15625, 117649, 531441])
In [ ]: # MC
numbers = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
result = [n**3 for n in numbers if n%2!=0]
print("power_odds")
test(result, [1, 729, 15625, 117649, 531441])
Write a list comprehsion to determine the length of each word except 'the' and store as
word_lengths
In [ ]: sentence = "the quick brown fox jumps over the lazy dog"
## your code
word_lengths = ## your code
# TEST
print()
test(word_lengths, [5, 5, 3, 5, 4, 4, 3])
In [ ]: # MC
sentence = "the quick brown fox jumps over the lazy dog"
words = sentence.split()
word_lengths = [len(w) for w in words if w != "the"]
# TEST
print("words_lengths")
test(word_lengths, [5, 5, 3, 5, 4, 4, 3])
Convert the following list of temperatures in Celsius to Fahrenheit. Round the results to 2 decimals.
Fahrenheit = 9/5*Celsius + 32
In [ ]: # MC
celsius = [43.6, 67.3, 43.6, 56.4]
fahrenheit = [round((9/5)*c + 32, 2) for c in celsius]
# TEST
print("celsius_to_fahrenheit")
test(fahrenheit, [110.48, 153.14, 110.48, 133.52])
Write a lambda function that squares number for all odd numbers from 1 to 100
In [ ]: # MC
numbers = list(range(1,100+1))
answer = list(map(lambda x: x**2,filter(lambda x: x%2!=0, numbers)))
# TEST
print("square_odds_lambda")
test_answer = [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625, 729, 841
test(answer, test_answer)
Write a list comprehension that square number for all odd numbers from 1 to 100
Hints: range(1,100)
In [ ]: # MC
answer = [n**2 for n in range(1,101) if n%2!=0]
# TEST
test(answer, [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625, 729, 841,
961, 1089, 1225, 1369, 1521, 1681, 1849, 2025, 2209, 2401, 2601, 28
3025, 3249, 3481, 3721, 3969, 4225, 4489, 4761, 5041, 5329, 5625, 5
7225, 7569, 7921, 8281, 8649, 9025, 9409, 9801])
In [ ]: # MC
names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']
answer = list(filter(lambda x: x.startswith("A"), names))
# TEST
print("extract_a_names_lambda")
test(answer, ['Anne', 'Amy'])
Write a list comprehension to extract the names that begin with 'B'
In [ ]: # MC
names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']
answer = [n for n in names if n.startswith("B")]
# TEST
print("extract_b_names_lc")
test(answer, ['Bob', 'Barbara'])
e.g. [(1, 7), (1, 3), (3, 4, 5), (2, 2)] yields
[(2, 2), (1, 3), (3, 4, 5), (1, 7)]
Hint: use a custom key= function to extract the last element form each tuple.
In [ ]: # MC
#output: [(2, 1), (3, 2), (1, 3)]
list1 = [(1, 3), (3, 2), (2, 1)]
#output: [(3, 1), (1, 2), (2, 3)]
list2 = [(2, 3), (1, 2), (3, 1)]
#output: [(2, 2), (1, 3), (3, 4, 5), (1, 7)]
list3 = [(1, 7), (1, 3), (3, 4, 5), (2, 2)]
def sort_last(tuples):
return sorted(tuples, key=lambda x: x[-1])
# TEST
print("sort_last")
test(sort_last(list1), [(2, 1), (3, 2), (1, 3)])
test(sort_last(list2), [(3, 1), (1, 2), (2, 3)])
test(sort_last(list3), [(2, 2), (1, 3), (3, 4, 5), (1, 7)])
Exercise 10 - Coordinates
In [ ]: coords = []
for x in range(4):
for y in range(2):
coordinate = (x, y)
coords.append(coordinate)
print(coords)
In [ ]: # MC
coords_lc = [(x,y) for x in range(4) for y in range(2)]
# TEST
print("coordinates")
test(coords_lc, [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)])