2016-03-19 My most interesting mistakes so far

First, a disclaimer of sorts: you might think that I’m blogging like crazy in the hope of winning through sheer volume of posts. Nothing like that. It’s just that I learned a lot, and I wanted to share these things. It makes so much more sense to blog without a week’s delay about what I achieved, especially if I’m swelling with pride;-). (In fact, this very post was mostly written between Wednesday and Friday, and the only reason I didn’t post it yesterday was that I forgot to do it at first, and then suddenly it was too late and I was going to bed.) Do not expect more than 2-3 posts per week on average, even if there are short peaks of two-three posts in a row. I have a life, I have a family, I have a job, and I even have other writing projects.

OK, now back to our normal schedule.

Last time, what I wrote was a bit of a stream of consciousness. As I promised then, I’m going to be a bit more technical today. I mentioned that my app is currently “working” (i.e., it doesn’t crash, and it sometimes draws something), but that was not always the case. The errors I have made were many, but let me share the top three (and a few honorable mentions).

The first runner-up is the fact that I used an ArrayList of objects of type TurtleLine (which were badly named – they are in fact segments) to remember the drawing. Since apparently I have to be able to redraw the whole thing in DrawingView.onDraw, I had to abandon the hope that I’d be able to draw each segment while the turtle moves and promptly forget about it. Turns out, an ArrayList is trivial to use and iterate over – though for some strange reason the thing that iterates over its values is called for and not map or similar. I know, I know, but I couldn’t resist;-).

It seemed a good idea on paper: each turtle movement is recorded (as a line segment), then onDraw draws all these lines and it looks good. Except that it doesn’t – I should have drawn a single line consisting of many segments and not a sequence of one-segment lines. (Can you think of a reason? If not, compare these two diagrams! I guess I could have also mitigated this problem by changing the line ending style, but thiat would be a hack.)

layout-1.png

The second honorable mention is definitely the fact that I messed up analytical geometry. While I feel excused that I didn’t know where the origin was (hint: it’s in the top-left corner, how weird), once I learned that I should have known how to turn left and right, not in the opposite direction… (And that Math.sin and Math.cos want radians, not degrees.) Never mind, that was a bit embarrassing, but easy to fix.

OK, so let’s get to the medalists.

Number three is the initialization (again!): while I did remember to initialize the Turtle object this time, setting its position to (0,0) was not my brightest idea ever. I quickly changed that to (getWidth()/2,getHeight()/2).

Number two is connected with number three: my fix didn’t work. This in fact I do not blame myself for: it is not obvious (though not especially surprising, either) that the width and height of a view are not yet known at the moment its constructor gets called. My temporary and ugly fix was to hardcode them as numbers (until I put out the other fires).

I googled a bit, and it turned out that this is indeed not trivial and quite subtle. I found a solution, and I’ll see whether it works. If not, I can always initialize the turtle’s position to a sentinel value of (NaN,NaN) and fix it right before the first movement. Ugly hack, but should work.

Number one is in fact rather subtle, and I should have thought about it earlier. The only thing that redeems me is that once I put in the debugging statements, and looked at the LogCat, the problem was almost instantly clear to me.

Here is what I had. I defined the classes TurtlePoint (representing a point on the plane), TurtleLine (representing a segment, i.e., a pair of points), and DrawingView (as the descendant of ImageView, owning a Turtle and drawing its trails in onDraw). And this is a small part of the drawing routine:

TurtlePoint oldpos = drawingView.turtle.getPosition();
TurtlePoint newpos = drawingView.turtle.goForward(100);

This seemed correct – drawingView.turtle.getPosition() returned the turtle’s position, goForward was defined to return its position after the movement (forget about the magical constant 100 for now, I’ll make it configurable later!), so everything should be fine, no?

Well no. Remember, these functions return objects. And that means references to objects (pointers, if you will). So all that gets remembered somewhere in the depths of DrawingView is the reference to the object holding the current turtle’s position! In other words, all the lines actually drawn connect the turtle’s current position with itself. No wonder I didn’t see anything on the screen… And here’s the correct version, which creates new points as it goes:

TurtlePoint oldpos = new TurtlePoint(drawingView.turtle.getPosition());
TurtlePoint newpos = new TurtlePoint(drawingView.turtle.goForward(100));

(As you can see, today’s episode was brought to you by the letter “I”, as in “Initialization”.)

OK, enough for today. There are quite a few more things I’d like to write about, but they’ll have to wait a bit.

CategoryEnglish, CategoryBlog, CategoryMakeYourselfKnown