Friday, February 21, 2014

week 5

Throwback to week 5. All I remember was how hard the lab is...

The function Danny led us through in class provide me with enough inspiration to finish A1. It's a great idea which i could not have though of myself.

I find the lingoes used to describe the relations among value, variable, memory address in 148 different from those in 108. But since computer science is not about the accuracy of language. I would probably let it go. Still, my understand is a variable contain value, which refers to an memory address as traced in visualizer.

About the scope in python, the key point to scope given in class is to follow the hierarchy system and apply the sequence. For example, in the example given in class, the most important part to understand is how do_global() failed to let  print("After global assignment:"spam) print global spam, but instead, nonlocal spam. Since nonlocal already 

But looking back, as i am reviewing everything and do the labs all over again, recursion begins to make sense to me. Practice makes perfect. Here are some typical recursion question, one of which i copy from slides, one i think of my self:
largest number in a nested list: the insight is to replace every nested list with the max. and the base case is where there's no nested case: max(l),  so the code is return max([largest(i) if isinstance(i, list) else i for i in l)]), by creating a new simple, not nested list
the second example is to decide whether a number is in a nested list. The base case is where there's no nested list, simply n in l. The insight is to n is either in non nested list or inside nested list. Code: return any(n==i if not isinstance(i, list) else whether(n, i) for i in l)

Thursday, February 20, 2014

week 6

This week we begin with binary trees. Its supreme node is called the root. And especially for binary trees, each node can only have 2 children. In the list expression, recursion is obvious in that the tl[0] is an object/ value while the rest two component are tree lists themselves. As for the three methods to trace the tree, I find the first one is what we generally use, while i really don't know what the other two can be used in. Binary tree presents a systematic hierarchy of data structure.
In addiction, i come up with a different solution from class: e.g. in order [tl[0]+ (inorder(tl[1]) if isinstance(tl[1], list) else []) + (inorder(tl[2]) if isinsatnce(tl[2], list) else []). The ternary structure requires all three components. And this solution is just a thought, I later find out this would not work if the list is None.

The second part is the general tree implementation, where the trees can have more than two children. It follow the structure from binary tree except that it combines the branches of each nodes together in a list(from left to right). Clearly, the leaves are also presented as subtrees with children set to empty list in its __init__ method. I spent a lot of time trying to figure out how to write its methods in recursion and find that though it's relatively easy to trace and understand recursion; it's so much harder to write them down on my own. By looking at the answers, i gather some inspiration from then.
__contain__: I was initially kind of confused about that it doesn't  have a base case. But when self.children is [], the for loop wouldn't executed, thus ending the recursion.  Notably, the use of "any" is helpful in some cases
__repr__: I was trying this in the shell, and it turned out that i don't need to use recursion at all. Since i pass in a tree list, the __init__ method__ would turn it into the appropriate structure, and when we tried to "represent" it. Can't we just simply use "Tree()". format(self.value, self.children)?
leaf_count: this function also used something new that took me a while to understand. The idea I frist come up with is sum([leaf_count(i) ) for i in t.children),  then i am stuck with the base case.
count: the base case is when self.children == [], return 1 e.g.sum([2**x for x in []]) return 0

Meanwhile, I am trying to come up with an ultimate process to write recursion function. The first step is coming up with the base case. And write code that recursion can run.  But loopholes are everywhere.

Questions
1. if statement can exist without else, in the short-form list expression can we use ### if ## and leave out the else?  when i tried this, it results in an error.
answer: [x+7 if x> 2 else x+2 for x in [2,3,4]] ternary fixed syntax

2. when we define our own class, isinstance method should also work on defined classes. But for the Tree class here, even though we require children to be None or another Treelist, isinstance can't tell the difference. AKA isinstance(Tree(2, [2,3]), Tree) evaluates to True. How can we fix the problem?