Sunday, 15 February 2015

Week 6: Object Oriented Programming

OOPS, we're on week 6 already and just finally summarizing objected oriented programming (see what I did there ... again?)

It's been a bit of a ride, having just finished the first midterm and received the marks for both the midterm test and the first assignment. At the start of the year in September, we learned the hard basics of Python programming (by hard I mean literally, not difficulty-wise) - putting together a slab of functions, variables, and nearing the end of the course, classes. That was our first introduction to what was later perceived as "object oriented programming", in addition to "abstract data types". So, that brings us to the painfully obvious question: what exactly is an object? After reviewing some slides and doing some online digging, I came to a simple conclusion:

Everything in Python is an object.

Again, what does this entail? Well, everything in Python, from classes, functions, variables, methods, can all be passed as arguments to other, well, functions, methods etc etc. This means that they can be assigned to variables to be passed and have operations performed upon. Tying it to object oriented programming (or OOP for short), it essentially means that everything I've ever done in Python from the basics of arithmetic to module manipulations and recursions have all been classified as "OOP". Now, with the introduction of abstract data types of creating our own variables and classes, the idea of object oriented programming stretches a bit,

In creating our own variables and classes, I feel that we've stretched the boundaries of object oriented programming, yet at the same time progressed towards a better understanding of the subject/material. Hear me out:

Traditionally, I understood object oriented programming as operating with objects - that is, to create variables, and through a large series of functions/methods/operations, to manipulate and add on to a series of standard variables (str/int/float/list etc), thus the "stretching" of boundaries. Yet with Python and the concept of anything being an object, this fulfills my understanding of the concept of OOP.

Sunday, 8 February 2015

Week 5: Recurring thoughts about recursion

See what I did there? :)

To the best of my knowledge, recursion, to me, is a form of Python script that calls itself to perform a specific task. It eases tasks for which there is no definite/finite number of function calls. Prof. Heap shared with us a simple reasoning. Suppose you wanted to sum a list. Call sum(), right? And if you wanted a depth-1 nested list, you'd loop around it and then sum it up. But what if we didn't know the depth of the list? Say you have 6 loops, but then you encounter a list with depth 7? With the examples we did in class, I understood it as a form of a "nested list unraveller", where you keep calling the function on lists and lists until you finally end up with flattened list and then you perform the function on it. A basic example is:


def f(x):
    if isinstance(x, list):
        return sum([f(a) for a in x])
    else:
        return 1

Where f(x) calls itself every time it encounters a list. With this,

f([1,2,3,4]) returns 4. Is it a list? Yes, now call f(x) for each element in the list, and return 1 if it's a number. This returns a list of [1,1,1,1] to be summed. Because this code calls itself to check for lists, we are essentially providing a quick solution to find out how many elements there are in any depth of a list.

f([1,2,3,4,[55, [1, 3, 44, [12], 1]], [[65]], 12]) returns 12. Notice how the many brackets are basically ignored?

Even then, recursion was a bit of a doozy for me. I attended the night lecture and attempted the given worksheet on tracing recursion. I had trouble (and even on the midterm too), not in understanding the given code, but rather the method Prof. Heap wanted us to write it in. He said that if we knew the trace call, just fill it in directly instead of retracing again. I tried that, thought I felt that my solution was ridiculously short compared to his.

During the lab, I tried again to trace it methodically, and while I understood every solution and problem given, I still had trouble writing the tracing the way Prof Heap wanted. Then came the midterm - a simple 3 questions over 8 pages in 45 minutes (some unwarranted time lost due to the sluggishness of the previous EX100 occupants) with a dead given: a recursion tracing question.

I'd like to say that I can confidently write basic recursive functions without much trouble, though I'd definitely like to see my midterm results first :)

Update: (01 March 2015)

Now having learned about trees (both binary and not), I can definitely see recursion being a useful tool. For example, making a tree with a height of 5 and then performing specific tasks, to my knowledge, is all but unfathomable without recursion. When some of the nodes are leafs, and some aren't, with an indefinite height, there isn't really a plausible solution (that we've discussed in class) that would really work - other than recursion. With this being said, I can now see many possible improvements on many of my other small home-projects that I've been working on. Though I do struggle with some specific tree functions (such as the in_between exercise from lab #6), I do think that recursion can now be confidently added to my toolbox of useful Python tools.

Sunday, 1 February 2015

Week 4: Reflections on Weeks 1 & 2

It's already week 4 of the new semester, and with the first assignment behind us now, I figure that it'd be a good time to look back at the first two weeks of the course. Coming into CSC148 (having taken CSC108 in the earlier fall term), I was fairly confident in my abilities to program basic programs logically, using helper functions and loops accordingly. I sat down Wednesday night in front of Professor Heap, an instructor I had heard many good things for. The topics for the first week were mostly review and an introduction: abstract data types (classes, subclasses, etc), and general object oriented design.

As a bit of a side note, I was not that confident in my abilities at designing classes. Although they were on the 108 final exam, and on the PCRS system for that course, I didn't get too much practice applying them. Moving on, the first two weeks were very rough for me even if there wasn't any "homework" (unlike, again, CSC108) that was due. I had trouble keeping up with the professor's pace in class design, for example, when he wrote point.py to review classes and their functions, in addition to Heap's implementation of stacks. I understood the concept, but the code whizzed right by me. Since we didn't do any further exercises with the stacks, I was a bit lost in trying to determine a good usage for them.

Right now, I am currently recapping the first two weeks by looking over the given .py files, and I realized that there were many files that the Wednesday night class didn't go over. We never received the yellow/white handouts, and I don't think they were mentioned in class either. To help my own understanding, I had to use Stack Overflow to answer some of my questions on __repr__ and practice using them on basic classes.

All in all, the first two weeks had a very rough transition on me. Putting together the pieces of a new "abstract" approach to Python implementations in addition to a much larger course load compared to last semester meant that I had even less time to straighten my own understanding. As of week 4, and moving into week 5 for the upcoming midterm, I do believe that I am now much better equipped at tackling the problems yet to come. I can now firmly state that I have "mastered" the first two weeks' material.