Saturday 26 October 2013

Week 7

This week we covered something I've been looking forward to for a while - linked lists. It seems a lot simpler after learning about it but there were lots of things to take away from the course this week.

There are two ways of thinking about the linked list, both of which can be summarized in one sentence: either as a sequence of nodes, each of which contains both a value and and an embedded reference/link to the following node in the sequence, or as a tree with an arity of 1. It seems simple enough, but the wording made it a bit confusing to me. In class, the nodes were represented as classes with a value/item attribute, and a next attribute (the link), which was itself a node. In that case, it seems like the nodes in a linked list do not contain references to other nodes but rather just contain the nodes themselves as an attribute. This seems to be contradictory to the picture used to represent linked lists:


which looks like a sequence of nodes. Rather, the code makes the link list seem like a bunch of nested nodes, with the depth as an indicator of the order. Thinking about linked lists this way, or as a tree, makes more sense to me.

Another difficulty I encountered this week was understanding the difference between __repr__ and __str__. In essence, although they are both string representations of an object, __repr__ is called when either the object itself  is called or repr() is called on the object, and __str__ is called when print() is called on the object. The main difference is that __repr__ is a more formal representation of the object, and should return enough information to be able to fully reconstruct the object. In other words object == eval(repr(object)) should return true (although in practice this doesn't always happen because sometimes it leads to an infinite loop). On the other hand, __str__ is more of an informal representation and emphasizes readability rather than unambiguity.

Besides these two concepts, we covered some other methods like __contains__, __len__, and __getitem__ (which we were also able to try and implement ourselves in the lab) which allowed us to get some more practice writing recursive methods for trees.

Also, the links to all of the SLOGs were posted this week so I'll be reading over some of them and talking about what some of the other students are thinking in the remaining weeks. I'll try to comment on things I find interesting and hopefully others will comment on this blog if they feel like it. Overall, I really enjoyed the class this week and was able to learn some new concepts while applying them and practicing older ones.

Week 6

Week 6 - the halfway point for the course! Coincidentally, because of Thanksgiving and the first midterm we didn't have any class for the week - just the midterm on Wednesday and lab #5/ exercise #4 on Friday. 

First off, let's talk about the midterm. It was a fair test, and covered recursion, classes/inheritance, and testing. I liked that the questions were varied as opposed to being along the lines of: 'write code for this function' each time, testing our understanding in different ways. I thought that the first question was interesting - it involved calculating the output for inputs 1-6 in the recursive function we had to write for assignment 1.  I thought that it was a good way to test the ability to read and understand how a recursive function works - except for the fact that those who went far enough in assignment 1 have already written the exact same function themselves, and that more time was spent doing simple arithmetic than thinking about the code. The rest of the questions were quite straightforward: writing a recursive function, implementing a subclass of list, and writing 3 possible tests to test our subclass. Overall, I enjoyed writing the first midterm.

The exercise this week was about tree traversal, and was a good way to keep the concept of trees fresh in our mind in preparation for linked lists the following week. Since we only touched on trees rather quickly during week 5, it was a good opportunity to review the code for the different tree traversals, as well as get some practice writing recursive functions for trees.

The lab provided a good comparison of the efficiency of three different ways of iterating: for loops, list comprehensions, and generators. I remember when I first started learning Python that one of the first problem sets involved a problem very similar to the pythagorean triples function in the lab. It was a struggle back then, but I never realized how simple the solution could be with list comprehensions/generators. Finally, one last thing I learned this week was the any() built in function - something I wish I knew about sooner!

Next week we'll be covering some new and important material (link lists) so I'm looking forward to that next.

Sunday 13 October 2013

OOP and recursion

The assigned topics for this week that I'll be talking about are Object-Oriented Programming, and recursion. These two words pop up pretty often in the programming world but what exactly are they and why do we care?

Object-Oriented Programming, or OOP for short, is a programming model where everything can be represented as an object or a class. What is an object/class you say? Well in truth it can really be whatever you want it to be.

For example, in Python a string is an object. In this case, it's a sequence of characters which have certain characteristics or "attributes", like their length and also certain functions or "methods" that can be applied to it, like the join() method. At first the purpose of OOP may not be obvious, but the main benefit is that it allows us to abstract physical things and concepts that we have in the real world, and create a recipe for it in a program. Using the previous example, a string is really just a recipe for representing some text. An instance of a class, for example of a string, is a specific example of that class. Something like 'hello' would be an example of a piece of text, or using OOP lingo, an instance of a string.

Another benefit of OOP is the concept of hierarchy, which is a very human and natural way to classify things. For example, let's say there is a zookeeper who wants to represent his zoo in the virtual world. He would like to be able to classify the animals in his zoo, but also store attributes (what's their name, what do they eat, how many legs do they have) and methods (feed the animal, clean up their enclosure) related to each animal. A natural way to approach this would be to create a class (a specific object) called Mammals, which could have an "number of legs" attribute of 4. Then, he could create a subclass of mammals called lemurs, which would have a "food" attribute of bamboo. Finally if he had a lemur in his zoo called George, he would create an instance of a lemur with the name "George". In OOP, a subclass inherits from its superclass, which is what allows for this kind of organization.

In short, OOP allows programmers to abstract ideas from the real world and represent them in a program, whether it be plain text, animals, or stacks.

Another concept which allows programmers to bring real world thinking into a program, is the concept of recursion. Recursion is essentially the idea of breaking a task down into smaller bits, until the pieces of the task are small enough to be solved very easily, and then finding the solution by rebuilding all the solved pieces together. In a function, this manifests itself as having a base case, the smallest possible piece, and having the function call itself on a smaller piece until it gets to the base case, which is when it starts building back up. An example of a recursive function would be a function that calculates the nth fibonacci number. If you were asked to calculated the first or second fibonacci number, the answer would be simple: 0 or 1, because you already know what they were. However, if you were asked to calculate the third fibonacci number, then you would have to think back: what was the first and second number? Or, for the eighth fibonacci number, you would have to think: what are the sixth and seventh numbers? To solve that, you would need to find the fourth and fifth, and then the second and third, and so on. Hence, recursion is in fact a very natural way to think about solving certain problems, and usually leads to very readable, simple, code which can solve seemingly much more complex problems.

Using these two concepts of OOP and recursion, computer scientists are able to bring more natural concepts and ways of thinking from the real world into a program.

Week 5

This week, we talked about recursion, got started on trees, talked about the midterm, and handed our first assignment in. Pretty eventful I must say!

We finished off recursion by writing a function for solving the Towers of Hanoi which made me realize how much more comfortable I am with recursive functions compared to the start of class - they no longer seem like a magic black box - although they're still pretty cool to think about.

Something that I learned this week was the concept of a tree as well as the ways to traverse the tree, but I'm sure I'll get used to it with more practice and I'm looking forward to learning about some of its applications.

Overall, with the assignment due in the middle of this week and the midterm coming up next week, there wasn't much time to cover new material. However, it's been a good time to go back and look over the course material up to now to prepare for the midterm. With some solid practice writing recursive functions from the lab on Friday I feel pretty confident about the content we've covered so far, with the exception of the different kinds of traversal through a tree (I'm still working on it!). I'm also looking forward to seeing what assignment 2 will be like, which is coming up in a couple of weeks.

Wednesday 9 October 2013

Week 4

Hello and welcome to my new blog! Here I'll be discussing all things CSC148 on a weekly basis. For this first post, I'll be going over everything up to week 4.

So far, we've focussed on a couple of core topics: classes and inheritance, raising exceptions, stacks, debugging, and last but not least - recursion. Although I've already had an introduction to these concepts through MIT's 6.00x course, in class we were able to spend a bit more time on each topic which not only exposed me to some new ideas but also helped gain a better understanding of certain of what I already knew.

The first change that I noticed was the course's adherence to proper style and convention for code. The PEP8 and PEP257 documents really gave me an idea of the style standards in the python community, and How to Code Like a Pythonista gave some useful tips that I had never heard about. The simplicity of the first few exercises and tutorials gave me a chance to think about and incorporate these new ideas into my code. On the other hand, I found that the PEP8 checker didn't allow for any exceptions that may allow for better readability of the code, which went against the very belief that "a foolish consistency is the hobgoblin of little minds."

Another thing I learned is the unittest and doctest methods for debugging/testing. I had skimmed over the code treating these subjects on Coursera, but the exercise and tutorial allowed me to get some practice in actually implementing test suites and understanding how they work.

Finally, the course gave me a better understanding of topics I had already been introduced to. I was able to gain some insight on inheritance and the relationship between classes (more specifically how that relates to methods and parent class constructors), as well as get some practice on trying to wrap my head around some recursive functions, going through each layer to see how the functions work.

A final highlight of the course so far that I'd like to mention is the first assignment, which involved solving and animating the Towers of Hanoi and Reve's Puzzle. The assignment was challenging, and in hindsight, wasn't frustrating or difficult. Through the assignment I was able to learn about tkinter, Reve's puzzle and the frame-stewart algorithm, and get some practice using many facets of python programming. However, I think the most value I got from the assignment was from taking the time to read and understand someone else's code and add to it, an aspect of programming that I haven't really been exposed to, and one that I tend to avoid if possible. Finally finishing the assignment and watching the animation of the solution was a great feeling!

So in short, it's been an exciting first couple of weeks. I'm really looking forward to the rest of the course!