Monday, July 20, 2020

The Magic Rule of Computer Programming

A view of my current desktop on my iMac showing Xcode with the iPhone simulator running my current version of Set. Notice the cheat button at the bottom of the phone screen, which was part of the extra credit in Professor Hegarty's assignment. I designed it so that it highlights two cards of a matching triplet, and then you have to pick the third one on your own. It turns out to be a good thing to implement because in testing the game while building it, you have to play it over and over again. If you've played Set you know this is not so easy at all!

When I sat down to do the midterm assignment for the latest Stanford CS193P course on designing iPhone apps--building a game of Set---I knew it would be challenging. I had just listened to Paul Hegarty's lecture on animation programming, and I knew the assignment called for building an app in which cards are dealt out from a deck in animated fashion, flying through the air to land in their right place on a grid of rows and columns.

I figured the parts of the assignment leading up to that step would be fairly easy. I told myself I understood the basics. So for the moment I set aside the animation part and went about building a simple version of the game app in which the cards just appear automatically in their place on the screen, with the correct symbols on them for a game of Set.

Yikes was I ever wrong!

Even this simpler part turned out to be way more challenging than I expected. Normally I wouldn't mind. In the type of programming I usually do for work---building web applications on servers, and also coding how things look in a web browser---I can almost always do what I need to do by a careful step-by-step approach of testing and debugging. In that kind of programming, I know how to get into the nitty gritty and track down whatever is going wrong until I can fix it. It's like being a Canadian Mountie who "always gets his man." It's a system that always works.

But iPhone programming is a whole new ballgame for me. For one thing, to build iPhone apps you have to use Apple's own software, called XCode. Moreover you have to use a special programming language that's new to me, and (most importantly) you have to use special libraries in that language for how things are displayed on the phone screen.

It's this last part that really threw me off.  The logic of the underlying coding is easy for me to understand, but in the end, if it doesn't look and behave right on the screen, it's just bogus, as Professor Hegarty would say.

In this case, when I set out to make the simpler version of the game, it seemed to work at first. But when I had the program deal out more cards, as is supposed to happen during the game, everything was messed up. The grid on the screen reoriented itself to make room for these additional cards, but no new cards actually appeared. There were just blank spaces on the screen where the new cards were supposed to be.

Moreover the cards already on the screen, the ones that got shifted to make room for new ones, were messed up in a way that seemed random. Some were correct, but others weren't the right size anymore, and the symbols inside them stuck out beyond the edges of the card. There didn't seem to be any pattern to why some cards behaved correctly and others didn't. Not good!

It didn't make sense to me. At first I tried to get into the nitty gritty in my usual way, which involves having the program itself print out debugging messages that tell me what's going on at any given point in the program. This is the tried and true way that most programmers do it, and in my usual method of programming, this works in almost every case to track down the issue.

But with the way things are done iPhone programming, and the new graphics libraries from Apple, I couldn't do that. In some places where I wanted to have messages printed out, you aren't even allowed to put in those kinds of statements. Even the ones I was able to put in seemed to indicate that everything was ok, and that my program ought to be working!

It was one of those moments when I questioned whether I had the chops to do this. If I had been enrolled in the Stanford course, I could use the class discussion board to contact the professor, but being a "party crasher" with the free version, I was on my own. Nothing in my deep-dive Google searches or on Reddit helped at all. The material was brand new. I couldn't find anyone else who had even tried to build this assignment yet.

In a way this situation is very liberating. It felt like a throwback to decades ago, before there were dozens of sites on the web with all kinds of answers to common programming issues,. You had to figure things out on your own often from documentation in books, which you had to go buy in Barnes and Noble.

For a few hours, being stuck like this, I went through a range of emotions, most of them bad. I'm not really enrolled in this course, I told myself. There is nothing at stake except my ego and my own resolution to finish this assignment. Maybe I'll just call it a day and move on to the next assignment.

But it would sure be nice to figure it out, I thought. If I could make it work right, then I would really own the knowledge in a deep way, which is exactly what the assignment was supposed to do. Wow, this place Stanford really is great for learning things.

But what to do? Fortunately I had a fallback.  It came to my rescue and saved the day. I call it the Magic Rule of Computer Programming.

The Magic Rule of Computer Programming is not a standard term. You won't find it on the web. It's just something I made up.

In fact I didn't even call it that until just now, because I had to call it something for this blog entry. Nevertheless it's pretty accurate as a term. It's something I discovered years ago that gets me out of 99% of any kind of programming jam like this, where something isn't working and I can't figure out why.

The Magic Rule of Computer Programming comes from the realization that you are never really out of ideas about what to do. You only think you're out of ideas.

In almost every case that I'm stuck like this, and it seems hopeless, I just ask myself this question:

"OK, what's something I could do, to make a change to the program, that might touch on the issue at hand in some peripheral way, but which I don't think will actually do anything to fix the problem?"

Surprisingly it's usually an easy question to answer. There is almost always something one I can try to do, but which I have shunted off in my mind as not the right solution, because it doesn't seem like it would do anything.

So I force myself to try the thing that I think won't work. Most of the time it turns out to be the right thing to do to fix the problem.

On a basic level, it is simply the idea that when you are stuck, do something you can do.

And if that doesn't work, there's often a second obvious thing to do, just like it, that I've already made up my mind as being hopelessly wrong. Ninety-nine percent of the time one of these obviously "wrong" things turns out to fixes the problem.

So in my temporary despair about the iPhone midterm assignment, and having resolved that I would complete the assignment even if it took six months of plugging away, I applied my Magic Rule.

I tried the one thing that I could do, that might change the way the program worked in regard to the display of the missing cards. I expected nothing would happen.

Lo and behold it fixed it! The newly dealt cards began appearing on the screen. Only after it worked did I realize why it had to be the right solution.

Likewise a second application of the Magic Rule cleared up the issue of the symbols sticking out past the edges of the cards.

Woo hoo! I was on a roll. I was going to finish this thing in no time.

This morning I hit yet another despair-inducing dead end and had to fall back on my rule again. It's been a roller coaster experience in the last few days.

Fortunately there is no deadline and when I'm done I think I'd be ready to work in Silicon Valley, although that is definitely not my goal, for many reasons. These days I measure myself by this type of abstract criteria of excellence, which I alone determine.

In programming things tend to balance out, as far as effort. Some things you think will be hard turn out to be easy. To get full regular credit for Hegarty's midterm assignment, his students were allowed to skip making the "swerve" design on the cards in the Set deck, and also to skip making the stripes inside the design (instead using simpler versions of these). One could do those things for extra credit, he said.

Of course I was going to do all the extra credit.  It turns out both of those things was fairly easy, although I'm still working on the right bezier curves for the swerve, as you can see from the image above. At least it doesn't look like a bowtie anymore.

Among other things, I've banned myself from writing to Professor Hegarty until I've finished every last bit of every assignment in the course, including the extra credit. Not until I've mastered the material will I feel worthy of telling him what an awesome course he made. No doubt he would immediately understand the Magic Rule as I've stated it.

Does the Magic Rule apply to real life? It's tempting to think so, but computer programming is not real life. There's no guarantee something will work in real life situations, the way there is with computers, which are always logical. But I think it's a pretty good philosophy to keep in mind.

In any case, at the the rate I'm going, I'll be ready in another day or two to tackle that animation of cards flying out from the deck that I mentioned. I'm sure it will be a piece of cake!



No comments: