From the existing example.py:
class Matrix:
def __init__(self, s):
self.rows = [[int(n) for n in row.split()]
for row in s.split('\n')]
self.columns = [list(tup) for tup in zip(*self.rows)]
def row(self, index):
return self.rows[index - 1]
def column(self, index):
return self.columns[index - 1]
An alternate implementation processing columns in a method rather than an instance property:
class Matrix(object):
def __init__(self, matrix_string):
self.matrix = [[int(ele) for ele in row.split(' ') ] for row in matrix_string.split('\n')]
def row(self, index):
return self.matrix[index - 1]
def column(self, index):
return [row[index - 1] for row in self.matrix]
An extended implementation using .copy()
to protect against accidental data mutation:
class Matrix(object):
def __init__(self, matrix_string):
# have to use "List Comprehension" to make lists in a list
self.matrix = [[int(num) for num in tmp.split()] for tmp in matrix_string.splitlines()]
def row(self, index): # grab which ever row requested
return self.matrix[index - 1].copy() # use .copy() to protect accidental data issues
def column(self, index): # grab the first number in each array
return [row[index - 1] for row in self.matrix]
- [Classes][classes]: the exercise objective is to define a
matrix
type. Tested methods are linked to amatrix
class - [Objects][objects]: creating different instances with different data representing different
matrices
is tested - [Constructor][constructor]: customizing object initialization with actions and persisting data. The example uses a constructor to process the passed in data into a list of lists assigned to an instance property
- [Dunder Methods][dunder-methods]: the example uses the
__init__
magic method as its constructor for the class - [Return Values][return-value]: "row" and "column" list values are expected from defined instance method(s)
- [Implicit Argument][implicit-argument]: the example uses the
self
implicit argument for methods and properties linked to a specific instance of the class - [Namespaces][namespaces]: knowing to use
self
.<propertyname>
for instance properties andself
as first argument to instance methods in a class - [Instance Methods][instance-methods]: tests for this exercises require one or more instance methods that will return a specified row or column list of the
matrix
. - [Instance Properties][instance-properties]: this exercise requires one or more instance properties to persist passed in data.
- [Mutability][mutability]: in the extended example, knowing there are no protected or private properties in python and adjusting coding patterns
- [Assignment][assignment]: instance properties need to be assigned passed in data
- [Method Arguments][method-arguments]: the methods returning "row" and "column" need to take both
self
and an integer as arguments - [Lists][lists]: this exercise requires "row" or "column" be returned as a
list
. Alist
oflists
is also the recommended way to process and store the passed-in data. - [Indexing][indexing]: the "rows" and "columns" of this exercise need to be retrieved from a list of lists via index
- [Bracket Notation][bracket-notation]: knowing that
[]
should be used to refer to a value at a specific index in a list - [Slicing][slicing]: the extended solution to this exercise can employ a slice (returns a copy) instead of calling
.copy()
. - [Iteration][iteration]: the passed-in string is iterated over, and split into rows. The row lists are iterated over and split into elements
- [Iterables][iterables]: understanding that strings, lists, and other data structures can be iterated over in the same fashion
- [Iterators][iterators]: the example solution for this exercise uses
zip()
, which returns an iterator. - [For Loop][for-loop]: iterating over the passed in
matrix
string using afor
loop to extract "rows" and "columns" that are appended to a list - [Comprehension Syntax][comprehension-syntax]: knowing that this is equivalent to a
for loop
- putting the row or column creation code inside the list literal instead of using loop + append. - [Zip][zip]: the example solution for this exercise uses this function to aggregate the column-wise elements of each row list to form the matrix "columns".
- [Argument Unpacking][argument unpacking]: the example solution for this exercise uses
splat
(*
) to unpack rows for thezip()
function. - [String Splitting][string-splitting]: the example uses
str.split
with and without separators to break the passed in string into "rows" and then "elements" - [Type Conversion][type-conversion]: the passed in data is in
str
format but the output is expected as a list of typeint
. - [Int][int]: the example converts the parsed
str
elements intoint