Thursday, 20 March 2014

Can't see the forest for the (binary) trees

Over the course of the last two weeks, my experiences in CSC 148 have been completely dominated by trees -- binary trees, regex trees (some of which are unary trees), binary search trees, trees with linked lists-- and for much of that time, I felt at least a little like I was lost in the woods.

When we first saw trees in Week 6, the concept seemed fairly simple. Understanding the structure and terminology of trees-- roots, nodes, children, leaves, height, etc-- was easy with a picture of a tree in front of me. Things got a little harder when I had to applying the same concepts to TreeLists--which visually seemed much more complex than the trees they represented. Traversing trees by hand was almost fun (shout-out to whoever posted that traversal video featuring Paul Gries, who I singlehandedly credit with making me interested enough in computer science to be taking this course, which is currently kicking my ass)--and I was SO READY for a midterm question that asked me to reconstruct a tree given two traversals.

That question never did show up on the midterm--but lo and behold, there it was as part of e3. Figuring out the code to produce the tree was a little more complex, but still a fun logic problem. The strategy of working things out by hand and then asking, 'how did I know that?" really helped--for example, knowing that an inorder traversal traces left-root-right allows you to split the tree into left and right subtrees (with the root isolated by virtue of its place in the PREorder list)--and then realizing that if I'm applying the same process to each subtree, it must be a good time to apply RECURSION.

(About recursion: even if I'm still not a pro at knowing HOW to use it, I think I'm much better now at knowing WHEN to use it--baby steps, right?)

Having knocked e3a off my checklist in short order, I internalized the (very wrong) idea that e3b would have the same level of difficulty--initially challenging, but then I would just GET it. (I worked on that function for several hours. I never 'got it'.) I knew enough to use the 'height' function we had seen in class to get the depth of the tree, but I never did figure out a way to identify the individual elements in the longest path. Neither did any of the 5 other people I converse with in this class. I THINK this has to do with my insistence on evaluating trees from the root down, when really I should be working with recursive calls from the leaves on up, but I need even MORE time to work with this function to figure it out.

Disheartened by this experience with trees (and also by my time-crunched earlier experiences with A1 and A2.1), I was dreading sitting down to work on A2.2, certain that I would while aware every spare hour I had (and some that I didn't have) being frustrated with the functions.

Luckily, this was not the case. I sat down with A2.2 on Monday morning, and managed to knock off most of the work before my lab on Tuesday night. It was so nice to walk into that classroom feeling like I had a handle on things (by the end of the night, I'd lost the handle again, as my worst enemy, linked lists, joined forces with binary tree traversals to confuse me soundly). I even helped some other students debug their code! Mine wasn't perfect-- I couldn't get one of the examples from the handout to match a longer, more complex string--but at least I was ahead of the curve this time.

Thankfully, after much perusal of Piazza, I stumbled across this post, which COMPLETELY cleared up my misunderstanding of how regex matching worked and ALMOST caused me to shout 'YES' after I successfully completed my function in the back of another class whilst watching a movie.

Having submitted A2.2 several hours ahead of the deadline (what a nice change!), I'm breathing a little easier--for tonight. Tomorrow, though, and for several days after, I'll go back to the demanding task of climbing (and descending) trees in preparation for the midterm--which I expect is going to be MUCH more difficult for me than Test 1.  Hopefully by the time Wednesday rolls around, I'll be equipped with the skills I need to find my way out of the woods.

Sunday, 9 March 2014

Losing The Race Against Time

This was a hairy week for me-- I had a major takehome midterm (40% of my final grade) due in another class, too many shifts at work (thanks, coworkers, for choosing this week to have babies and/or go to South Africa), and a heavy mileage training week--and it did not end well.

Over the past few weeks, I've realized I've bitten off more than I can chew by trying to go back to school full time, work (almost) full time and train for a marathon. I'm exhausted all the time, unenthusiastic about everything and too afraid to ask for help. With the cold weather over the past week, SAD hit me especially hard and I just couldn't deal.

Although I got some comfort in knowing that I scored very high (okay, let me enjoy my one triumph this week, perfectly) on the midterm for this class, and know that I am pulling in good marks in the labs and (hopefully) on this sLOG, I'm starting to feel pretty lost when it comes to CSC148.

I've just handed in a drastically incomplete file for A2 part 1, and although I feel like I understand the concept of the assignment, and think I could work things out given more time, I'm seriously doubting my prospects for success in this course. Over the course of the past two assignments, I have spend copious amounts of time trying to puzzle out the answers to questions the assignment didn't even pose. For example, in working on A2, I spent a valuable chunk of time trying to work out function that would convert a string representation of a regex to a nested list (I was unsuccessful in this venture). I think this might have been helpful, but less than necessary for part 1.

I've also come to the realization that maybe I can't do this alone-- perhaps I shouldn't try to be so self-sufficient, but instead actually work with a partner on these things. If only I wasn't so busy with work and training an commuting and a class schedule full of conflicts with office hours, I might have time to commit to meeting with other students or a TA.

My biggest realization this week is that something in my life has got to give--but I'm genuinely unsure what it will be. I need my job to pay for my classes,  I need my classes to get me into grad school, and I need to run because it (paradoxically) makes it easier for me to breathe most days. Marathon training seems like to obvious answer, but my training time is precious to me--it saves my sanity and might be the only thing standing between me and my next meltdown.

So really, my biggest lesson this coming week will be figuring out how to ask for help.

(And on a lighter note, of all this days to spring forward and lose an hour, there couldn't have been a worse one than today.)

Sunday, 2 March 2014

A Recurring Theme

Back when I was a lit student (which was longer ago than I care to think it was),  I read far too many novels far too closely, looking for the most tenuous connections to what a professor or reviewer had identified for me as "the theme" of the book.

On one memorable occasion, my class read a novel that my professor presented as "a commentary on the struggle between art and science; between 'people of letter' and 'people of numbers'". Being a novel (and therefore presumably written by a 'person of letters'), the commentary was SLIGHTLY biased, and more or less decried scientists as immoral beings who are going to destroy the world as we know it.








I struggled with that book a lot, both because I hated that it seemed impossible to be both a 'person of letters' and a 'person of numbers'. I thought I was both, studying chemistry and English literature as I was, and if I had to choose, I wanted to be a 'person of numbers'. Unfortunately, working with letters has always been second nature to me, and working with numbers has always been much, much harder.

As much as I try not to believe in right brain/left brain and other dichotomies about learning styles that I (ashamedly admittedly) view as 'excuses' or 'not trying hard enough',  I've always thought that I just don't have a math brain. I love math, I work really hard at it, but I can rarely look at a problem and instinctively know how to begin solving it.

Frankly, if it weren't for years of teachers forcing me to complete math and chemistry and physics problems using the full problem solving method (which has a name or acronym that I've now forgotten), wherein you identify all the variables, and then go through the list of equations you know and see which ones use those variables, and then which of those equations provides the sort of variable you want as an answer, I would still have no idea how to solve most of the math problems in my everyday life.

So, I think it's pretty clear that a recurring theme in my life involves the struggle of dealing with numbers and conceptual programs involving calculations that comes with being a 'person of letters' in some sense trying to 'fake it' as a 'person of numbers'.

This struggle has reared its ugly head again in the process of learning about recursion for this class.  I feel like recursion itself has been a recurring theme of the lectures since day one, and my confusion with it has been a recurring theme for almost as long.

Looking through my notes, the first two sections on recursion don't really explain what it is or why it's important. They show how to construct at recursive function sum_list using list comprehensions, and although I can grasp that it's supposed to be more efficient than using a for or while loop, I don't really understand how that efficiency is accomplished. What confuses me even more, though, is how you seem to be able to call sum_list within its own body of code. How on earth do you use a function that you're still in the middle of defining?

Next section: "To understand recursion, trace from simple to complex", followed by some more example calls on sum_list. I traced them. Great, now I understand how to use this recursive function, but I still don't know how to write one (This is something I struggled with a lot in the labs---getting a handout that showed the recursive solution for a problem, then asking me to solve the same problem using a simpler loop. How was I ever going to learn to write recursive functions if I didn't get to try it in a supported learning environment? Wouldn't it make more sense to give us the loop solutions and ask us to condense them to recursive ones?)

One week later: Let's forget recursion and talk about exceptions for a while, mmmkay? (How about no.) However, in an aside with regard to assignment one, perhaps the most helpful definition of recursion I encountered in this class--"recursion is all about solving the problem of a given instance by reducing it to the solutions of smaller instances".

The following week, a traced example of the function remove3s blows my mind (and the mind of my fellow confused classmate, who had been puzzling over the same question as me for weeks--how do you call a function inside its own definition?) I feel like i get it now--the function call inside its own body is kind of like a reset button--it takes you back to the top of the code body, and you apply the same process to the smaller instance of the problem (e.g. the inner list in a nested list where the recursive function was first applied to the outer list). Still, I feel like I know how to use these functions now, but would be lost if I ever tried to write one.

The next week, a slide bearing the title "Getting that Recursive Insight for the Tower of Hanoi" strikes fear into my heart. "Insight" sounds a lot list "instinct", which is something I definitely don't have when it comes to recursion and by definition can't be taught. But then we go on to talk about identifying patterns--I can do that, albeit with some struggle--and I see that a function can be recursive and still have if/else statements and a function body longer than one line (at some point, I got in in my head that all recursive functions had to be in the form of list comprehensions, which where often paradoxically incomprehensible to me).

It wasn't until I started studying for the midterm and came across past tests containing problems that required recursive solutions that I realized two things:

1) I know more than I thought I did about recursion, and tracing function calls really does help you to understand how it works, even if it doesn't feel that way at the time.
2) "insight" !=  "instinct";  insight can be learned, and the best way to learn it is to keep doing the same sort of problems, over and over again. After A1 and two practice tests, I was able to pick out which problems in later tests sought recursive solutions, and (despite my earlier misgivings about lack of practice) WRITE THOSE SOLUTIONS.

Following the midterm, in hindsight (and in the course of writing this post), I have discovered a new recurring theme in my academic life--trust the process. Sometimes things you think aren't helping you or teaching you anything new are doing exactly that. Learning the pieces of things can be confusing, but the feeling you get when you're able to put those pieces together is incomparable and incredibly satisfying. (And obviously, gaining recursive insight into a problem is actually a lot like looking for a recurring theme in a novel. Just because I wasn't born a 'person of numbers' doesn't mean that I can't use the skills I do have as a 'person of letters' to solve numerical problems when they show up in front of me.)