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
Before the lab
Quiz
Study for the python quiz
Linear Algebra
One of the main features of Octave we will discuss is vectorization. To understand it, we need some background material on Linear Algebra. If you've taken a linear algebra course recently, this should be easy, otherwise you will probably need to review
Vector Operations, particularly
- Addition
- Subtraction
- Scalar multiplication
-
- Addition
- Subtraction
- Scalar multiplication
Matrix Multiplication Review
Background
We will mainly rely on the Octave Interpreter Reference. A more tutorial style guide is the Gnu Octave Beginner's Guide, which is available in ebook form from the UNB library.
We'll refer to the online text by Robert Beezer for linear algebra background. We can happily ignore the stuff about complex numbers.
Python Quiz
The first half of the lab will be a quiz on python
- Time
- 50 minutes
- Activity
- quiz
Running Octave
- Time
- 5 minutes
- Activity
- Demo / discussion
There is a GUI accessible from
Applications -> FCS -> GNU Octave, or by running from the command line% octave --guiThere is also a REPL accessible from the command line by running
% octaveTo sanity check your octave setup, run the following plots
>> surf(peaks) >> contourf(peaks)
Recursive Fibonacci
- Time
- 10 minutes
- Activity
- Demo/Group programming.
Here is a JavaScript recursive function for Fibonacci:
function fib(n) {
if (n<=0)
return 0;
if (n<=2)
return 1;
else
return fib(n-1)+fib(n-2);
}
Let's translate this line by line into an Octave function.
Save the following in ~/cs2613/labs/L20/recfib.m; the name of the
file must match the name of the function.
function ret = recfib(n)
if (n <= 0)
ret = 0;
elseif (n <= 2)
ret = 1;
else
ret = recfib(n-1) + recfib(n-2);
endif
endfunction
Like the other programming languages we covered this term, there is a built in unit-test facility that we will use. Add the following to your function
%!assert (recfib(0) == 0);
%!assert (recfib(1) == 1);
%!assert (recfib(2) == 1);
%!assert (recfib(3) == 2);
%!assert (recfib(4) == 3);
%!assert (recfib(5) == 5);
Note the
%! assert. These are unit tests that can be run with>> test fibThe syntax for
%!assertis a bit fussy, in particular the parentheses are needed around the logical test.
Questions for your journal
Table based Fibonacci
- Time
- 25 minutes
- Activity
- Programming puzzle
A powerful technique for making recursive A more problem specific approach (sometimes called dynamic programming) is to fill in values in a table.
Save the following in ~/cs2613/labs/L20/tabfib.m. Complete the missing line by
comparing with the recursive version, and thinking about the array indexing.
function ret = tabfib(n)
table = [0,1];
for i = 3:(n+1)
table(i)=
endfor
ret = table(n+1);
endfunction
%!assert (tabfib(0) == 0);
%!assert (tabfib(1) == 1);
%!assert (tabfib(2) == 1);
%!assert (tabfib(3) == 2);
%!assert (tabfib(4) == 3);
%!assert (tabfib(5) == 5);
Questions for your journal
- What are two important differences about array access in Octave compared to Python and JavaScript?
Performance comparison
- Time
- 10 minutes
- Activity
- Demo / discussion
Let's measure how much of a speedup we get by using a table.
Of course, the first rule of performance tuning is to carefully test
any proposed improvement. The following code gives an extensible way
to run simple timing tests, in a manner analogous to the Python
timeit method, whose name it borrows.
# Based on an example from the Julia microbenchmark suite.
function timeit(func, argument, reps)
times = zeros(reps, 1);
for i=1:reps
tic(); func(argument); times(i) = toc();
end
times = sort(times);
fprintf ('%s\tmedian=%.3fms mean=%.3fms total=%.3fms\n',func2str(func), median(times)*1000,
mean(times)*1000, sum(times)*1000);
endfunction
We can either use timeit from the octave command line, or build a little utility function like
function bench
timeit(@recfib, 25, 10)
timeit(@tabfib, 25, 10)
endfunction
Questions for your journal
What are the new features of Octave used in this sample code?
Roughly how much speedup is there for using tables to compute the 25th fibonacci number?