Sunday, December 29, 2013

SOLID principles

As a software developer, there is always something new to learn.  There's always a new hot language to learn, framework to apply or tool to try.

For anyone who doesn't have a formal education in computer science, like myself, there's also a lot of old concepts to learn.  Importantly, you should prioritize learning these old gems before filling your head with the newest trend.

The old stuff has stood the test of time, so it's probably been useful somewhere.  And if it's been used, it's also been criticized; so you can learn from that too.

Even if the old concept is fatally flawed, they are part of the lexicon and of the computer science knowledge base.  Someone might refer to these concepts in describing a new concept.  So, being unaware of the past may make it harder to keep up with the future. 

The last few days I have been reading about SOLID.  This qualifies as an 'old' concept (or concepts).  It's an acronym for the "first five principles" of object oriented design.  Basically, when you are writing code, it should follow these principles, and if you don't, you better have a good reason why you are not. 

There isn't much I could add to the discussion that hasn't been discussed thoroughly.  But for my own sake, I thought I'd define each of them again in my words.

S - Single responsibility.

Make sure your classes are responsible for one thing and only one thing.  You want modular components, not a single "God" object that can do everything.  The primary benefit of this is encapsulation.

O - Open / Closed Principle

Write code that is open for extension, but closed from modification.  When you are adding features, you want to write new code, and not have to modify old stuff.

L - Liskov Substitution Principle

I don't like the name of this principle.  'Liskov' doesn't mean anything to me.  It really should be called the 'Substitution principle'.  Anyway ...

Wherever you using a base class, you should be able to substitute a derived class.  Make sure your derived class D "IS-A" subtype of base class B.  Because your public interface will depend on virtual methods, make sure your derived class D behaves like a base class B, except

I - Interface segregation Principle

It's better to set up lots of client specific interfaces than just a few general interfaces.  Fat interfaces will have lots of unintended dependencies.

D - Dependency Inversion Principle

The name of this principle is confusing too.  It sounds like I should should invert or reverse the direction in which modules depend on one another.  But what if I had the dependency relationships correct in the first place?

In any case, I think the point of this principle is that all concrete classes should depend on abstract ones.  Say you have some object and you want to save its data to a database.  You should have the object depend on some abstract database writer.  When you want to change the way you write to a database, you can modify the database writer and not have to modify the object.

SOLID

So, those are the solid principles.  You can get by as a programmer without actually knowing of these principles.  But it makes a lot of sense for any programmer to spend some time becoming familiar with these concepts and terms.  It helps when you are designing your classes and it helps when you want to communicate with fellow programmers.  

Saturday, December 28, 2013

Osprey Talon 44

For Christmas 2013, I got a new backpack, the Osprey Talon 44 Backpack.


I've always wanted a backpacking backpack; so I'm pretty happy with the gift.

I got it because it is light. I plan on using it for hiking, bike riding, and any other travel in general.

It should be durable enough for me. It has a lifetime guarantee, but unless it falls apart soon, I'll probably never ask Osprey to live up to the guarantee. It would be cool to pass this along to a kid or nephew one day. I could tell them about all the cool places I've gone to with this bag.

My wife and I have our next trip planned. We'll be doing some hiking on the Inca Trail to Machu Picchu. I'll report on how it holds up.

Update 1

Pro: It is a great size for the Machu Picchu hike. It very comfortably holds your rain gear, liquids, snacks, cameras, sun-screen, etc ...

Update 2

Con: It is not water-proof. You should invest in a cover to make it water proof.

Update 3

Con: When it is full, the upper compartment works great and everything is secure. When the bag is partially full, things sag in odd ways, and it feels like the bag is partially exposed and open on top.

Update 4

The top of the bag is opened and closed with a cordlock. I find it very difficult to use. I accidentally pulled the drawstring out of the lock and it was extremely difficult to reinsert. I found a pen cap to be the best tool for shoving it back in.

Friday, December 13, 2013

Rating my reading

I got an email from Pocket today.  Pocket is an app that I use to read articles.  Today, they sent me a report of how many words I read in the last year.  My stats are here.  So far, in 2013, which isn't over yet, I have read 748,610 words.

I don't know how this number is calculated.  Do they know if I opened an article and closed it before finishing?  What if I opened an article more than once?  In the end it doesn't matter.  .75 million words is my new benchmark.

More than the absolute number, the more interesting part of the given statistics was that I was in the 95% percentile of users.  This means, I read more than what 95% other users read.  So this tells me something interesting.

Over time, I'd like to see how much I've been reading versus myself.  Maybe after some life events, like if I have kids, I will see a huge drop off in reading.  Maybe nothing will change over time.

It felt good to get this report.  I think reading is worthwhile (so does this guy), and it's encouraging to hear that I've done a lot of it.  Maybe I'm vain, but statistics about oneself are interesting.  It's one of the reasons I started building the app usage monitor.

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.

Wednesday, December 4, 2013

Motivation

I experienced a few things yesterday and they all led me to the same thought.  I'll note them here, and you can try to guess what feeling I had after each one.
  1. I played in a basketball game where my team was completely annihilated.  It was like the NBA vs the pee wee league.  We were totally outclassed.
  2. I was looking over some old code that fumbled through a few actions: unzip files, delete a subset of them, re-zip remaining files and then move them to another directory.
    After some thought, and reading through 'man zip' and 'man find', I replaced garbled nested code with a few clean unix one-liners.    
  3. I found out that an old buddy of mine had started his own company in a field that he has loved since we were kids.  
If it wasn't apparent to you, I'll tell you now. The feeling I had after each of these events was motivation (or maybe ambition).

After losing my basketball game, I felt that I had to get back into shape and practicing regularly.  After finding out a cool solution to a coding problem, I had a revitalized feeling to continue studying and reading to uncover cool solutions.  Finally, after hearing about my friend, along with being very happy for him, I also felt motivated to do more with my life.  

Yesterday, no matter what happened, I felt motivated.  It is similar to that old Tootsie roll commercial, "Whatever it is I think I see, becomes a Tootsie Roll to me".  I was drawing motivational fuel from whatever I was seeing or experiencing.  Let's hope I can keep putting it into action. 

Saturday, November 30, 2013

Syncing data - from android client to cloud

I finally set up all the components for syncing data from my android client to the cloud.

  • With Google App Engine, I can store backed-up data in the cloud and allow users to see different views of their data via a web browser.
  • With the Cloud Endpoints Api, I can securely send data from my android client to my Google App Engine app.
  • In my android client, I imported the Endpoints library code to send data to the cloud.

Now that I got all of my pieces working for data syncing, I should be done, right?  Actually, there's still a lot of work needed to set up the syncing for real Android users.  When should I send data?  Once a day? Once an hour?  How can I make it easy for users to customize how their app is synced?

Making the wrong decisions on syncing data can have a lot of adverse effects.  This may lead to problems on my Android app, my AppEngine app, and/or both.  Luckily, someone else realized that syncing is a critical issue and spent time working on some general solutions to this problem.


I haven't had a chance to read through it all, but hopefully I can adjust my code to work with this sync-adapter framework.  Even if it doesn't work with what I have now, I'm sure I'll learn some important concepts that will help me make a good syncing solution.

Sunday, October 27, 2013

Google Chromecast

I have a Blu-ray/DVD player from Samsung, and it works fine for playing dvds or blu-ray disks.  Additionally, it has a few apps, like Netflix, to play videos over the internet.  Unfortunately, using this blu-ray player to watch anything on the internet is *not* a good experience.
  • It is very hard to search for a movie, because there isn't a keyboard.  You have to use the remote and direction arrows to type in a movie title. 
  • Just opening the app for Netflix or Youtube is very slow (much slower than on my computer that uses the same internet connection).  
  • You cannot view an arbitrary website.  You can only view videos from a few specific sources.
  • For Netflix, there isn't a way to turn on subtitles.  This feature is available on my computer and tablet.
Because of this poor experience, I wanted to buy a cable to connect my laptop to my television.  After a bit of research, I eventually decided to forego wires and go for a Google Chromecast.  So far the experience has been great.  Also, every issue I had with the "Smart" blu-ray player was solved with the Chromecast. 
  • Searching for movies is simple, because I use my computer to browse.  
  • Opening apps is fast, because I use my computer. 
  • As long as you can open a video from a browser, you can "Cast" it to the television.  So, you don't have to wait for a new app to be supported.
  • For Netflix, you can turn on subtitles.
Another benefit of using a Google Chromecast is that you can cast movies from any device.  It works from my Macbook Air, my wife's Windows laptop, my Android phone and tablet.

*Update* I have had mixed results watching videos through the browser.  Perhaps the download rate isn't good enough, but sometimes the video is laggy and jumpy.  For apps, the video quality is consistently very good.

*Update* One disadvantage of using Chromecast is that you need some wi-fi infrastructure.  So, if all you have is a movie on a computer without wifi, you wouldn't be able to cast it to a television.  In a more common scenario, if you are in a hotel, the wifi restrictions may prevent you from casting videos, but I haven't verified this.

Into the unknown with Google App Engine

As mentioned before, I am setting up a cloud back-end for my mobile app.

This has involved writing code in a few different languages.  
  • Java - for the android application.
  • Python - for writing the Google Endpoints API.
  • Javascript/Html/Css - for writing a web client for the endpoints API. 
Working from the tutorials, I have been able to progress without too much issue.  However, I ran into a little bit of confusion when trying to pass around a datetime object.  Specifically, I wanted to:
  1. Start with a date / time value. 
  2. Pass that to my endpoints api. 
  3. Store it in the Google App Engine datastore.
I couldn't find solid documentation on how this works, so it took me a while to figure out. Here are the steps:
  1. In javascript code pass in your date time for some field like so:
    { some_field : "2011-12-16T10:00:00.000" }
    The format is Year-Month-Date"T"Hour:Minute:Second.FractionalSeconds
    When I tested, passing in a time zone offset threw an error.
  2. In python, when you construct your date time field use:
    from protorpc import message_types
    some_field = message_types.DateTimeField(1, required = True)
    # This is a little bit different from passing other fields which use protorpc.messages
  3. Once you have the datetime field, you can use the type ndb.DateTimeProperty in your model that you will insert.
This all works by passing in a string, which gets parsed and converted to a datetime object.  If you didn't want to use protorpc conversion to a datetime object, you can pass in a datetime string that you'd have to encode and decode.

Update - After I set up an Android client to send data to my endpoints api, I got more errors about the datetime having a bad timezone format.  After some trial and error then googling for solutions, I decided that dealing with datetime data wasn't worth the hassle.  I changed the datastore to only save "Long" values.  Then I updated the API to send and receive long values.  Finally, when I get to the UI, I convert the long into date time format for display.  This made things much simpler and cleaner.

Sunday, October 20, 2013

Mobile App + Cloud Backend

I wanted to set up a cloud back end for my Android application for a few reasons:
  • To practice and learn about cloud and web development.
  • To improve my Android app by backing up user data and to provide additional analysis based on a more full history for a given user and aggregated data from multiple users.
As a beginner web programmer, I didn't know where to begin.  Despite some criticisms, I turned to Google Cloud Endpoints in Python to provide a solution.  This works with Google App Engine and gives you a bunch of things: such as user authentication, data storage, ways to generate libraries for different clients (such as Android or the web) and scalability (although my user base is pretty small for now).

I started with this sample tictactoe application.  After a few minutes I got the sample application to work on my local machine.  When I moved the application to the cloud as a Google App Engine application, I got errors about "Origin mismatch".  The resolution was to make sure you registered any clients with the correct url.  This includes matching the protocol type as well - ie use "https".

After a few hours (spread out over a few weeks) I was able to create some new request/response objects which are used in the messages passed to and from the back end to a client.  I think I have a decent feel for how things work. In my head, the cloud back end goes through the following steps.
  1. A Web Client (or Android) creates JSON (or java) message object. 
  2. Your generated backend libraries convert these message objects into some request object.
  3. The request object is then sent to one of your backend apis/methods.
  4. (In my case) I take the request object and put it into the Google App Engine datastore.  In your case, you can do whatever you want.
  5. A response message is created and sent back to the original web or mobile client.
  6. Your generated backend libraries convert the response message back into a message. 
  7. Your client can then do whatever they want with the response.
I haven't actually implemented or tested anything in the Android client, so we'll see if my thinking about how this all changes. 

Saturday, October 19, 2013

Improving jury duty

I have an idea for improving jury duty.

Every trial should be recorded, without the jury being present.  After the trial is over, the recording can be edited. Then, the edited video can be presented to the jury who would make a decision.

Here are the advantages:

  • It would save time for jurors.  An edited trial can be watched faster than the actual trial.  Any delays in the trial, such as lawyer objections, can be removed from the video.
  • It would help with jury selection.  If jury selection occurred after a trial was complete and edited, they would know exactly how many hours the trial took.  
  • It would make the trial more unbiased.  If one lawyer or witness makes a statement that the judge wants to 'strike from the record' and the jury is supposed to disregard it - the video can actually ensure that the jury will be presented only with what they are supposed to see and hear.

Sunday, September 29, 2013

Tools I use today

I found an old blog post that I forgot to publish.  I'll post it now, because it's better late than never.

It's July, 2013.

When I have kids, and they grow up, I bet they will have all kinds of gadgets that would seem like science fiction to me.  Hopefully, I will also be playing with new gadgets as well.  In any case, I wanted to give a state of affairs of my belongings today.

In the future, I can compare what I have and use today with what my kids find commonplace for them.  I may nostalgically reminisce about the archaic tools of my past.  Or, I may find that the tools of yesteryear were really good enough.

Computing devices:
Phone - Samsung Galaxy Nexus 16GB
This phone runs the Android operating system.  I bought it about 1 year ago.  The thing that I am most likely to do on this phone is to read.  If I just read news articles, the battery will run out by the end of the day.  So, I often charge my phone wherever I go.

Computer - Apple MacBook Air 13.3-Inch Laptop
I bought this a few months ago. It is my first apple/Mac computer.  Previously I used a dual booted Windows/Linux laptop for well over 5 years.  This thing is comfortably light, and the battery life seems to be more than sufficient for my day to day use.

Tablet - ASUS Nexus 7 (7-Inch, 32GB) Tablet
My wife gave me this for Christmas last year.  I haven't really found much usage for it.
If there is ever a choice, I tend to go with either my phone or computer.
In my world of somewhat redundant technology, this tablet gets the least of my attention.

Travelling - Bike - Dahon Speed Uno Folding Bike
I am lucky enough to commute to work by walking.  On the rare occasion that I want to move faster, I may travel by subway or ride my bike, a Dahon Speed Uno.  This is a fold-able, single speed bike.  I got it almost 2 years ago.  My wife bought it for me for my birthday.

Monday, September 16, 2013

Always improving

As a programmer, most of my day is spent programming.  While programming is fun, it can be tiring.   Unsurprisingly, some days I don't have the energy to code.

In those times, it's good to have something else to do that is productive.  Here are a few things that I've been doing to stay busy.

Coursera

When I am tired of coding, it's nice to just sit and watch something.  I am taking a databases class.  It doesn't have a strict timeline, so I can watch a course or two whenever I get a chance.  I am familiar with databases, but I have never taken a structured course on them.  Therefore, I learn something in each lecture, but it isn't too mentally taxing.

Practice typing

I read a rant about the importance of typing fast.  From that reading, I realized that I am not good at typing numbers.  I didn't even know which fingers I was supposed to use when typing numbers.  So whenever I want something truly mindless to do, I go to a site that helps you practice typing.

VIM plugins

I heard of vim plugins before, but I didn't really ever use them much.  I imagine that once I begin using them, I will realize how useful they are.  I started by installing pathogen.  I then installed NERDTree, syntastic, easymotion, and sensible. Some of these (pathogen, syntastic and sensible) are really simple to use and work right out of the box.  NERDTree and easymotion are also easy to use, but the more you practice using them the better you will be at using them.  Playing with vim plugins is fun and hopefully makes you more productive - whenever you do decide to start coding again.

Tuesday, September 3, 2013

First time using coursera

A few days ago, I registered for my first class using coursera.  Coursera provides free online courses from top-notch educators.  The first class I am taking is https://class.coursera.org/db/class, by Jennifer Widom from Stanford University.

I use databases pretty often, so I expect to be familiar with a lot of the material.  Nevertheless, I hope the course will help me fill in gaps of knowledge that I might have missed and organize my understanding of databases in general.

So far, I have only watched the first lecture, which was just introductory material on databases.  Here are my some things that I liked.
  • The quality of the video and audio is good.  It is clear and clean.
  • The video has subtitles, which I turn on even when I have audio on.  
  • The video also lets you change the playback speed. I set it to 1.25x speed.  When I come to a lecture where the material is more unfamiliar or a bit difficult to understand, I can reduce it back to normal speed. 
  • Each lecture is relatively short. The longest one goes for 30 minutes, but many are around 15 minutes.
  • The ability to pause and rewind is great and much better than live lectures.  If I missed something I can rewind and try again.  Or, I can go on the internet and search for a different explanation.  I can then move on with the lecture when I feel ready. 
Overall, I think coursera is a pretty great service, and I hope that I persevere long enough to benefit from it.  

Monday, September 2, 2013

Mac Apps

Here are some general purpose apps that I use on my Mac.

Spectaclehttp://spectacleapp.com/
This is an essential app for me. It lets you use the keyboard to rearrange windows. Apple should build something into the OS to handle this. Until then, this works pretty darn well.

CheatSheethttp://www.cheatsheetapp.com/CheatSheet/
This app that makes learning Mac keyboard shortcuts much easier.  When you want to look up a keyboard shortcut for the app you have open, hold down the "Command" button.  After a few seconds, a popup appears with a menu of keyboard shortcuts available for a given application.

It is basically a keyboard shortcut to the keyboard shortcuts menu for a given application.

This is a great idea for any operating system.  Give the user one way to quickly see available keyboard shortcuts for any application. Over time, I have been using this app less and less, probably because you don't need the app once you've learned them.

git cheat sheet

Here's my personal cheat sheet for using git.  Use at your own risk.

Change the name of a local branch.

  • git checkout "name_of_old_branch"
  • git branch -m "new_branch_name"

Merge Branches

  • git checkout -b "new_branch_to_work_on"
  • make changes ...
  • git commit -a
  • git checkout "master"
  • git merge "new_branch_to_work_on"
  • change from "new_branch_to_work_on" should be merged into master

What is the status (what files have changed)

  • git status

Setting up which program to use for diff'ing files:

  • git config --global diff.tool vimdiff
    • This makes vimdiff your difftool.
  • git config --global difftool.prompt false
    • This stops git from asking you if this difftool should be used

What changes have I made to a file (since last commit)?

  • git diff filename
  • git difftool filename

How has my file changed?

  • git log <filename>
    • This gets revision #'s and log notes.
  • git diff <revision#> <filename>
    • This compares latest revision with the specified version.
  • git diff <oldrevision#> <newrevision#> <filename

How to make a new repository?

  • git init
  • git add .
    • This will add all files to a repository.
  • git commit -a 
    • Commit file additions to repository.

Sunday, September 1, 2013

Vim - never leave home without it

I have been using Eclipse on and off for about a year.  I've gotten slightly more comfortable with it over time, but it still feels a bit clunky for me.

To make things easier, I decided to add a vim plugin to Eclipse.  I first tried something called vimplugin, but I settled on using vrapper.  The setup instructions are here.

I predict it will make coding in Eclipse a much better experience. 

Thursday, August 29, 2013

Testing is Fun

When I started programming, testing was the thing you did after you finished your first draft of a program.  If you've built a website, you may test that it displays the page as you designed it.  If you've built a calculator, you test that adding positive numbers, negative numbers and fractions all work right.  After testing, you'd find some bugs, fix them and say "Oh well, I guess it's time to ship".

Better late than never, I finally hopped aboard the test driven development band wagon.  Armed with Google Test, I'm beginning to make testing part of the early stages of my development process.  There are probably lists that detail all the benefits to test driven development, and you can and should search for them on your own.  But some benefits that I've personally experienced and felt are:

  1. Thinking about testing makes me write better code.  If you want to write unit tests, you need to separate your program into distinct modular components, so you can test one part at a time.  Of course, writing small byte-size units of code is generally a good programming practice anyway - so that's one win-win. 
  2. Testing gives you confidence.  All programs have some bugs, but testing helps you out in a few ways. 
    1. Before you check in code, testing might help you catch a bug.  So, buggy code doesn't enter your repository.  Nobody but you knows that you're a sloppy programmer!
    2. After your code has rolled out to the world, your test might find a bug before any user's notice it.  Although not ideal, maybe you can roll back changes or submit a fix before any clients begin complaining.  Only your coworkers know you made a mistake!
    3. One of your clients spots a bug and you get called up to fix it.  Testing will help you isolate the problem.  You know what tests have been written and what edge cases haven't thoroughly been tested.  Hopefully your tests help you fix the problem faster.  So, your clients know that you had bugs, but they marvel at your customer service.  
Now that I've experienced some of the benefits of testing, I can't imagine writing code without them.   

Tuesday, August 27, 2013

Pocket > Google Reader

A few months ago Google Reader was retired.  I quickly passed through the 5 stages of grief, and I knew I'd find something that would fill the void.

I started with Feedly.  This app looks much nicer than the old Google Reader app.  However, I found it hard to use.  It was just a bit too slick, with too many animations, and too many views.  It's not a knock on Feedly.  I suppose there's someone that likes all of the eye candy, but it wasn't for me.  I eventually found and settled on this dirt simple Rss reader - Sparse Rss.  

Sparse Rss has been serving me well, but in the midst of transitioning away from Google Reader, I started reading more articles that were brought to my attention via Twitter, Google Plus and even email.  I realized that I needed a place to store these articles that came at me from multiple sources.  The answer is Pocket (aka Read It Later).  I mainly use the Android App, but I've also used the Chrome App.  

Pocket looks great, yet is super simple to use.  It automagically decides on the best view for articles so that they are very easy to read.  It's hard to explain.  Somehow, the articles look great in Pocket.  It is as if they optimized the UI to make it best for someone who wants to read.  Perfect.

Even better, I found out that they have a developer API.  There are already a number of existing applications that use RSS to add articles to Pocket.  I will try them out and see if any of them improve my Pocket experience.  But even if I can't find an app that I like, I can't complain because the option is always there to write one myself.  Thus, the onus is on me, which is great.

Update: I usually use pocket on my phone, but today I decided to read some articles over a web browser.  They have this feature, where if you press "/", a quick screen guide for keyboard shortcuts is shown.  The guide itself looks great, and it is incredibly useful.  I already started using keyboard shortcuts (mostly j and k to navigate through a list).  This application always impresses me.

Monday, August 26, 2013

Testing sql queries

I was working on an Android application, and one of my queries wasn't returning what I expected it to.  

To test my query, I decided to just run sqlite on my computer, which is pretty simple.  Here are the steps:
  1. Download sqlite from http://www.sqlite.org/ .
  2. Unzip the file into some folder and then you can start a database called test1 with a command like this:
    ~/bin/sqlite3 test1.db
  3. Create a table and insert some data.
    create table phrase_table (words char(50));
    insert into phrase_table (words) values ('hello');
  4. Run queries like:
    select * from phrase_table;

While that was pretty simple, another tool to quickly test queries is http://sqlfiddle.com/ .  This is a web tool where you can set up a database table and then test queries.  For simple cases where you'd like to share your queries, this is a fantastic tool.

Monday, August 12, 2013

Simple C++ program with Google test

I have little to no experience with unit testing.  I want to change that.

In principle, unit testing sounds simple.  Unit tests are used to isolate and validate small parts of a program are working.  In practice, I don't really know how it's done.

As a first attempt, I tried to build a simple program with tests using google test, https://code.google.com/p/googletest/.  After downloading and unzipping the library, I moved it into a folder -- SomeDirectory/libs/gtest-1.6.0.  I then copied these files into a separate directory.
  • Makefile -- this is used by make to build both the test program and my program.
  • sample1.h, sample1.cc -- These define some functions that are linked into the test program and into my program.
  • sample_unittest.cc -- This defines test macros that are run in the test program.
If you put these files into a directory, you are almost ready to run the test.  You will have to update the paths in the Makefile.
  • GTEST_DIR = SomeDirectory/libs/gtest-1.6.0
  • USER_DIR = ./ 
You can run then run "make" followed by "sample1_unittest" and you should see some successful test output.

I wanted to add a real program with this test suite, so I wrote this:
To build the program I updated the Makefile to build "my_program" like this:
TESTS = sample1_unittest my_program
and then I added this to the end of the Makefile:
my_program : sample1.o main.o 
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

After running make, I had two programs.  "sample1_unittest" was the original test program and "my_program" was the 'real' program that I was testing.

Sunday, August 11, 2013

Gist - a great way to share and view code

I often want to embed code snippets into my blog posts. I am testing a method with this post that uses gist.github.com. The idea is that you put your code into some repository and then create a reference to it from wherever you want to use that code.  The code in the post will auto-magically have nice syntax highlighting, be easy to copy, and modifications can be made independent of the blog post.

It took me about a minute to create this gist: https://gist.github.com/dhan12/6206272.
The gist page gave me this one liner to add to my blog post:
  <script src="https://gist.github.com/dhan12/6206272.js"></script>
The output is shown here: It worked on the first try. I think this will be the way of the future for me.

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.

Sunday, August 4, 2013

Weekend coding

This weekend was a typical one for me (at least for the last few years).  I spent the majority of the time with my family, hung out with some friends on one night, and did some household chores.

During the weekend, I managed to spend about 1.5 hours working on my latest project (this google app engine).  Given it was only a small amount of time, I made some decent progress. 

In my day job, my objective is to build reliable, maintainable, error-free performant code.   
At home, my objective is to build things that are interesting and fun, while learning something along the way.  Given the difference in weekend coding from real-job coding, here are some pointers on how to make progress on a hobby project successful.
  • Keep a list of work items that you may want to work on next. This list should be varied like, "updating the database schema to hold a user's dataset" or "update the UI to align all the buttons on the page".  I never know what mood I will be in when I return to a project. If I feel like making UI updates, working on back end tests or whatever, there should always be something ready to work on.
  • Make quantum updates.  This means take small steps that a make a difference.  If you try to accomplish a big task within a small amount of time, you may not finish anything tangible, which is disheartening.  
  • Code first, fix errors later.  This is probably the one that is the biggest departure from my normal habits.  For weekend coding, it's most important to get something working, so that you can give yourself a job-well-done pat on the back.  If you spend too much time harping on every edge case, you again might run out of time. 

Tuesday, July 30, 2013

One project down, another to begin

In my experience, software programs are never finished.  You can always add a new feature, optimize some back end code, or integrate it into another workflow.  The reason why we stop working on a program is either boredom, someone deems it good enough, or the bosses want you to work on something else that they is more important.

Nevertheless, almost all projects come to some end.  Today, one of my projects came to an end.  Well, it's more like we've reached a milestone that we targeted a few months ago.  After a lot of hard work and a few late nights, we actually finished just about everything we set out to do, hooray!

In the coming days, we'll be planning the next things we'd like to work on.  I have some opinions on what would be the best features to work on, but it will be something that a few people will discuss and come to some consensus about.  In the end, the features we decide to work on will not affect my day to day life.

As a new project is being planned, the most important bit is estimating how long the project will take.  If I underestimate how much time I will need, it will put pressure on me to finish code faster and may lead to buggier code.  So this time around, I will do my best to give myself ample time.  I will do my best to not work overtime (aka, I will not work for free).

Sunday, July 28, 2013

Google app engine python search tutorial

After completing an introductory tutorial for Google App Engine using python,  I was able to create the first version of an app engine project, englishtokoreanforum.appspot.com.  I modified and extended the tutorial a bit to set up a few other handlers and data types.

I then went on to the next Google App Engine tutorial, which would teach me how to set up searching over an index that I set up for this app.  Unfortunately, when I first tried it, the application in the tutorial would run, because of this issue.  (It has since been fixed after I upgraded to the next version of the GoogleAppEngineLauncher).  

Along with setting up the search index and functionality, this tutorial is nice because it isn't as trivial as the first tutorial.  It shows how someone might want to organize all the files that might go into a real project.  The different files types in this tutorial are *.html, *.py, *.yaml, *js, *css. It shows how to separate data files, test files and the main application.  This is invaluable for a beginner, and something that isn't often emphasized.

Saturday, July 27, 2013

How many programmer days will it take?

At work, I have become the lead developer on bigger and more important projects.

I began designing the goals of projects, rejecting and championing ideas, and building and supporting much larger code bases.  I've enjoyed all of it, except for having to estimate how long it will take to build something.  I think the worst part occurs when you make an honest estimate before the project starts, and then you find that you are running out of time near the due date.  If at all possible, I try to make up the time after work or on weekends.  If it looks like I still can't make the deadline, I report it back to my manager, where it feels like I have to admit one of two things:

1. I am a poor, unskilled, lazy developer who does not fulfill promises.
2. My past self was an ambitious, cocky, know-it-all who made outlandish over promises.

As one of these projects come to a close (miraculously near the proposed deadline), I worry again about the next project.  Should I just game the estimate with tons of buffer time?  That doesn't seem honest.

Monday, July 15, 2013

Google App Engine - Python

I already spent some time building a Google App engine product in Java. Java was a natural choice because because I was already working with Java (and Google) as I was building an Android App.  While I was/am making some progress it has been slower than I had hoped.  So, for my next Google App Engine App, I am going to give Python a try.

Again, similar to Java, I'm not very familiar with python, so this will be another learning experience.  I started by following this tutorial, https://developers.google.com/appengine/docs/python/gettingstartedpython27/introduction, after which I was able to do many fundamental web actions (displaying a site, reading/writing to a datastore and responding to events).

My initial feeling is that it is great to develop without eclipse.  I believe that eclipse can be a great and powerful tool, but I have not mastered it yet.  Learning a new programming language and a new framework and a new IDE has been slow for me.

Just using a terminal to start a development server, mvim to code, and a browser to view is refreshingly simple.  Eclipse worked like magic, but for a beginner like me, it felt like black magic where I didn't what was going on.  One feature that I know I will miss when coding with mvim is code completion.

So, without further ado, here's the app I created.
http://englishtokoreanforum.appspot.com/
As of right now, it is the final product of the tutorial.  In the future, I envision to make a forum where users can view and enter english to korean translations.

As a final note, I mistakenly chose this appspot domain name.  I was playing around with different titles, and hit enter by accident.  Anyway, I'll live with it for now.

Monday, July 1, 2013

Recruiters

I had a bad experience with a recruiter, aka head-hunter, a few days ago.  Here's what happened.

About a week ago, the recruiter, let's call him Mr. X, emailed me saying that someone I knew recommended me to him.  Wow.  A personal recommendation.  That's great, but I didn't reply.

A few days later, Mr. X emailed both my work and personal email accounts saying that he has a position that seems like a good fit for me based on one of my past colleagues recommendation.

OK, because of the personal recommendation, I thought it might be worthwhile to investigate what this recruiter has.  I sent Mr. X an email saying that I would like to chat about this position he thought I might be a good fit for.  I sent him my phone number and a time range that I would be available.

Mr. X didn't confirm that he would call, but a call arrived.  The problem was, the person calling wasn't Mr. X. It was Mr. X's colleague Mr. Y.  I didn't really have any loyalty to Mr. X, but passing my file along before we ever spoke doesn't exactly make me feel special.

After informing me he wasn't Mr. X, Mr. Y wanted information from me, but didn't want to give me any.  He began the conversation by saying,
"Can you tell me about your programming experience?"

I didn't want to be difficult, but I couldn't help it.  I said something like:
"You emailed me saying that, based on a personal recommendation, you had a great position for me.  Please tell me why you think I'm a good fit for the position."  

Well, Mr. Y began speaking again, and before I knew it, he was asking me again about my programming experience.  He's a professional recruiter, and I am not a professional job seeker.  He was getting me to tell him whether I knew about smart pointers, what I worked on, what I wanted in a job and so forth, but I couldn't get a clear answer on what the job was that I was supposedly a great fit for.

The only thing I really wanted at this point was for him to tell me what the job was.  After a bit, I finally said,
"Can you just email me the job title and description?"
He replied that this was a special position and that he and the hiring manager had a good relationship, and blah blah blah.  Mr. Y basically told me that this job didn't really have a written description.  I still couldn't figure out what the job was.  How the heck did Mr X or Mr Y figure that I was a good fit for this mysterious job?   He must have gotten me really confused, because before I knew it, he was asking me for a resume and I said I would work on it.

The call ended.  Mr Y. emailed me, asked for my resume, and I guess he slipped, but he gave me the job title.  I looked up the recruiting firm and saw that this was a listed job with an actual job description.  In the end, the job wasn't for me at all, and I emailed Mr. Y saying that it wasn't a good fit.

Over the course of the emails and calls, the only thing that the recruiter said about the job was that it was 'prestigious'.  I'm not sure if recruiters will ever really understand what a developer is looking for.  I sometimes want to recommend that they read Joel's test, but I think a recruiter will use that for evil instead of actually helping developers find good roles.

Saturday, June 22, 2013

Thoughts on the 2013 NBA Season and Finals

The team I was rooting for, the Spurs, lost to the team almost everyone was rooting against, the Heat, in a 7 game series.  I imagine that history will glorify the Heat and will more or less forget this year's Spurs.

I set my DVR to record the games.  Since the games were on late, I expected to watch the start of games and then finish the rest the next day.  However, I ended up watching most of it live.  I guess I was really into this series.

During the breaks in action, I checked twitter to read live instant updates.  I think twitter could replace or at least supplement sports announcing.  I'd like to tell the television who I'd like to follow and then their tweets would appear on the screen.  I'd also like to chat (maybe through twitter) with friends while the game is going on.  This would all appear on the television screen so that I don't have to constantly check my laptop or phone.

As much as I like Jeff Van Gundy, there are other broadcasters that I don't like as much.  If I don't like a broadcaster, it would be great if I can switch to another.  For big games, there are usually at least two sets of announcers (the local and the national).  For huge games, there are international broadcasts as well.  I'm sure some people would prefer to watch the game with the broadcast in a non-English language.

I have devoted way too much time to following basketball this season.  Zach Lowe, you have raised the bar for basketball analysis, hopefully other writers keep up.  I am now always commenting on the angle in which the Spurs bigs set picks (something that only diehards could get excited about).  48MinutesOfHell, your writing is always thoughtful and exceptional.  Well done.  The basketball Jones, you guys always crack me up.  It's gotten to the point where I feel like I understand some of your private jokes.

Now that the season is over, I'm happy to get back the time used watching, reading and listening about basketball, but it was fun while it lasted.

(Actually, after I post this, I'm going to listen to the final TBJ podcast, which I haven't had a chance to listen to yet).

Monday, June 10, 2013

Ruby on Rails tutorial

I began this tutorial, http://ruby.railstutorial.org/ruby-on-rails-tutorial-book, about a year ago and got through a few chapters.  However, I lost momentum, and for reasons that I do not remember at all, I stopped working on Ruby development.  Since I got a new computer and I probably forgot everything that I learned, I'm going to have to start from scratch and go through the tutorial again from the beginning.

Installing ruby, rvm, gem, rails ...
There seems to be a lot of stuff needed to install and configure in order for you to begin coding.  There really isn't anything fun or interesting to learn as you install this software.  You just have to do it, and hope that you didn't make some silly mistake that comes back to bite you later.   After a few minutes of downloading, compiling and other magic, I finished the installation process.

first_app
So after installing and configuring, you can start up your first app rather quickly.  With these commands:
rvm use ruby-1.9.3-p429  
rails new first_app
bundle update
bundle install
rails server
Bam! The server was up and running for me, viewable from a broswer and I didn't have to write a single line of code. It was almost too easy.

Github and Heroku
As recommended in the tutorial I also made a git repository, pushed the code onto github and deployed the project to heroku.  There is a lot of 'pushing' and 'pulling', and it can be a little confusing.  Here is a rundown of what's going on.

On my local machine (my laptop), I have all the source code and configuration needed to run the application.  This is good for development.  If all of your users (and other developers) had access to your laptop, this might be good enough.

But what if I want to share my code or back it up in case my machine crashes?  That's where GitHub comes along.  At the lowest level, Github is a place to back up your code.  At a higher level, it's a repository which can help you keep track of changes, allow you to easily test and revert changes,  and share and merge your changes with yourself or others.  The final thing that Github does (that I will mention) is that it helps me push my files onto Heroku.

Now, what is Heroku?  Well, for the purposes of this first app I just made, it's a better version of your laptop.  After you push your latest versions of your files onto Heroku, it figures out that you have a ruby on rails app and starts the server, where users can now visit.  You can configure heroku to work a bit differently than your laptop.  For example: (if you followed the tutorial), on your laptop you used sqlite as the backend database, but told Heroku to use another database (postgres).

Conclusion
This is the second time I made the first_app ruby on rails app.  It's been so long, it was almost all new to me.  Although, I think I was able to move along a bit faster this time, and I definitely understood a bit more than I did last time around.

Sunday, June 9, 2013

Biking in NYC

Citibikes have come to Manhattan.  This is a bike sharing plan where:
  • you sign up for access for some period of time (a day, a week or a year)
  • take out a bike from a bike stand (self service - without a human operator)
  • ride
  • return the bike to another bike stand (again, without human intervention)
  • hopefully return your bike within 45 minutes so you don't pay overage fees
I have my own bike, and there aren't many bike stands anywhere near me (or any above 59th street for that matter), so I do not plan on using the system at all.  However, I hope the system works and leads to these benefits:
  • Safer streets for cyclists.  The raw number of bike accidents and related injuries will surely rise, because the raw number of riders (many of them less skilled) will rise.  Yet, the more cyclists there are, the safer it is for other cyclists.  Cars (and pedestrians) will be more aware of cyclists, which will hopefully reduce the rate of collisions with each.  
  • Less congestion on the subway and buses.  
Hopefully there are many other unknown benefits.  Some downsides of citibikes are:
  • reduces the number of parking spots for cars.
  • the bike stands are a bit of an eyesore to some.  I'm not sure if the bike stands look worse than parked cars or wind mills off the coast of cape cod, but it is a complaint.

NYC culture

When the weather is nice, my wife, dog and I will go to Central Park at least once a week.  Over the last few weeks, there were a few events that affected our visits.

Puerto Rican Day Parade
This ran along 5th Avenue.  When there were breaks in the parade, pedestrians were able to cross the avenue to enter or exit the park.  We were able to enter at 72nd street without much delay.  However, when we entered the park, we found that the walkways were very congested and the normal access areas (lawns, the mall, sheep's meadow) were all blocked off.  I'm not sure if there was another access point, but a police officer told us that there was no access to our normal walking and relaxing areas, so we just left the park.  I'm not sure if restriction of park areas was related to the parade, but it ruined our visit nonetheless.

Conclusion: Unless you want to see the Puerto Rican Day parade, avoid 5th avenue, the east side and central park on this day.

Israel Day
Similar to the Puerto Rican Day Parade, there was a parade that ran along fifth avenue.  We crossed and entered the park without much delay on 72nd street.  Most of the park functioned just like any other day, except that an area near the Mall (just above the fountain) was closed off.  The only people who seemed to be allowed in were those who participated in the parade.  We didn't really ask how we might gain access, so we just walked around the restricted areas.  On this day, there were also protestors.  Because of the restricted areas with selective access, the protestors, Israel's history with terrorism, and the recent Boston marathon bombings, I couldn't help but feel a bit of tension in the park.

Conclusion: Similar to the Puerto Rican Day parade, avoid this parade and its activities unless you are sure you will participate and be allowed in to all of the restricted areas.

Japan Day
Unlike the parades, no roadways are blocked off for this event.  Instead, you will find Japanese volunteers scattered around the park advising visitors on where the events are.  Near the volleyball courts and the Mall, there is a large number of stands where the Japan day events are being held.  I think there was an origami stand and another place where you can try on kimonos.  You will also find lots of free Japanese food and drinks.  Also, there is a stage where you will see Japanese performers.

Conclusion:  Although it is crowded, this is the best of the events.  You might learn something, nothing is blocked off, and there will be lots of free stuff.

Thursday, June 6, 2013

MySQL on Macbook

My wife wanted to set up an environment so that she could practice her sql skills.  After a bit of research, I decided to give MySQL a try.  Here are my notes on how it went.

Step 1. Download the software.
http://dev.mysql.com/downloads/mysql/
I chose the 64 bit DMG archive for Mac version to install.  Before the download started I had to jump through a few hoops.  First, I had to register to get a new oracle account.  This sign up was pretty painful.  I had to provide my name, full address, phone number, and a complicated password.  As usual, I entered a password that I will surely forget by the next time I am asked for it.  I then had to fill out a survey about my job, what I will use the software for and some other questions.  This was a bit off-putting, but in the end, I finally downloaded the file.

Step 2. Installation.
I clicked on the downloaded dmg file and then the pkg file which started the installation process.  I was told that the install would use 680.9 MB of space, which seems a bit high.  The software was installed in less than a minute.  I also installed the MySQLStartupItem.pkg, but I'm not sure what that is.  I finally installed the MySQL.prefPane, which gives a GUI (placed as an icon in system preferences) so that you can easily start the MySQL server.

Step 3. Hello world.
I wanted to do the basic operations with a database to make sure that I had installed everything ok.  In the programming world, when you start working with a new language, you would try to write some code, compile it, and then output the results.  Typically, you make the program say, "hello world".  I think I got my database to say "Hello World" with the following commands:

a. First, I created a database:
mysql> CREATE DATABASE testdb;
Query OK, 1 row affected (0.00 sec)
b. I confirmed that my database was created by showing them:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
c. I then told mysql to use the database I just created.
mysql> use testdb;
Database changed
d. I created a table.
mysql> create table phrase_table ( 
-> words char(25)
-> );
Query OK, 0 rows affected (0.02 sec)
e. I added one row. It has one column called words and the phrase "Hello World".
mysql> insert into phrase_table (words) values("Hello World");
Query OK, 1 row affected (0.00 sec)
f. I finally selected all rows from my table to get the program to say "Hello World".
mysql> select * from phrase_table;
+-------------+
| words |
+-------------+
| Hello World |
+-------------+
1 row in set (0.00 sec)
e. Done. I got the basic operations to work. This link was pretty helpful. http://www.mysqltutorial.org/basic-mysql-tutorial.aspx

Wednesday, June 5, 2013

Jury duty notes

The day before jury duty.
Tomorrow I have jury duty, and I am looking forward to it.

Last time I served, I made it as far as walking into a court room.  I never had to answer any questions from the judge or a lawyer.  So basically, I just sat around, read and waited.  Needless to say, I loved it.  It was like retirement.

This time, I plan to take a book, a computer, a tablet and my phone.  This should give me enough things to read as I wait around.

Day 1 of jury duty.
I arrived a bit before 9 am.  I went through security, got to the floor I have been assigned to, and waited until the doors were opened.

When we were allowed in, we found a seat, watched a video, filled out some forms and waited again.  At first, I was a bit disappointed that I didn't get a seat near a power outlet.  But I soon found a computer room where I could sit and plug in.  I would think that a spot at one of the desks would be in higher demand, but there were a few remaining spots.

Around 10:15 am, we were told that a judge wanted to see everyone at 2 pm in another building.  So we were free until then.  If we were told this the day before, I would have gone to work for half a day.

After lunch, I bought soup dumplings and ate in the park, I went to the other jury waiting room and waited.  Around 2:30 pm, we were all called to the court, where the judge told us that this trial could last over a month.  The judge asked for volunteers who could serve.  A few people volunteered, but the judge was looking for more.  She then asked a few people why they couldn't serve and she said some were ok and some were bad excuses.  After a few rounds, I eventually volunteered.

I definitely did not want to spend weeks coming to this court house.  I did not want the projects I was working on at work.  There was no good reason for me to excuse myself, but there were a lot of reasons for me to serve. Every citizen should be ready to serve their city/country if called upon.  I also thought to myself, if I postpone now, there is no guarantee that I will have more time in the future or get a shorter case later on.  My desire to not procrastinate and my civic duty led me to volunteer for a trial I had no desire to participate in.

After about 60 volunteers arose, the remaining jurors were sent out of the courtroom.  The judge made some remarks, and then names were called out and chosen to sit in the jury box or in a specific seat in the audience.  My name was not called out.  Each of the jurors who had their name called out answered a list of questions like, "where did they live", "what do they do", "do they know any policeman", etc ... After this line of questioning, all jurors were told to go home and report back to the court room the next day at 9:45 am.

Day 2 of jury duty.
I went to the court house and waited for the judge to call in all of the jurors.  This time, the lawyers did most of the talking and each set asked a bunch of questions.  Some were directed to the whole set of jurors, like "Does anyone have any issue with saying someone is not guilty if there isn't sufficient evidence" and some were asked direct questions like "Mr X, will you be able to judge impartially the merits of the case based only on the evidence presented in the court room?"

After a few hours, all jurors were sent out of the courtroom.  After about half an hour, the jurors who had their names called earlier (30 or so of them), were called back into the courtroom.  After a few minutes, several of them walked out.  Then, for all of the rest of us, we were told to go back to the jury waiting room -- we weren't going to sit on this trial.

Back in the jury waiting room, we were told to return in an hour, after lunch.  After lunch (this time I ate Mapo Tofu in the park) we waited for a bit and were then eventually released with papers saying that we served for two days.

Is circumstantial evidence enough?
One line of questioning by the defense to the prospective jurors made me think that I might not be able to serve.  The defense said that the evidence in this case was all circumstantial.  He asked if we could render a verdict using just circumstantial evidence.  The example he gave goes as follows:

If you pick up your mail (in your apartment building) today, and then return tomorrow and find mail there again, then it is reasonable to conclude that the mailman visited your apartment building. 

After a moment of thought, I thought of three ways mail could be in your mailbox without the mailman visiting.
  1. When I picked up the mail, I left a letter behind.
  2. A neighbor incorrectly got a letter addressed to me.  The neighbor put the letter into my mailbox or asked the doorman to put it into my mailbox.  
  3. The doorman had only sorted some of the mail when I picked up the mail, and he finished putting the mail into the boxes after I made my first pick up. 
If asked, I don't think I could convict someone of a crime if all evidence was circumstantial.  Maybe it was a bad example, or I was thinking about it incorrectly.

Conclusions
My jury experience was a little bit better than the previous time.  With a power outlet, wifi, computer and a phone, I can always find something to read or play around with.  In the future, I hope the jury duty experience improves even more such that we don't have to physically go to the court house unless we are actually needed.

Tuesday, June 4, 2013

Updating Google Drive Files from an Android App

I want to save data generated by my Android App as a file on Google Drive.

Setting up the environment for the first time
First, I needed the google play services library, which I setup using this guide.  I used the "Android SDK Manager" from Eclipse to download the SDK.  This took a while to complete, because installation of one item required an upgrade or installation of a few other dependent libraries and tools.  In all, it took me about an hour.

I then followed this guide to update my Android project to work with the Google Play Services and Drive API.  At this point, I should have been able to:
  • Connect your app to Google Drive.
  • Ask you which account you'd like to use.
  • Allow you to save a picture that you take to Google Drive.
Of course, things didn't work right out of the box.  Here are the issues I encountered.
  • My app was crashing with a message about "No Activity found to handle Intent { act=com.google.android.gms.common.account.CHOOSE_ACCOUNT (has extras) }".  As suggested by a stack overflow question, I tried running my app on a real phone (instead of with an emulator) and it worked without crashing.
  • When I tried to save a file to Google drive I got a 403 error with a meesage about "Access Not Configured".  I realized I set up a client id using the production version of my keystore.  I had to use the development version from eclipse with:
    keytool -exportcert -alias androiddebugkey -keystore .android/debug.keystore -list -v
    where the password was 'android'.
My business logic
For my app, I'd like to.
  1. Create a new csv (spreadsheet) file on Google Drive.
  2. Check if a previously saved file from my app exists on Google Drive, and read it.
  3. If a file exists, update the existing csv file with updated data.
1. Creating a new Google Drive Spreadsheet file.
After creating a comma separated file, I saved it to Google Drive with the function listed below.  Importantly, you have to call setConvert(true) in order to allow Google Drive to update the file.

private String m_filename = "someFile";
private void saveFileToDrive() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
// File's metadata.
File body = new File();
body.setTitle(m_filename);
body.setDescription("Description for "+m_filename);
body.setMimeType("text/csv");

// File's content
String filePath = getApplicationContext().getFilesDir() +
java.io.File.separator +
m_filename;
java.io.File fileContent = new java.io.File(filePath);
FileContent mediaContent = new FileContent("test/csv",
fileContent);

// Insert and convert to spreadsheet
Insert request = m_service.files().insert(body, mediaContent);
request.setConvert( true );
File file = request.execute();
if (file != null) {
Log.i("MyTag","saveFileToDrive file Id:"+file.getId());
}
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (GoogleJsonResponseException e) {
GoogleJsonError error = e.getDetails();

Log.e("MyTag","Error code: " + error.getCode());
Log.e("MyTag","Error message: " + error.getMessage());
} catch (IOException e) {
Log.e("MyTag","saveFileToDrive failed");
e.printStackTrace();
}
}});
t.start();
}

Monday, June 3, 2013

2012-2013 NBA season

We are about one week from the end of the NBA season.

Even though I am a huge NBA fan, I am glad that the season is almost over.  Being an NBA fan is time-consuming.  I read about the NBA (Zach Lowe has the best stuff these days), listen to podcasts (the best NBA podcast is the Basketball Jones), and of course watch games (which I typically watch recordings of). 

Given the time commitment, I have been toying around with the idea of giving up my fandom.  
While I may never totally give up the NBA, this may be the last season that I follow the game very closely.  Here are some things I will remember from this season.

1. Teamwork (chemistry) seems important.
When the Knicks were playing great, assists were high, scoring was easy, and the game was beautiful.  The Lakers looked lost all season, and it did not seem as if they liked each other.

2. Shaquille O'Neal has no business being on the TNT broadcast team.
His comments are never insightful.  His interactions with Ernie, Kenny and Charles are awkward.  He mumbles.  He replaced the great Chris Webber, whose analysis was incredible.  Please fire Shaq.  At least make him a sideline reporter.

3. The NBA serves many masters.  In game 6 of the Heat-Pacers Eastern Conference finals, Chris "Birdman" Andersen was suspended for shoving Tyler Hansbrough.  In the pre-game highlights for game 7, the shove was shown as one of the highlights of the series.  Why is a punishable offense part of the highlights?

4. Everyone in the NBA is a remarkable athlete.  I tend to find the ones with the greatest physical advantage to be boring.  This year, my favorite players to watch were Stephen Curry, Jason Kidd, and Manu Ginobli.  

Sunday, June 2, 2013

The Office Ends

For as far back as I can remember, there has always been a television show that has been targeted to my age group.

Over the years, I remember watching Full HouseSaved by the BellBeverly Hills 90210, and Friends.  Each of these shows seemed to be made for me.  Most recently, The Office coincided with me getting my first real office job.  A few weeks ago, the series finale aired, which I watched today.

Here are some notes on how I felt watching the show
  • I felt a strong sense of sad nostalgia.  Unlike school, where there is a new beginning after graduation, the end of office life seems depressing.  Most of my youth was spent studying for a career, and when that career is over, I don't know what I will do or how I will feel.  
  • I wonder what show will capture the mood of my next stages in life.  Maybe (if I have kids) it will be Modern Family.  I wonder if shows will continue to target my age group anymore.  For example, MTV seems to target the teen audience.  
  • I always thought Michael was the star of the show, and then maybe Jim or Dwight.  But now I think it was Pam.  She had the most to learn, the most to overcome and the greatest lessons to impart.

Monday, May 27, 2013

Brazil Trip - Igauzu Falls

I just returned from a 10 day trip to Brazil. We went to Rio de Janeiro, Iguazu Falls, and the Amazon Rainforest via the city of Manaus.

In this post, I've noted some notes and tips about visiting the Iguazu Falls.  You can visit the falls from either Brazil or Argentina, but we only saw the view from Brazil.

  • Try to sit on the top level of the double decker buses that take you from the main entrance to the falls.  On the way there, sit on the right side side, and on the way back, sit on the left side.
  • Go to the bird park.  You get an extremely close up view of many birds.  Our favorite was probably the Toucan.  We enjoyed the bird park about as much as we liked the falls.
  • Try to book a flight that doesn't leave too early or too late, so that you can take the public bus from the city center to the airport.  It is much cheaper. 
  • We went to Bufalo Branco Churrascaria.  The meat was ok, but a little bit rare for our tastes.  The salad bar is pretty meager.  If you do plan on going to this or any churrascaria, make sure you have a translator or a word list of the major meats so that you have an idea of whether you are eating beef, chicken, lamb, or whatever.
  • We stayed at the Aquas do Iguacu Hotel.  The location is close to the bus stop and to a few restaurants.  The breakfast food tasted a bit stale and we had an issue with a bunch of bees flying all over the dining area.  Overall, this hotel is affordable and just sufficient.  

Sunday, May 26, 2013

Brazil Trip - Rio de Janeiro with a tour group

I just returned from a 10 day trip to Brazil.  We went to Rio de Janeiro, Iguazu Falls, and the Amazon Rainforest via the city of Manaus.

In this post, I've noted my experience with a tour group in Rio.

We started our trip in Rio.  The day we landed, we took a tour with Brazil Expedition.  We also used this tour company to pick us up from the airport.  The tour started by picking us up from the hotel and taking us to a beach where hang gliders were landing.  We had about 20 minutes to watch hang gliders and sign up for a ride later on.  This part of the tour was rather useless and I felt like it was only there to get us to sign up for something after.

We were then taken to Tijuca National Park.  After a long flight and car ride, it was nice to walk around the park and breathe in the fresh air.  In total, we walked in the park, took pictures of trees and waterfalls, and returned back to the tour van in about 45 minutes.

The next visit was the Christ the Redeemer Statue.  At this time of the year there were very few people and there were virtually no lines to see the site.  We were told that the lines could be very long in peak season.  The tour guide brought us to the ticket entrance area but did not actually enter.  I think she did not enter because she would have had to pay the entrance fee.  While it was nice to walk around at our own pace, it would have been good to have the guide around to give us details and so that we could ask questions.

After we returned to the van, the tour guide gave us a little overview of how and why the statue was made.  I think it would have been better if they gave us this information before we visited the statue.  Perhaps they usually do it while the group is waiting on the line to enter.  I actually learned a bit more overhearing another private tour guide who was walking near us as we entered the site.

We then went to the secret Lapa steps.  We were dropped off at the top of the steps and walked down.  About half a block away from the block of the steps, we had a traditional brazilian lunch.  We paid for our own lunch, which was pretty good.

Overall, the tour provides an easy way to see a few of the major sites in Brazil.  They could improve in time management and I would have enjoyed a bit more information about all of the sites we visited.

Wednesday, May 8, 2013

Better Android logging

Programming is a humbling experience.  It seems like everything I code has room for improvement.

Today, I found out about android.util.log.  This class gives you a better way to print out logging statements.  So, instead of doing,
System.out.println("Look! Code finished, the value is:"+value);
which would print data to the LogCat window in Eclipse with a logging level of INFO, you can do something like,
Log.w("MyTag","Look! Code finished, the value is:"+value);
which prints data to the same LogCat window in Eclipse with a logging level of WARN with a tag of "MyTag".  You can adjust the logging level by using Log.v, Log.d, Log.i, Log,e, Log.a which are verbose, debug, info, error, and assert respectively.  

The best part of this logging is the tag.  With the tag, in Eclipse you can create a filter in the LogCat window, and just see your tagged logging messages.  This is very nice if you are testing on a real phone or tablet which may have a lot of other logging messages unrelated to the app you are testing.

This is much better than just using a System.out.println, because the system messages are sometimes very hard to find among the clutter of other logging output.

I think small changes like this reduces developer frustration and friction, which ultimately leads to improvements in developer productivity.

Sunday, May 5, 2013

What happened to the sports section

When I was a kid, sports was a treat.  My earliest memory of knowing about sports was the 1986 Mets world series.  For some reason, everyone was happy.  Everyone in the city was celebrating together, and I joined in, without really understanding why.  My second earliest memory was watching the Giants win the superbowl in 1990.  By this time, I knew what sports was, watched the whole game, and truly appreciated the win.

From then on, I would watch whatever games (baseball, basketball, or football) that I could.  If you missed the game, since we didn't have 24 hour coverage with ESPN, your only hope was to catch a few highlights at the end of an hour long news broadcast or read a recap of it in tomorrow's paper.  I loved those little morsels of sports.

Why did I like sports?  Mostly, because it was fun to play.  Sports was also an escape into an idealized life.  There were heroes trying to overcome obstacles ending in either heartbreaking defeat or jubilant triumph.  Things were clear and lacked ambiguity.

In the past few decades, sports has evolved for me.  Coverage of sports has gotten intense.  ESPN runs sports games and analysis all day, every day.  With the power DVR, these days I've been able to watch a lot of playoff basketball.  Since I don't care about watching games live, I can watch a 3 hour broadcast of a game in less than an hour whenever I have time.  This is achieved by fast forwarding through commercials, free throws, time outs, and time used for instant replay reviews.  This is awesome.

Analysis of sports is pretty great now too.  After I watch a game, I typically look through twitter for reactions.  As a fan, it's fun to hear others celebrating with me.  It's similar to the experience of watching a game with other fans, without the pain of paying for tickets or going through traffic to get to the game.  The day after a game, I could get a newspaper for a recap, but I also have a few sports blogs which will write a few articles on a game or nba podcasts to listen to.

Sports has gotten a lot more subtle and complicated.  A player used to be judged on merit and beloved for effort.  Nowadays, a fan cannot simply like a player anymore.  A fan must know the player's history, the player's stats and be able to argue why that player has a better salary structure than another.  Advanced stats has convinced us that we cannot even tell who the best players are just by watching.  We need experts to analyze the game and tell us who we should cheer for.

Even if you ignore stats, choosing a player to root for is still complicated.  Every athlete now has a narrative.  We no longer judge them solely on their performance.  We must delve into their hypothetical emotions, motivations, and psyche to conclude whether this player deserves praise or not.

The other day, a new story line emerged when an NBA player, Jason Collins, announced that he is gay.  I suppose that is news, and I hope that it reduces bias and discrimination.  But as a kid, it's not really the sports story I craved for.  As an adult sports fan, I couldn't care less that he's gay.  I'd rather hear about his defensive footwork than what he likes to do outside of the game.

How has sports evolved?  It was a treat.  It was an ice-breaker where anybody could ask anyone else, "Did you see the game last night?"  Now it's as complicated as picking stocks.  It is as emotional as any soap opera.  Its rules are as complicated as our judicial system.  It's players have gotten to be so physically superior to the average person that they scarcely resemble anyone I know.

So is sports better than it was?  I think it oddly takes more effort than it used to.  In the past, I watched every game or highlight I could and read every newspaper article I could find.  This often left me wanting for more.  Now, there's too much.  I don't have time to watch every game I have access to, read every newspaper or blog, and listen to every podcast.  I think the challenge is getting as much sports as I want, but not any more than that.

Sports has changed a lot in my life time.  I wonder where it will go in the future.

Sunday, April 28, 2013

Chasing stack overflows

Recently, one of my programs crashed with a segmentation fault error.

For the user of a program, bugs and crashes are bad.  For a programmer, bugs and crashes are ok. Almost everything I learn is via bugs and crashes.  If I knew a better way to implement something, I probably would have done it that way in the first place.  Watching your program crash and burn or compute at a snail's pace is great motivation to write better code.  And making a code change that fixes your buggy program is a powerful way to learn.  One might call this Crash driven development.

Here are a few things I learned:
1. Get comfortable using debuggers and examining core files.  It took me a bit of time and mental energy to set up the debugger that by the time I wanted to analyze things, I was sort of already mentally checked out.  I took a look at the stack, I dumped some local variables and I kind of gave up.  Using debuggers should be as easy as opening text files and reading what is going on.  

It turns out the reason for the crash could have been found if I spent a little more time with the debugger.  However, I gave up too soon.  The reason I gave up was because I don't have much experience working with debuggers.  I figured I'd be better off just reading my code, running tests and going from there.  Unfortunately, the crash wasn't really reproducible on my development machine, so using the debugger with the crash environment saved was the way to go.

2. Prove the bug, before implementing a fix.  After some time hopelessly trying to reproduce the crash a coworker told me that the machine where my program crashed was set up with a relatively small default stack size*.  He suggested that I raise the stack size.  This led me to a whirlwind of reading and code fixes, and tests that led me to conclusions like, if I overflow my stack, my program will crash.  While that statement is true, it didn't really prove that the cause of my crash was a stack overflow.  I should have spent more time definitively proving the suspected cause of my bug was indeed the cause or not.

3. Ask for help.  One colleague suggested that I had a stack size issue, which wasn't the case. Another suggested that I refactor my code a bit to make it a little more clear what was happening at the time of the crash.  This second discussion led me to re-evaluating a different section of my code and somehow seeing the problem.  Even though the second colleague didn't see the bug, just discussing the issues with him led me to solving the issue.  I have no idea how the brain actually works, but somehow just explaining my bug to another person who just asks questions is enough to re-wire my brain to see previously before hidden problems.

Just as a final note, the cause of my bug was an off-by-one error.  I was reading from a dynamically generated set of data records that could have variable number of fields and records.  I was using the wrong bounds, and sometimes (only on one type of machine and sporadically on some queries) the program would crash.  The fix turned out to be just a one line code change.

*Whenever I face a problem I'm not familiar with (in this case, stack sizes and stack overflows) I  typically turn to Google to help me research stack overflows.  How can I reproduce one, what signs are there that I might be doing something bad, are there messages that will help me identify what is going on, etc ... Unfortunately, searching the internet for information on stack overflows has been rendered virtually impossible by the ubiquitous programming Q&A site, stackoverflow.