This feed contains pages with tag "python".
Introduction
In this assignment you will write a class ColumnDict that takes a
table in the form of a list of lists (e.g. from a CSV file) and
provides a key-value data structure (dictionary) where the values are
the columns of the table.
For full marks in this assignment your solutions should not use any loops, but only comprehensions (and other builtin functions as needed). Your solution should also work with arbitrarily large input.
- Make sure you commit and push all your work using coursegit before 16:30 on Thursday November 27.
Dictionary functionality
Provide a constructor, and appropriate “dunder” methods so that the following tests pass. You should only store the data once.
def test_one_row():
table= ColumnDict([["alice", "bob"],
[27, 32]])
assert table["bob"] == [32]
assert table["alice"] == [27]
def test_two_rows():
table2= ColumnDict( [["alice", "bob"],
[1, 2],
[False, True]])
assert table2["bob"] == [2,True]
assert table2["alice"] == [1,False]
def test_three_cols():
table3= ColumnDict( [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]])
assert table3["bob"] == [2,True]
assert table3["alice"] == [1,False]
assert table3["mallory"] == [3,None]
def test_update():
table3= ColumnDict( [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]])
table3["bob"]=[42,False]
assert table3["bob"] == [42,False]
assert table3["alice"] == [1,False]
assert table3["mallory"] == [3,None]
Selecting subsets of columns
Write a select method for you ColumnDict class that produces table
(list of lists) table with subset of the columns. Your select method
should handle any number of key arguments, including zero.
def test_select1():
table3= ColumnDict( [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]])
out=table3.select("alice", "mallory")
assert out == [["alice", "mallory"],
[1, 3],
[False, None]]
def test_select2():
table3= ColumnDict( [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]])
assert table3.select() == []
Iterator
Provide appropriate dunder methods to support iteration. Do not copy
or traverse the data more times than necessary. Do not use generators
(i.e. yield). Your code should pass (at least) the following tests.
def test_iter1():
rows= [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]]
expected = [["alice", "bob", "mallory"],
[1, 2, 3],
[False, True, None]]
table3= ColumnDict( rows )
assert list(table3) == expected
def test_iter2():
rows= [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]]
expected = [["alice", "bob", "mallory"],
[1, 2, 3],
[False, True, None]]
table3= ColumnDict( rows )
out = []
for row in table3:
out.append(row)
assert out == expected
def test_iter3():
rows= [["alice", "mallory", "bob"],
[1, 3, 2],
[False, None, True]]
expected = [["alice", "bob", "mallory"],
[1, 2, 3],
[False, True, None]]
table3= ColumnDict( rows )
assert [ row for row in table3 ] == expected
assert list(table3) == expected
Getting started
- Make a directory
~/cs2613/labs/L19 - Download Work.zip and unzip in your newly created directory.
Generators and iterator classes
- Time
- 25 minutes
- Activity
- individual
Consider the countdown generator from Section 6.2
def countdown(n):
print('Counting down from', n)
while n > 0:
yield n
n -= 1
Referring to Section
6.1
an equivalent iterator class. Here we will implement the entire protocol with one class, but multiple classes like we did for JavaScript is also reasonable.
Modify only the __next__ method of the following skeleton class so that given
tests pass.
def countdown(n):
yield 'starting'
while n > 0:
yield n
n -= 1
def test_generator():
counter = countdown(3)
assert [ t for t in counter ] == \
['starting', 3, 2, 1]
class Counter:
"Iterator class simulating countdown"
def __init__(self,n):
self.n = n
self.first = True
def __iter__(self):
return self
def __next__(self):
# insert code here
self.n -= 1
return self.n+1
def test_class():
counter = Counter(3)
assert [ t for t in counter ] == \
['starting', 3, 2, 1]
What is __iter__ for?
- Time
- 25 minutes
- Activity
- individual
Update the __iter__ method of your previous solution so that the following additional test passes
def test_twice():
counter = Counter(3)
assert [ t for t in counter ] == \
['starting', 3, 2, 1]
assert [ t for t in counter ] == \
['starting', 3, 2, 1]
- Question for your journal: what is an important functionality difference between generators and more general iterators?
Using Generators I
- Time
- 25 minutes
- Activity
- individual
Note that 6.5 just asks you to run some code, but you do have to be in the correct directory when running it.
For 6.6, you essentially need to split the given code so that the
first part is the new generator follow.
Using Generators II
- Time
- 25 minutes
- Activity
- individual
Start with the following stock related classes:
Complete Exercise
6.7. I
suggest you make a new file follow2.py so that you preserve
solutions for 6.6 and 6.7.