Signing off for a second time

And I’ve made it through the course! I don’t feel like I learned as much this semester as I did in CSC165, but the number of lectures I skipped might have something to do with that. And the number of labs I missed (and still need to catch up on) definitely has something to do with that. It’s a shame those were cancelled. They’re the only reason I managed to keep up with the course material. Now there are gaping holes I’ll need to fill in before the exam, though I think reviewing the sorting algorithms and completing option B of the third assignment will take care of most of them.

Assignments taught me a lot. The last one nearly killed me because pruning is really hard, apparently, even though it was described in immense detail and the algorithm was broken down for us on the assignment handout. I think I spent a total of nearly 24 hours struggling with pruning alone, which is kind of ridiculous, but I think I finally (sort of) understand it now. It would be nice to have done more with optimization and sorting algorithms this semester since we’ve really only just scratched the surface, but the amount of time we spent on trees and recursion means we did learn some things thoroughly.

The main thing this course has done for me though is getting me excited about what I’ll be learning next year. Second year should be fun. I’m already really looking forward to it.

Just have to get through finals first. One month til the exam! One month to start studying! This will go splendidly.

Pictures will be your salvation if only you let them try

Looking back, my biggest struggle this semester I think has been with trees and linked lists. But mostly trees, since that’s what the bulk of the course has been addressing.

And it hasn’t even been with trees themselves, because the idea behind them is very simple. It’s my inability to slow down and force myself to draw some pictures before sitting down to code it. Skipping the pictures never works, I always have to go back to them eventually, but I’m always far too stubborn to start with them. The same often happens with math problems – I try to derive a formula off the top of my head even before I’ve gotten confirmation that I have any clue what’s going on. Why? Why do I keep doing this to myself? Why do I keep bashing my head into the wall instead of looking for a door?

Now that I think I finally understand what the pruning technique is asking for on assignment 3, I forbid myself from opening the computer until I have filled up a page with pictures and diagrams and haphazard explanations. This assignment is short and the concepts behind it are simple. I’m not allowed to waste more time struggling with my lack of patience for pen and paper than I need time to actually complete this. It’s the final stretch! Have to make it count.

From what I’ve seen on other people’s SLOGs (particularly here, here, and here), what they struggled most with is recursion, but after that struggle, now realize how incredibly convenient it is. Account for a few base cases, and then have the function call itself until it reaches them. You write comparatively little code given the task you want to accomplish and get some powerful results out of it. Pretty cool stuff (y’know, when you take a few steps back and don’t feel like tearing your hair out over it).

And suddenly, proactivity!

Since Danny went over assignment three in class with us this week, I figured it would be worth my while to take a look at it in advance and see what I could make of it before meeting up with my group. The ideas seem simple (especially since they’ve been broken down so thoroughly for us) and the whole thing seems fairly straightforward, though pruning feels like it’ll be tricky to implement. Myopia, though, sounds a lot like what I’ve heard is used for chess – a few moves are applied to a given game state, and then a simpler algorithm is used to look ahead and try to draw some rough conclusions about how effective those moves were. Except it’s not simple at all, probably, because chess is ridiculously complicated, but it is at the very least faster than taking Minimax all the way would be.

I’m glad we’re finally talking about optimization. In CSC108 last semester, assignment two had us dealing with several very large text files and the run times were very long. That’s when I learned that for loops take a lot of effort to execute and getting rid of a few cut the run time drastically, though it was still by no means fast. It’s nice to be able to build on that small epiphany in a more formal context now.

Test #2, or How I managed to bankrupt approximately half a crowd of imaginary people

And my second round of midterms officially kicked off this week! Here’s a recap of the highlights:

In one corner, weighing in at a few weeks of preparation by Professors Heap and Horton, was test #2 for CSC148. And in the other corner, weighing in at a few hours of studying minus a restless night, was Julia. The two were fairly matched, and the outcome much anticipated. Bets on the winner were evenly split. Tension filled the air. The stakes were high.

The test gave Julia the advantage, making all its moves known ahead of time as she skimmed its pages. She tackled recursion first. A weakness! It was surprisingly similar to what had been given to her in labs, and Julia was prepared. She answered it with ease, taking the test by surprise, and moved on to linked lists. Having become overconfident with her success on the previous question, however, Julia suddenly slipped and forgot to update the size of the list after the element had been removed! Nothing she couldn’t recover from though. Just a scratch, she shook it off and finally took on question one….

And then proceeded to lose all the free marks on that test, because she didn’t write an aid sheet, because she’s an idiot. She lost the match, a lot of people lost their money, and Julia is no longer in the running for a half-decent GPA. Not a good start to a round of midterms that only become progressively harder with each successive match. Sigh.

On errors – ones other than my own, for a change

And assignment two has officially been handed in! This past week was stressful to be sure, but I think I got enough out of it to be able to zoom through the labs I’ve been neglecting and (hopefully) do well on the next test.

There was a lot of talk about using copy.copy versus copy.deepcopy near the end as people were struggling to get minimax to work, none of which I understood since we weren’t making copies of anything at all in our minimax and it seemed to be working fine by then (it took a couple of days, a lot of talking, and a final three hour push the night before the deadline to get it to that point, immediately after which I checked my email only to see that Professor Heap sent out an incredibly detailed breakdown of exactly how he expected us to implement it, which would’ve been absolutely lovely to receive about twelve hours earlier if he could’ve managed it, but what can you do). I only realized what all the fuss was about on Friday. We used a string to represent our board, so when we applied a move to it, simply assigning the new game state the function returned to another variable caused us no trouble because strings are immutable in Python. Other people, however, used lists of lists to represent their boards, which probably made a lot of their code in tippy_game_state much easier to write than ours, but messed them up in minimax. Assigning a list X to a variable Y and manipulating Y will still end up changing X since lists are mutable. The copy module was brought in to help them avoid that mess, but using a shallow copy on a list of lists leaves the inner lists intact, which is where people were running into trouble.

So I’m glad I now understand the mistake, even if it was one I didn’t even give myself the chance to make by doing it the hard way. That’s one source of stress gone.

Only the test remains.

Getting it together (an attempt)

I already wrote a summary of Object Oriented Programming last week, so this week I’m just going to write a progress report (and by progress report I actually mean long list of everything I need to fix if I’m going to pass the second term test).

Recursion had been treating me fairly well until last week’s lab, which I couldn’t even finish because I got stuck (the fact that it had to be cut short as a result of my TA having to leave early for a midterm didn’t help either). I had planned on getting it done over the weekend, but all that time somehow went elsewhere. Now, I am half a lab behind, stuck on minimax, and worried. Wrapping my head around trees has been difficult, and the lack of labs for the next forseeable future certainly isn’t going to help. I’m tired of trees. I want to branch out.

Pictures do help tough, and I’ve noticed that I always put off drawing any until I can’t take it anymore, at which point I suddenly realize that everything is very simple and I could’ve been able to find my solution much more quickly if I hadn’t been so stubborn. So there’s one thing to work on. Chanting “find the base case” to myself like a mantra before trying to deal with the rest of the function also helps. I find I’m too eager to tackle too much at once and end up overwhelmed and not tackling anything at all, so that needs to change.

Things to do to pass the next midterm:

  • Finish last week’s lab
  • Finish assignment 2
    • Get a solid grasp of what’s going on in minimax
    • Seriously, what’s going on with minimax?
  • Complete this week’s lab
  • All the extra lab exercises
  • All the past tests

Now back to that assignment…

OOPS — Object-Oriented Programming (a Summary)

How many times has that joke already been made? Countless, I’m sure. Am I sorry? Not even remotely.

Moving on.

This week, we’ve been asked to write a summary of object-oriented programming concepts, and though I don’t feel equipped to talk about OOP as a whole yet, I can at the very least discuss what we’ve covered so far (which, I suspect, is the expectation).

The bulk of the course has had us focused on classes so far, and while I found them pretty straightforward for the most part, I couldn’t understand for the longest time what they were good for. Why did we have to bother with them? Why do we care? Can’t we just write the functions we need to solve our problem and move on with our lives?

But now I think I understand it a little better. Classes are good for creating a framework that lets you solve a larger spectrum of problems. The parent class is that framework and giving it characteristics for the child classes to inherit and expand upon is that spectrum. Though I’m still a little miffed by the fact that the most useful code the superclass provides tends to be the init method and the extent to which I have to abuse NotImplementedError, it probably has more to do with the nature of the classes we’re writing than with classes as a whole. Overall, I definitely feel like I’m in a better position to appreciate the wide range of opportunities classes give us.

The last few weeks have also been spent on trees, stacks, and queues (which I always spell wrong the first time). Stacks and queues aren’t particularly difficult to use, but I’m still not sure as to why we would ever want to use them. Being able to access items only in a specific order seems like it’s more trouble than it’s worth. Why not just store everything in a list? Everything is a lot more versatile that way. Stacks and queues appear to be marvelously inefficient, but I suppose there’s no way working with them for two hours in one lab period could be enough to fully grasp them.

Trees, on the other hand, are a little less straightforward, and it occurs to me that my factorial function from last week may not have made me an expert on recursion after all (who’d a thunk it?). The lab this week was more challenging than usual, and I have a feeling it’s because I’m not entirely sure how the visual representation of the tree we see on paper gets translated into code. A  closer look at the lab should help with that, though, as should working my way through the extra exercises.

Smoother sailing still

Forcing us to go through the tedious process of tracing recursive functions before letting us write them ourselves was a surprisingly efficient way of getting me to understand how this whole thing works. I’ve heard horror stories about recursion questions coming up on exams and people having to leave them completely blank because “either you know it or you don’t”, but it seems straightforward enough once you get the hang of it. From the little of it that I’ve seen, there appears to be a fairly simple pattern: break your main task down to its simplest operation x, and if you aren’t in a state to do x yet, unravel your input by having the function call itself until you are. Then you just have to put it all together. There’s probably a lot more to recursion than my naive view of it, but that seems to be the general idea.

In last week’s lab, we had to write a couple of recursive functions, and I managed to, but I wasn’t sure if I actually knew what I was doing or if I was just copying what I’d seen from the week before, so I wrote a function to calculate factorials as a quick test:

def factorial(n):
    '''Return the factorial of n.'''
    if n > 1:
        return n * factorial(n-1)
    else:
        return 1

And it works! Clearly I’m an expert now that I’ve managed to write the most basic recursive function in existence, so I’m pretty sure I’m good to go.

Smooth sailing

The first month of the semester is gone and midterms are already here to ruin my life. The next two weeks will be super stressful, but the first three have gone fairly well. I have mixed feelings about how much I’m getting out of the lectures but the labs more than compensate for that. The real learning happens when you actually do instead of sit back and watch.

The material itself has been fairly straightforward so far. Classes and inheritance are a logical extension of what we started in CSC108 and recursion is a little weird, but tracing it is no problem so hopefully that portion of the midterm will be okay. The first assignment was kind of a shock because after being spoon-fed all the functions I needed to write in CSC108, being given only a general idea of what’s required left me lost; my partner and I had no clue where to start. When I first looked at the assignment, I thought “This looks complicated. There’s no way it can be, it almost certainly it isn’t, but it looks complicated.” But then we actually started writing out what we’d need and grouping things together and suddenly it was no trouble at all. I remember once hearing a CS professor at Waterloo say that if he could write something that would shock you if you tried to do an assignment without having written out a partial solution on paper first, he would, and I can see why. Life becomes a lot easier when you break things down. You can’t forget the big picture, but without the smaller parts there’s no picture at all.

So overall, it’s been good. Hopefully the next two weeks go just as smoothly.

Why to write right

… and I’m back for another semester of SLOGs! On this week’s episode of “Julia struggles to keep a blog”, your favourite generic CS student will be writing about writing and why geeks oughta get with this confounded “communication” nonsense.

What I’m about to say about nerds who sit behind computers all day can honestly be said about virtually every human being in existence, though, so really this is about why people in general need to learn to write. Which seems straightforward enough.

People write to express ideas, right? If you have an idea you want to share with someone else, you’re going to need to figure out a clear way to communicate it to them. If you want money for a research grant, you’re going to need to be able to write a convincing proposal to get you that money. Your idea is worthless if you can’t convince someone to give you their money to implement it. If you’ve thought up a cool project and want to assemble a team to get it done, you’re going to need to convince people that you’re worth their energy. Being able to write well lets you persuade people that you aren’t wasting their time, even if you secretly are.

It’s also useful for solving problems. I talk to myself a lot because hearing my thoughts out loud helps me find a hole in my logic. Not being able to explain to myself what I’m doing and why gives me direct proof that I have no idea what’s going on and tells me that I need to go back and reevaluate. Writing serves the same purpose, but with the added bonus of having a record to refer to should you need it in future.

Writing clearly and phrasing things well is also good for telling jokes. Nobody likes someone who constantly fumbles with their punchlines. If nothing else, you’ll make some friends. Not quite as good as a research grant, but I’ve heard they’re all the rage these days. Must be good for something.