Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Sunday, January 24, 2016

Back to School

I have just started the coursera course Algorithms Part 1.

I half-heartedly tried out the course before. I listened to some of the lectures, I glanced through some of the exercises and programming assignments, and I may have tried to do some quickly (using Python instead of Java). But this time, I am going to give it a good effort and do all of the assignments and try to really complete and pass the course.

On Friday, the course began, and I started watching the videos. After the introduction video, I found it easier to just read the lecture notes and the slides. It was quieter and I felt myself concentrating a little bit more. As things get a bit more complex, I may watch the video, especially when there are demos that don't animate in the slides.

By Saturday, I finished the first round of lectures, and I began looking at the programming assignment. Since it's the first assignment, I've been spending a lot of time getting my environment set up. I tried the recommended IDE called Dr Java, but it felt a bit unpolished. I decided to use Eclipse, which I had to re-install. Eclipse is not as light-weight, but I think it makes things a little easier to do, especially since I am a novice Java programmer.

It's a bit annoying getting all of this started. I wish they had set up an initial pre-class assignment before. Before the class started, I could have tried to set things up, and we could have had a simple HelloWorld style project where I could iron out the process of creating files and submitting them. Oh well, once I get this working right, hopefully it won't be so bad in subsequent weeks.

Ok, time for breakfast, and then I will go ahead and give the first week's programming assignment a try.

Tuesday, January 12, 2016

Bugs at Work Messing with My Head

I was debugging an issue yesterday, but I could not fix it.

From the start, I knew the problem failed in an API call written by some other team. I traced through the unfamiliar code stack and determined the problem was that I couldn't write to a given database. But the settings on the machine indicated otherwise. So, it took me all day, and I was still stuck.

Because I couldn't perform at work, I was in a bad mood.

Apologies to my wife. The bug screwed me up.

Update
I subsequently found out that the problem was a deprecated API that was no longer supported in my test environment. It was as if I was trying to figure out why a webpage was rendering poorly on Internet Explorer 6 on a Windows NT machine.

After I discovered this, it just didn't make any sense to try to fix this problem anymore. So, that put an end to my debugging. All in, about 7 hours wasted, but now I could at least move on.

Tuesday, December 1, 2015

Schooled

Learning is a process for me.

When I initially hear of a new concept, my reaction could be any of the following: surprise, awe, doubt, indifference, etc ... Regardless of the initial response, I typically don't have a real firm grasp of the concept just yet (even if I think I do). If I try to use the concept, it would be mostly hand-wavy, simplistic or clumsy.

That's where most new concepts mostly end for me. I am vaguely familiar but I don't really have a good grasp of it.

But sometimes, the concept is prevalent and it comes back to me. So I read about it or hear about it again, either actively or passively. I start to see some interesting subtlelties that I didn't initally realize. I come to appreciate the concept more and more. Because I have a better idea about it, I become comfortable and use it regularly. And befoe I know it, I begin telling others why I think this concept is interesting and useful.

In the world of programming, there are lots of concepts. Some of them have taken me a long while to learn. Here are a couple examples of things that have taken me a while to learn: Object Oriented Programming, Agile developement, and Unit Testing. For each of these, I thought I understood the concept pretty early on. But as I look back, I can see that I had a lot to learn about each and that I've slowly become better at each of them.

For me, learning is a process. It requires listening and reading, doing and teaching. It needs repeated attempts spaced out over time. Oddly, it often requires me to do other things for a while, so that I can see the concept in different lights.

So, learning can take some time. Lucky for me, I like learning. It's one of the best things about being a programmer. I'm always being schooled.

Sunday, February 8, 2015

Build something new every time

When you work on a project, think, "How can I create something so that I never have to re-write this same program again?"

For example, say you are asked to setup a process that retrieves a file from a ftp site, reads the file and updates a database. Instead of writing something that just does the job, you should try to write a generic ftp retriever, a generic file reader, and a generic database updater.

Then you data-drive every piece of the process to deliver a solution for this specific problem. When you need to work on a new (yet similar) project in the future, you just have to change the configuration and data-drive your next process.

If you follow this practice, things may initially take longer to get done. It's much harder to write generic code. It's possible that you'll never reuse this generic code again, which means you wasted your time. But I think it's more likely that if you needed to do something once, you'll need to do it again.

So, you may or may not be more productive. But I think you'd in general be happier, because writing new programs is good for you. It will force you to think and learn. You won't get bored by the tedium of doing the same thing over and over and over again ...

I guess what I am getting at is simplay another way of saying keep things DRY, and save your key strokes for something new.

Sunday, December 14, 2014

Trying out HackerRank

For the last two weekends, I have been working on problems from HackerRank. HackerRank is a site where you can solve programming puzzles. The challenges require writing a program that ingests some input test cases and returns an answer.

The problems often require understanding some fundamental programming concepts (like traversing trees or choosing the correct data structure). I am hoping that over time it will make me a better programmer.

Even for problems that seem relatively easy to solve, there are often some test inputs that are designed to stress the system. For example, on one problem, I wrote a recursive function to do some work. This worked fine for the sample test cases, but they eventually failed when the data inputs got very large. In order to handle all of the test cases, I had to refactor the code away from the nice, clean, recursive version to something a bit more messier.

Monday, September 29, 2014

A debugging story


Today, I was helping a coworker fix a bug.

At first glance, it didn't seem as if it would be too hard to fix.

The problem was easily reproducible. Sometimes reproducing a bug depends on rare race conditions or odd work environments. The bug we had appeared every time you did a certain sequence of steps. So, we were off to a good start.

I was able to find (and run) a version of the code where the bug didn't exist. So I knew, that somewhere along the way, some discrete code change created this bug. Maybe, all I'd have to do do was go through the list of changes until I found the nefarious one.

This is where things got difficult. Even though I had an old bug-free version and a new buggy version, there were too many changes between then and now. Running a diff between the two version was useless. I tried to undo half of the changes, to try to narrow down where the bug first crept in.
That didn't work so well, as the project failed to build due to all sorts of incompatibilities.

It was like searching for that proverbial needle in a haystack. I felt like I was on a wild goose chase. Everywhere I turned, it was another dead-end.

In the end, I never found the bug. My co-worker ended up figuring it out, before I could.

Even though I didn't find the bug or check in any code, I think it was still a worthwhile experience. I got to think deeply and learn about a piece of code that is related to things I work on. It's always good to have more code-context and knowledge.

I also spent a good deal of time thinking and being confused over some javascript language details. In particular, I thought the cause of our bug was that the code depended on a 'for loop' iterating over a javascript object in a particular order. As it turns out, this was a safe assumption, and not the cause of our bug.

My takeaway from this is the following: if you want an ordered list (when all else is equal), use an array instead of a javascript object. Both may work, but an array has a more intuitive order. Most people wouldn't question the order of an array, and wouldn't waste time trying to verify that iterating over an array in a specific order works or not. Just because the computer (and other language experts) will interpret something correctly does not mean it is the best way to code. Writing code that the average programmer can understand is almost always better.

All in all, this debugging session is typical of many debugging sessions. It's never as easy or as hard as you expect. The bug is often not where you expect it to be. You often feel like you wasted a lot of time.

But if all goes well, you have improved your code base and learned something along the way.

Sunday, July 27, 2014

Meanio version 0.4.0 does not work

I tried to upgrade to the new version of Mean.io, version 0.4.0. As of this writing, it has been a complete failure.

I began by trying to upgrade one of my existing applications. Since I did not touch any of the core components provided by Mean, I hoped the upgrade would be easy. 

Using git, I pulled in the latest code. I had to do some manual merging, but it looked pretty straightforward, so I still felt optimistic. I then used npm install to install everything. Then I ran grunt to start the server. No errors were given, so things were looking good.

However, when I try to open the web app on my local host, it stalls and I don't see anything happening. I spent a millisecond trying to debug what the problem was, but I realized I'd never make any progress. There were too many diffs due to the upgrade. And I wasn't going to spend time trying to figure things out. 

Instead, I tried to install a fresh new mean app. I used the basic commands:
  sudo npm install -g meanio
  mean init Mean.init.demo
  npm install

I got a slew of errors, and I gave up.

It's probably something I did. It almost always is. 
Maybe I should work harder to debug this, but I thought the framework was supposed to make my life easier. 
I'll try again next week. Onto something else.

Update
Following the debugging steps in http://enginx.com/blog/mean-io-v0-4-released-stay-synced/ , I was able to get my app using Mean 0.4.0 to work. 

Tuesday, July 22, 2014

Understanding the Mean JS Stack

I began working with the MEAN.io javascript framework, but due to my ignorance on many fronts, I couldn't quite see how it all worked.

I was trying to figure out how it worked by reading the generated code; experimenting with small code changes to see the effects; and reading documentation from MEAN.io and questions from stack overflow. This didn't get me very far. I was either too deep in the code or too far above in the high level overviews.

The best learning tool for me was this youtube tutorial by Michael Moser. He went through each of the components of a MEAN stack application.

I'm finally starting to get it, I think. Here are two things that I'm starting to see.

Communication between the client and the server is done via http verbs. In your client side angular controller, you can do a few operations with your model like $get, $save, $remove and $update. These correspond to http verbs like get, put, delete, update and so on. It seems so simple now. My misconception was that I could define functions with my own keywords and I'd have to keep this in sync between the client and server.

The node package manager is only used on the server. This means, "npm install whatever" allows you to write
    var whatever = require('whatever');
in server side code. It doesn't work on the client (I think). This again makes sense now that I realized it. Node is your server, so you wouldn't install server side modules onto a client.

Working with new technologies is painful. But things are easier with youtube, tutorials, Q&A sites. After you become an experiment in something it is hard to remember how you felt when you were a newbie and what you didn't quite grok before.

This blog entry is just a reminder to my future self of how little I once understand.

Saturday, June 28, 2014

Using ack

While developing my first MEAN.io app, I've found that I need to use grep alot.

The MEAN framework creates lots of files in separate directories. When you have a complicated project that uses a lot of modules and custom packages, keeping things organized is a necessity. However, as a newcomer, I am having a lot of trouble finding code.

To help alleviate the pain of tracking down code within the MEAN framework, I started using ack, which is supposed to be a version of grep that is optimized for programmers. I wonder how many non-programmers use grep? Anyway, here are a few optimizations that I noticed:
  • It defaults to recursive searching (very important for frameworks that bury files in folders).
    So you use ack instead of grep -r .
  • Results are returned with the search phrase highlighted in colors. However, if you try to pipe your ack results into another unix command like less, you'll lose that formatting.
  • Syntax for adding custom flags seems more intuitive.
    Ex: searching for the word "debugger" in js files can be done like this:
    ack debugger --type=js
While ack certainly seems better than grep, I'm reluctant to completely abandon grep. Many times I need to log onto a bare-bones machine where ack might not be installed. On many of those machines, I don't even have access to the other flavors of grep like egrep or fgrep. In those cases, I'd have to remember how to use plain old vanilla grep again.

Friday, June 27, 2014

Mean packages are magic to me

I've been playing around with a Mean.io app for a few days now.

Working within a framework has had its advantages. For example, to set up a new model/view/controller package, I just entered this 1-liner command:

    mean package feeds

This created a nicely structured set of files that just worked. In the main menu of the app, a link is added which you can follow to discover how this new package works.

I wanted to understand how the framework was able to create a new package and how it was connected to the rest of the app, so I started diving into the code. Unfortunately, I couldn't figure it out. I'd account my inability to understand what is going on under the covers to a few factors: 1) I don't have and didn't spend enough time reading. 2) I'm a beginner to this style of Javascript coding. 3) Frameworks try to hide stuff from developers.

I should elaborate on that last point. Frameworks are not evil. Their goal is to abstract away difficult, messy, confusing parts of the code, so that you don't have to re-write or reconfigure those nasty parts. A side effect of this abstraction is that you may be left wondering, how does this all work? (as i am now).

As Arthur C. Clarke said, "Any sufficiently advanced technology is indistinguishable from magic." A lot of the MEAN framework is still magic for me. For now, I'll continue to rely on this magic, continue coding, and come back to it later when some of the magic starts wearing off.

Friday, June 20, 2014

Early reflections on MEAN framework

A few days ago, I initialized my first MEAN.io app.

It's fair to say that I'm a complete new comer to this style of programming. As a newcomer, I'd like to document what I think MEAN is, how it works and my overall impression on it. I'm sure there will be many misconceptions and inaccuracies. Over time, it will be funny to reflect on how lost I once was.

So MEAN is built on top of NodeJS. NodeJS is a server where you can write Javascript code. Why does it matter that you can write Javascript on the server side? The key point is that you program things such that everything is event-driven and everything has a call back.

For a developer like me, this makes the code look a bit gnarly. Instead of executing code in a linear path that matches the code in your text file, different functions are fired off as needed when things are ready.

Of course, the benefit of having event-driven code with callbacks is that the server keeps the UI thread free and clear as much as possible. This makes the application super-responsive. So, making things a bit harder for the developer, but nicer for the user is a good tradeoff.

Now on top of this event-driven server (NodeJS) MEAN uses ExpressJS. I have read that this is a web-framework. Since I'm not a web programmer, this is the component in MEAN that I am most unsure about. For now, I think of it as the plumbing or middle man that helps send messages between the UI screens and the backend server and databases. Is that a correct notion? I'm not sure. Like I said, this feels a little abstract to me.

So, I'll move on to the component I understand the best. MongoDB is a NoSQL database. You insert data and retrieve data as json objects, while they are stored in some binary format. Why is it json? I'm not sure, but it certainly fits into the idea of having this framework be javascript from top to bottom.

One of the nice things about NoSQL databases like Mongo is that you can easily add data to collections without a lot of painful schema designing. Any old json object is ok. The downside is that you can throw anything in, and that leaves model validation up to you.

And the final part of the MEAN.io web framework is AngularJS. AngularJS is a "new" way to do HTML and UI. So far, I've come across at least two new things that AngularJs adds to an HTML web page. Data binding allows you to use a variable directly in HTML code. (I think). Dependency Injection allows you to swap in different dependencies (pieces of code as needed). Did I define those correctly? What are the benefits to these things? I don't know.

I have a feeling that I not only said some dumb things, but that I will inevitably program some dumb things in the near future. Hopefully, I learn and can appreciate all of the magic that occurs within the MEAN framework.

If you are new to MEAN or to programming in general, take heart that your feeling of being lost is shared by me.

Tuesday, February 18, 2014

Frankenstein coding

These days, you can program and create real life applications via a Frankenstein approach.
  1. Start with a tutorial that creates a basic "Hello World" application.
  2. Think of a feature to add. 
  3. Google "How do I do 'X' in 'Y'?
  4. Cut and paste found code into your app.
Over time, you will eventually assemble an unique application that is a collection of copied bits.

Is it wrong to program like this? I don't know. I do feel that it is ugly, smelly and hacky (in a bad way). 

This is unfortunately how I have been programming my latest web app. HTML and CSS are new to me, yet they are both very human-readable. So I've gotten by, by just searching for what I think I want (give me a table or a new section) and then Frankenstein'ing it into my app. 

I am not proud of my Frankenstein-ing behavior. To stop it, I have started learning HTML and CSS with codecademy

After I've learned HTML and CSS, I will probably look back and think that I was a lousy programmer for cutting and pasting so much. I hope that my future self is a vastly superior programmer to my present day self. 

Yet, it's important to recognize that cutting and pasting is an important part of programming. Sometimes, you need to copy something in order to get something to work. You can go back and try to grok it fully later. 

Disclaimer: I'm not sure where plagiarism starts and ends when talking about code. I do not support passing off someone else's work as your own, but learning from others is ok. I think this is another separate debate. In the grey areas, to be safe, you should at least do these things: 1. ask for permission from the original author, 2. give proper attribution. 

Saturday, February 15, 2014

Commenter's Block

I have been thinking about comments today (the kind that you add to code, not to blogs). Adding comments to code is one of the first things we are taught to do, but I realized that it isn't that simple to do well.

I recently asked a co-worker to review a change I made. He replied,
"Each individual change looks fine, but there's a lot about the code that I don't really understand. Can you add some comments?"

I replied,
"Sure, the code is a bit gnarly and complex. Instead of me guessing what you think is unclear, can you quickly point out what spots need comments?" We use a nice tool for code reviews that makes asking for updates really easy.

He replied,
"You know what, I'll just accept your change for now. It's too hard for me to figure out what really requires a comment and what doesn't. Maybe we should chat about it later."

So, I've checked in the code and started rolling it out, without additional comments, but I wish I had a better idea of what's the BEST practice for adding comments? I don't have a complete guide in my head, but here are some random thoughts on the subject.

/* @author = Me, 
    @name=file.h */
I don't understand these types of comments. The author will change over time and there may be multiple ones with different levels of contributions. The file name is often obvious.

/* 
 * 
 * This is the start of the next section.
 *  
 */
When you are dealing with big files, this sort of comment can be pretty helpful for the sake of readability.

/* WARNING - This part of the code may not work during day-light savings */
This warning type of comment is pretty useful. If you see a bug, it should help you figure out what part of the code needs changing. I also feel more comfortable changing code that I know is already buggy and hacky. It's already broken, so there's nothing to lose!

/* TODO: Update this code after database change is made. */
In the interest of always be shipping, I often add this type of comment. Similar to the warning type of comment, this one tells you what part of the code should probably be updated next.

git log
I've started using git more and more, and I think the comments that exist as commit messages are often the most useful. They often tell you why a change was made, which is nice. A more powerful feature is that commit messages are dated, and if you know when your bug first appeared this can help.

/* TODO: add more good and bad types of comments to this post. */

Wednesday, February 12, 2014

Debugging


One of my favorite things about computer programming is debugging. For what it's worth, I also like vacuuming my apartment.

To be clear, debugging can be painful, annoying and stressful. But when you make a breakthrough and have that Aha moment, debugging a problem is very gratifying. I used to think of myself as a scientist. Maybe I was a bad one, but debugging programs has given me a lot more "Eureka! Oh, I see" moments than I ever had during my years as a scientist.

Another cool thing about debugging is the clear end-point. You start with a broken program or feature, and then you are done when the bug is fixed. I like ending the day certain that I did something worthwhile. I think this is one of the reasons why test-driven development is popular. You create the bug first, and then develop something that squashes those bugs.

When you debug, you learn. When I'm writing new code, I'm mostly trying to organize my own thoughts in a way that agrees with the compiler. When I'm debugging my code, I have to think hard about something I probably didn't understand before. If I'm debugging someone else's code (or some old code of my own), I have to understand what someone else was thinking.

For some people, they only want to work on building something from the ground up that is completely new. I like improving something now and knowing that I can keep on improving it later.

Bugs increase your technical debt.
Embrace removing all bugs from your code so that you can be debt free.

Tuesday, February 4, 2014

Gloomy programmer


Lately, I've been feeling depressed. I think it's about my work, but I'm not sure. Below are three somber stories that are in my head. I am hoping that blogging about it will help me clear it from my memory, and I can start thinking about other happier things.

The cartographer

(this is based on a short story I read about 10 years ago. I cannot find any reference to it). There was a man and his wife.  The man was a good man, and he loved his wife. He wanted to provide for his wife, and he found a job as a cartographer. In those days, a cartographer made maps by physically going to uncharted territories. In the beginning, he found the constant travel tiring and he missed his wife. He wrote letters to his wife and went home to visit as often as he could. Over time, without realizing how, he felt more and more comfortable away from home and his wife. Eventually, he wrote to his wife telling her that he would remain on the road and that he would never return home.

A pair of dogs

(this is based on something someone told me). There was a farmer. He had two dogs; a boy and a girl. The dogs would spend some of the day with the farmer, but would often go somewhere on their own. One day, the dogs returned from their adventure and the farmer saw that the dogs didn't have an appetite. This happened for two straight days, and the farmer became worried. The next morning, the farmer found one of the dogs dead. The next day, the other dog died.

A programmer

(this is my story) For the last year, I've been building and nurturing a project. It started as my own small seedling idea. I was overjoyed when I had a proof of concept to demo. It grew to be a major feature that everyone was excited about. Lots of people had opinions on what should be done next. There were so many discussions that everyone stopped working. The project is now suspended; pending UI reviews, business planning, etc... I am now working on some other project, and I have a hard time understanding why.

Sunday, February 2, 2014

Always be shipping - onward and upward

It's been said before (by smarter people than me), and it'll be said again. In any case, I feel like blogging about it today, and so it's the subject of this post -- Always Be Shipping.

When I say 'Always Be Shipping', I mean that code should always be moving forward. Code can be in a lot of stages.

At the lowest stage, it's just an idea in my mind.
'I think our app should provide some calculations for the user'.

Then, it might just be a "TODO:" with pseudo code in the real code.  Example,
// TODO:
// loop through item list here
//   for each item hook up to new api 
// return new amazing data

The pseudo code eventually becomes real compiled/interpreted functioning code that you can test on your development machine.
Woohoo - it works on my machine!

If it's working on your machine, you should start rolling the code out. Even in my hobby projects, I have a few levels of roll out. For Android apps, I have:

  • I start with the Emulator.
  • Then I have a test android device.
  • Next, is my actual phone that I use on a day to day basis. 
  • Then I can enable for some alpha testers. 
  • Then I can slowly roll out to some percentage of users. 
  • Then I can roll out to all users. 

If you find yourself stalling at any point of this process, you should figure out why, and then push forward.

If you have lots of ideas and you never get around to coding them up, then you need to get focused and implement one idea.  A functioning piece of code is better than lots of theoretical brainstorming ideas. Every great product had a 0.1 version. Go ahead and write the 0.1 version so you can start on the 0.2 version sooner. Otherwise, you will find yourself at 0 for a while.

If you have a functioning version of your code, but haven't released it to the world, you should ask yourself why. Are you afraid of bad client feedback?  Get a friend to try out the change and get their opinion.

Are you afraid of performance issues? That's good, but don't just sit and worry. Figure out a way to quickly turn off your change if needed. If things go awry, you can get back to a steady state easily. Even if things go bad, at least you have identified a real problem that needs to be fixed. The alternative is that you are optimizing for doomsday scenarios that never occur. In the future, you can use this mechanism (of quickly turning off a change) so you aren't stalled in the future.

For most software development these days, shipping code is something you should do early and often. This is true for other things. For example, when blogging, I try to tell myself -- Always be publishing. It's easy for me to write half a blog post, get tired, and leave it unpublished as a draft. It would be nice if all our code and blog posts were perfect before shipping/publishing, but then we'd never ship anything.

So - stop reading and start shipping.

Tuesday, January 21, 2014

Wasted time

In the ideal world, programming looks something like this:
Go to my desk. 
Tap on the keyboard to wake up my computer. 
Write code. 
Save and commit. 
Push code out to the world. 

Today wasn't one of those days. 

My work day was lost to meetings.  I listened to others debate the future of our product.  In the end, I wasn't even sure what the debate was over; thus, there wasn't a good resolution.  It was a waste of time. 

I then got home where I wanted to work on my Android app.  Since this is a one man hobby project, there were no meetings to attend.  I've been working on this for the last few days, so I had a good idea of what I wanted to complete today.  However, for some reason, when I plugged my phone into my computer, there was no connection.  I finally figured out that the usb cord just stopped working.  Not sure what happened there. 

To summarize, during the day, I didn't have time to write code because humans/coworkers couldn't come to an agreement quickly.  At night, I couldn't work because I couldn't connect my laptop to my phone.

Every day I wake up and hope to be productive.  Some days, like today, things arise which reduce your productivity to 0.  That's it. 

Wednesday, December 11, 2013

Hardware is hard

The wife and I started working on a robot.  We are trying to follow the tutorial at Let's make Robots.  I have found that working with hardware is hard.

As with many things, the hardest part is that I don't have the basic skills or knowledge.  For example, soldering looks like the basic building block of putting electronic components together.  For a regular software developer, it is akin to editing text.  If you can't solder, then you can't build any electronics, and I didn't know how to solder.  When you don't know what to do, how to do it, or why it should be done, making progress is hard.

In the hardware world, everything costs something.  In the software world, once you have a computer and an internet connection, there are tons of free languages and tools to build real world applications.  If you have been building robots for a while, you may have a collection of unused supplies.  But for me, a beginner, I had to buy a lot of stuff, from wires to soldering tips and of course batteries.

It is not easy to undo a change.  If you break something, you might need to buy a new one.  This makes tinkering a little bit scary.  For now, I don't have a good means of debugging a problem or testing a change.  It will take a combination of increased knowledge and maybe some new tools (like a volt or current meter) to really be able to debug problems.

This experience reminds me of being a physics student.  In class, we solved problems and the math worked out perfectly.  Then, we tried to measure things in lab, and all the answers were just a bit off.  The hardware world is much less forgiving, but I hope that going through the trouble of working with hardware will have some benefits.  I hope to have a greater appreciation for all hardware, and I hope it helps me be a better software developer.

Sunday, August 11, 2013

When code reviews become painful

Code reviews are good, see for example http://www.codinghorror.com/blog/2006/01/code-reviews-just-do-it.html.  This is not new.  In fact, I have experienced all of the benefits that come with code reviews.  They've helped me identify bugs, learn new ways to do things, learn what my coworkers are working on and all ... Overall, code reviews make the world a better place.

This past week, I found myself saying, "I hate code reviews".  I said it under by breath to myself so no one could hear it, but I said it nonetheless.  Here are two gripes I had with code reviews and some thoughts on improving the process.

Code reviews can lead to flame wars.  
My co-workers are great, and I have learnt a lot from them - yet, we all differ in the way we code.  The most frustrating code reviews are the ones where everyone agrees that the code works, but changes are needed for other reasons.  Maybe the reviewer thinks that the code goes against some best practices guidelines, the code will have some future maintenance issue or that the code is just unclear at first glance.   What do you do if the reviewer says, "Yes, your code works, but I would have done it this way."  Here are some things I thought of:

  1. Make your reviewer do some work.  If your reviewer critiques a piece of code, I think it is fair to ask for a suggestion on what they think should be done.  After a concrete suggestion is made, you can either implement the change or say why you don't think the suggested method is better.  If it isn't too clunky, a comment can be added with the alternative coding route.  
  2. Limit the number of time a change of code is discussed.  Unless there is a miscommunication, it should be possible to present all arguments for and against a change in two rounds of reviews.  After that point, I think the reviewer should accept the change or pass the code to someone else for review.  
  3. Don't get code reviews from your direct manager.  They have too much authority.  Their suggestions aren't suggestions, they become orders.  

Code reviews break my workflow. 
Waiting for my code to be reviewed takes time and breaks my workflow.  This is in contrast to great modern tools like automatic/continuous building and testing.  Immediate feedback increases productivity and delayed feedback is frustrating.

  1. When giving estimates for delivering an update, set aside another 2-3 days (calendar time) for each code change.  This will give you buffer time and will reduce stress and frustration.
  2. Make sure that you have a very realistic development and or alpha environment for testing where you can release code to before a code review is complete.  If you have an alpha environment, you can continue with the deployment process and ensure that if your change is accepted, you won't discover bugs later on when you are rolling the code out.  If the code review has a delay, you might find and fix bugs before the code review has even occurred.

Monday, August 5, 2013

Searching for a needle in a hay stack

I have a lot of faith in modern search engines.  If I want something to eat, need directions, or want to learn something, Googling for the answer will amazingly give me the answer.

But today I had some trouble finding some information.  I wanted to know how to construct a query for a google appengine app that would search over a group of values.  In SQL, the query would look something like:
select * from mytable
where field IN ('someDataToMatch', 'anotherGoodValue', 'and so on');


I figured that the syntax would be similar, but googling for something like
"Google appengine datastore query IN"

sent me in the general direction of where my answer was, but it didn't give me the answer.  The problem of course is that "IN" is a very common word and it doesn't really give the search engine much to work with.  As an aside and for future self reference, the answer I was looking for is here: https://developers.google.com/appengine/docs/python/ndb/queries#neq_and_in.

I imagine that Google and others are working on improving searching and probably have lots of great things that they are building and testing, but here a couple quick thoughts on improving search:
  1. Allow users to opt-in to a program where Google or any other search engine can essentially spy on you.  If a search engine knew that I was a software developer, who has been working on a google appengine project for the past few days, has spent some time going through a few tutorials, and reading stackoverflow questions about google's datastore, I would hope that they would have a better chance at helping me find the page that I want.  
  2. I need a browser extension that monitors all of the pages I look through after I start searching for something.  If I find the answer I am looking for, I can hit a button that says "I'm done".  I think this will be the only way to map search terms to pages that are good hits for me. 
I guess I think that improving internet search will be similar to the future of medicine - personalized just for me.