Sunday, December 28, 2014

My Pocket Reading for 2014

The year is nearly over, and I just found out that I'm in the top 1% of readers on @Pocket!. I read 2,191,432 words in Pocket in 2014. This is more than double of what I read last year.

What's changed

One of the things that I started using this year is IFTTT. I set up recipes to detect new articles from a source and then automatically save them to Pocket. This is basically an RSS feed. This makes reading easier and less time consuming, because articles just appear without me having to look for them.

Reflections

The end of the year is a common time when you reflect on what you did and think about what you want to do moving forward. I like the fact that I am reading a lot, but I can't say for sure what else I can draw from knowing this much. Maybe, I'd be better off reading less, and writing more? Maybe I should be more discerning about what I read?

In any case, the numbers are in, and they are what they are. Onto the next year !

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.

Sunday, November 30, 2014

Building Tic Tac Toe

This Saturday, I had some free time, so I decided to do some coding.

I thought it might be fun to build a puzzle type of game. It would involve using some complex data structures and algorithms that I have been reading about.

But as I started planning, I realized building a new game from scratch seemed a little bit daunting. Instead, I decided to write a program where I could simple play Tic Tac Toe.

I figured this would give me a decent framework in which I can build more complex games later.

Version 0.1 of this game is done and available here.

Wednesday, November 26, 2014

Hello World Project

I created a new git repository called HelloWorld.

(Here is the README for this project)

Hello World

This repository contains programs written in different languages that simply outputs the classic phrase Hello World.

For each language, I'll try to keep the code very simple and understandable, yet not completely trivial. For example, in the Python program, rather than just calling 'print "Hello World" ', I called a function, created a class, then had the class do the printing.

Motivation

Provide a way to view code snippets from many different languages.

Background

I had a bunch of these "hello world" type programs littering my computer in different directories. It felt messy and disorganized. By putting them all into a single repository, it's easier for me to find things I wrote before, and it looks a lot more impressive (to me at least).

Invitation

Please feel free to send me a pull request. If you are a new programmer, this is a low risk easy way for you to contribute to an open source project. I'm pretty sure that almost any pull request will result in some merged code.

Monday, November 24, 2014

Thoughts On Unit Testing

Adopting unit testing ...

Much has been said and written about unit testing before. Those previous comments convinced me to try to add unit tests to whatever code I was writing. As I have gone from a non-unit tester to a novice/intermediate one, I have observed a few things.

Unit testing instead of print statements.

Every programmer begins by writing a "Hello World" program. By writing such a program, you learn how to compile, run your task and verify your output. As I built more programs, I still had the old "Hello World" verification process in mind, and I often littered programs with print statements. These print statements would give me confidence that things were working as designed. After I was sure a function or class was working as expected, I would clean up these print statements that I had been using to help me develop.

It dawned on me that print statements that I used during development could be replaced by unit tests. If I wanted to check if a function was being called, I could write an "EXPECT_CALL" test, or if I wanted to validate that a variable was updated in some way, I should invoke an "EXPECT_EQ" test.

Advantages to Unit testing instead of print statements.

There are lots of advantages of using unit tests over print statements. You ask a computer to verify output rather than a human (you) from reading a terminal screen. Verifying mundane things over and over again is ideal work to shift from you to a computer. You keep unit tests in your source control even after you ship your code to production. Which means that your tests can be run again and again for all of time.

The only advantage of using print statements is that it is easy to use. This is true in the absolute bare minimum short run. But for any complex piece of code, it is not true. Are global variables easier to use than classes with encapsulated data? Yes, it is easier to directly modify and access a variable that sits in the global scope. However, it is much harder to understand and debug code that relies on global variables. Over time, the hard-to-use classes that contain private data, setters/getters, and other complexities actually become easier to use. You just have to get used to it. The same goes for unit tests. At first, they seem to add a lot of extraneous code for something that is clearly trivial, but over time, they are worth it.

My way of doing test driven development (TDD)

I have heard that test driven development is the way to go. In practice, I have found it a little bit odd to write a test before doing anything. I mean, how do you write a test for a function that does not exist? Maybe this is clear to others, or maybe I am doing things the wrong way, but here is how I do TDD.

  1. Write an interface (either a class or function). The interface should have some dummy implementation so that it compiles and even runs.
  2. Write one test that checks one feature of the interface. This test should fail.
  3. Update the implemntation such that the one test pases.
  4. Repeat steps 2 and 3, until your implementation supports every feature you need.

I find that this process makes me think about a good interface, and it makes me think whether any feature would pass the old YAGNI (You Aint Gonna Need It) smell test. It works for me, for now.

Sunday, November 16, 2014

Becoming a Stackoverflow producer

Being a stack overflow consumer

StackOverflow is an awesome source of information and code samples. It is really easy to be a consumer of this data. If you search on Google, then you will find answers on StackOverflow. It is like magic.

It is good to be a producer

I think it is a good idea to post on stack overflow. While posting an answer, it forces you to really think. Will this answer be easy to understand? Are there any better alternatives? By trying to provide explanations for concepts, I have found many holes in my understanding.

There is also some less tangible benefits from posting. It feels good to give back to the programming community, and it is also fun to have an answer accepted and gain reputation points.

Becoming a producer

Being a producer looks worthwhile, but it is harder than being a consumer. I was always a bit scared/intimidated to post a question or an answer. If I post something, someone may realize how much of a fraud I am and expose my weak programming skills. It is the same fear that I have when I want someone to review my code.

I do not want to be paralzed by this fear. So, this weekend, I decided to find an unanswered question and post an answer. I spent a decent amount of time on it, and my answer is about ten times longer than the question (so I hope it was worth it). I think the trick for overcoming the imposter syndrome is just to practice exposing your code and thoughts to others. After a while, you just get used to it, and your fear of being found as a fraud is just washed away, but all the benefits of producing remain.

Tuesday, November 11, 2014

Using the Android Emulator

First try with android emulator -> too slow

When I first started Android development, I tried to use the emulator, but it was painfully slow. I figured that it was because my laptop was weak (ex: it only had 1 GB of RAM). Luckily, I had an Android phone, so I replaced the emulator with an actual device. Given my weak laptop, I could not be sure if the problem was me or the emulator.

Second try -> still not worth it

After some time, I bought a new laptop with a little more oomph (4 GB of RAM !!!!). The Android emulator performed a little bit better, but it still performed worse than just using a real device. Since the apps I was building did not vary much from one device to the next, this was just sufficient. At this point, I was close to giving up on developing with an emulator forever.

Third try is the charm

With the latest release of Android L, I really needed to use an emulator. The SDK had retired an API that I was using, and I had to depend on a new one. A factory image of the new version of Android was not available for any device I owned. An emulator was my only option, which I feared would bring my development output to a crawl.

Luckily, I found that changing two things really improved the performance of the emulator - from unusable to rather snappy.

  1. Install the Intel Hardware Acceleration Manager. This is available in the SDK Manager in Android Studio, but it did not seem to work for me. So, I manually installed it.
  2. The other thing I did was change the emulator setting to 'Use HOST GPU' and to set the ABI to 'x86' (to take advantage of the hardware acceleration).

With these changes, the emulator has been running really well.

Conclusion

If you are like me, and you have previously given up on the Android emulator, maybe now is a good time to give it a try again.

References

Changes in Android 5.0

Intel hardware accelerated execution manager

Sunday, November 9, 2014

MarkdownBlogger

A New Project

I have been working on a small utility tool that would make blogging easier for me. It's called MarkdownBlogger. In short, it converts markdown text files into html, and then posts those html files to blogger.

Why I have liked working on this project

I have enjoyed this project for a few reasons. First, it's something that I would actually use. Since I spend most of my time building things for other people, it's pretty satisfying using something that I built myself. Also, since I wrote this, I can easily modify it to suit my needs in the future.

I also like this project because I have a well-defined goal in my mind. I want it to do a few things and not much more. With this definite end-goal in mind, I see the finish line in the near future, and I can know when I am done. I think having too many projects in the work-in-progress state can leave a nagging dark cloud over your head.

Now what

Well, I'll keep this blog post short and sweet, just like MarkdownBlogger is meant to be.

Monday, October 27, 2014

Android Deprecated My App

So after getting sidetracked with other upgrades and updates, I finally got to working on updating my Android app to use the latest version of the software development kit, version 21, called Lollipop.

As I started reading about the changes, I realized that Android was deprecating an api called getRecentTasks with a new package called android.app.usage.

At first glance, it looks like this new API will give me a lot of the same information that I struggled to get on my own. Because this API didn’t exist before, I had to do use Broadcast Receivers to periodically check on the state of the phone and figure out which app was in the foreground. I always had some lingering fears that I was draining the phone of its power or could potentially do some other damage to the phone by having something run in the background so often.

So the new android.app.usage API is great news. I can rely on that to fetch data, instead of my own home spun solution.

Of course, things aren’t so simple. Since many phones will not have the latest APIs, I will still have to support using my own home-made solution, and switch depending on whether a phone is ready.

I think it will be an interesting software challenge to refactor my code to support both the old and new sets of APIs, while keeping my code as clean as possible …

Resources I used …

Sunday, October 26, 2014

Weekend updates

I sat down at my computer this weekend to do a little update – testing my Android App with Android 5.0 (Lollipop) and incorporating some elements of Material Design.

Unfortunately, I never really got started.

I lost an hour updating my computer to OS X Yosemite. Then, I lost time reading about and playing with the shiny new OS update. When I tried to start working again, I found that macvim was no longer working. I lost some more time realizing that I needed to update Xcode and its command line tools to get macvim to work.

I was about to get back to my original task of updating my Android App, when I found out that my listng in the Google Play Store required a ‘feature graphic’ (something I didn’t have). So, I fired up Gimp, read through this (helpful tutorial)[http://www.gimp.org/tutorials/Floating_Logo/] and created a very crude image to serve as my feature graphic. If I ever make it big, I’d love to contract this sort of work out.

So, I finally got to the main task, and I started downloading the files for the new SDK. But downloading the SDK has been taking a while, so I started writing this post.

It feels like one of those days where things aren’t working out for me.

Resources I used …

Thursday, October 16, 2014

ELK.stack.on.my.laptop

ELK Stack

Combining Elastic search, Logstash, and Kibana (ELK) gives you an easy way to analyze logged data. The typical pipeline goes like this.

  • Some tasks output logs into files.
  • Logstash monitors those files.
  • Logstash translates those logs into records.
  • Logstash saves the records into elastic search.
  • Elastic search indexes the logged records.
  • Kibana allows you to query the elastic search engine

It is a powerful combination, so I wanted to give it a try.

I followed the steps outlined in http://aarvik.dk/a-bit-on-elasticsearch-logstash-kibana-the-elk-stack/ . You can obviously do the same, but here are my notes on the process (I did this on my Macbook Air).

Get the files

curl -OL https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.0.tar.gz
curl -OL https://download.elasticsearch.org/logstash/logstash/logstash-1.4.0.tar.gz
curl -OL https://download.elasticsearch.org/kibana/kibana/kibana-3.0.0.tar.gz

It is amazing that all of this is completely free to download and try out.

Testing each of the downloads

# Start your (elastic search) engines ... 
elasticsearch-1.3.4/bin/elasticsearch
curl -X GET localhost:9200
curl -X POST localhost:9200/person/1 -d '{ "info" : {"height" : 2, "width" : 20 } }'

# Testing logstash with command line arguments:
logstash-1.4.0/bin/logstash -e 'input { stdin { } } output { stdout { codec => rubydebug } }'
# or run with a config file
logstash-1.4.0/bin/logstash -f ./logstash.conf

I used the same logstash config file listed in the reference page I noted above. However, I did change one of the inputs to read from /var/log/system.log . At this point, I just wanted it get input from a file I knew was geting updates.

Setting up a local web development server - apache

In order to use kibana, you need a web server. Luckily apache is pretty much ready to use on Macbooks. I followed steps outline in http://ole.michelsen.dk/blog/setup-local-web-server-apache-php-macos-x-mavericks.html. Update The setup is slightly different for Yosemite.

I followed that site to get my server started, until my browser said "It works". Then I configured kibana to use my elastic search engine. To do this, update kibana/config.js to have this line:

elasticsearch: "http://localhost:9200",

This replaces -->

elasticsearch: "http://"+window.location.hostname+":9200",

This works because everything is on one machine. Finally, I moved the kibana folder over to be read.

mkdir ~/Sites
cp -r kibana-3.0.0 ~/Sites/
sudo apachectl start

You should now be able to visit your kibana dashboard at http://localhost/~username/kibana

Conclusion

Getting the ELK stack up and running was really easy. Hopefully I can think of a way to put this cool technology to good use.

Resources I used ...

  • http://aarvik.dk/a-bit-on-elasticsearch-logstash-kibana-the-elk-stack/
  • http://ole.michelsen.dk/blog/setup-local-web-server-apache-php-macos-x-mavericks.html

Wednesday, October 15, 2014

Blogging with Vim, Dropbox and StackEdit

The past

I have been using Blogger (formerly blogspot) for a while. It’s the obvious choice for any new blogger. It’s free, it’s easy to use and it’s from Google.

However, I have always sort of hated using the graphical user interface provided by Blogger. It doesn’t work offline so well. Sometimes it crashed and I lost some work. I couldn’t use my vim text editing skills. Jumping between the WYSIWYG and the HTML code mode sometimes caused erratic behavior.

The future

Given my distaste for Blogger’s given tools, I am trying out to find a new workflow. It’s a bit convoluted for now, but these are new steps that I am doing now to write posts:

  1. Go to a folder within my Dropbox directory called Blogposts.
    I will be creating files locally, which will be synchronized (backed up) to my dropbox folder.
  2. Write the original blog post in Markdown with vim.
  3. As I write, I preview what the formatted post looks like with Chrome and the Markdown Preview Plus Chrome extension.
  4. When I am done editing, use StackEdit to a) open this file (available through Dropbox) and b) publish to blogger.

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.

Monday, September 1, 2014

State of affairs - consequences of being overworked

For the last few weeks, I have been overworked.

Our team was given a deadline to build and release a product. But there was too much to do in the given timespan. It led to longer hours, less testing, more technical debt and created at least one burnt out programmer.

Of course, this affected my life outside of work. I didn't have the time, energy or motivation to work on any side projects. Instead, I spent my time mindlessly watching television or fiddling with my fantasy football team.

I hope to find a better balance as we start up the next set of work items, which will most likely include fixing bugs with the product we just rushed to complete.

Saturday, August 2, 2014

Hiking the JMT

I watched the movie Mile ... Mile & A Half last night.

It's a documentary about a few artists who hike the John Muir Trail. This is a 200 mile journey that takes about a month to complete.

The film captures a lot of beautiful scenes. My wife especially loved the views where you looked through a canopy of beautiful trees to see a sky full of stars.

Similar to other movies I have recently seen, this movie is about people going through a hard journey for a great pay-off. The obvious pay-off is the ability to experience amazing natural scenery. A secondary pay-off was the ability to interact and get to know some friends.

The film also highlighted that the painful journey helped accentuate the payoffs. Near the end of the journey, a few friends joined the team and hiked the last bit of the trail together. These newcomers expressed some regret that they hadn't paid their dues by doing the whole trail. They said that since they hadn't gone through all of the pains, they couldn't seem to enjoy the trail as much as their more worn out friends.

I'm a person who seeks to minimize pains as much as possible. The purpose of a lot of my programs is to remove the pain of manually doing something.

Yet, watching this movie makes me feel like pain isn't something we should actively avoid. In fact, hiking the John Muir Trail is something I would love to do some day. Pain and all. 

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. 

Tiny versus Somm

I saw two movies over the weekend. Tiny - a movie about living small and Somm - a movie about sommeliers trying to pass the Master Sommelier exam. I like watching people putting forth great efforts, so I liked both movies.
Each movie explains the journey of people trying to achieve something. In Tiny, a couple attempts to build a house from scratch. In Somm, several sommeliers are trying to pass an extremely difficult exam.

Each adventure has clear rewards. Becoming a Master Sommelier opens career doors and subsequent financial gains. Building a tiny functional house gives you an economical place to live. 

The perception of being a Master Sommelier is different from building and living in a tiny house. A Master Sommelier is held in high regard. Owners of tiny houses are often met with ridicule and have to defend and explain their living choices to others.

Another difference in the two adventures was the way the participants viewed the journey. Tiny house builders seemed to appreciate the journey of building their houses. Whereas the Master Sommelier candidates viewed studying for the exam as a painful means to an end. In the Tiny House movie, a couple who was thinking of going separate ways was brought closer together by the process of building the house. But the journey of becoming a Master Sommelier put huge strains on the personal relationships of each candidate. 

I'm one of those people who think the journey is as important as the ending. I also prefer beer to wine, and my smelling and test sensitivity is unrefined. So, the story of the tiny house resonated with me a bit more than the one about sommeliers. But that's just my opinion. Go and watch and decide for yourself!

Related Posts

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.

Sunday, July 13, 2014

Refactoring in Android Studio

I'm a bit of a dinosaur. My preferred development environment is unix. It's fast. I know how to use all of the tools I need to use. It's on both my home and work computers.

Nevertheless, I have been trying to evolve. I've been doing all of my Android development using Android Studio. It has been going well. I love the code completion. It's the only way to visually add widgets to an app and see the xml updates in real time.

Recently, I ran into a snag. I tried to use the "Refactor" feature in Android Studio to rename one of my classes from "Broadcast_receiver_handler" to "BroadcastReceiverHandler". The file and class name were updated and references seemed to be as well. Since it worked so well, I went on to refactor a bunch of other classes.

Today, while testing the app, I noticed some things weren't working so well. Without going into much detail, I found out that there was one place where the name for my Broadcast_receiver_handler was not updated, the AndroidManifest.xml.

One factor that made debugging more difficult was that Android Studio deleted and added files during the refactor process. I would have rather it did a "git mv" so that diff's would work better.

These are minor issues. I'll continue using Android Studio. It's only a 'beta' release now, so it should improve over time. But for some things, like global file and text manipulation as well as git commands, I will stick with a unix terminal.

Tuesday, July 8, 2014

Pros and cons of Unit Tests

I did a code review for a co-worker today.
I suggested that he refactor his code to make unit tests possible and then to add unit tests.

He argued against adding the tests. Here are some of his arguments against unit testing along with my responses.

Against Unit Testing Responses.
You're making the code more complex!

You want me to add factories and abstract classes and so on, just so things are more testable. You're asking me to rewrite a lot.

I don't want to re-write code that already works.
This is true.
Some things got more complex.

But see, writing code to become more testable, has the side effect of making the code more modular.

And making code more modular is good. 
You have to learn a lot to get going.

New frameworks, new tools, new concepts. All of these new things make things more confusing and complex.

This might be a fad that we forget about in a month or two. 
Learning is part of the job of being a programmer. It's one of my favorite parts.

Maybe the framework and tools we use for testing will change over time.

But you can't argue that the concepts are a waste to learn about.

Even if you don't want to use the concepts, it's cool to understand and learn. No?
Writing test code is a pain in the neck.

You are doubling my work load with no increase in production!
I disagree.
Writing test code is fun.
I've already tested it.

Trust me, it works. Why write a test?
Writing unit tests allow someone else (even a dumb machine) to test your code.

Otherwise, if I have to change your code, I'll have to stop by your desk and you'll have to tell me about it. Isn't that a waste of your time?

Sunday, July 6, 2014

Android Testing

For the last few days, I have been adding more tests to my Android projects. During this time, I have come to the conclusion that:

Unit tests are impossible in Android.

Maybe I should qualify that statement a little bit. Here's something that is more accurate:

For me, setting up unit tests in Android is so difficult, and running them is so slow, and learning and integrating external tools/code is so arduous, that it doesn't seem worth it to hack together a true set of unit tests.

In the mean time, here are the things I am doing in regards to Android testing.

1. Sticking with the emulator
I am running all of my tests and the app in the emulator or an attached physical device. The downside of this is that things are slow. I briefly tried to use Robotium, a highly regarded test framework that helps run your tests outside of the emulator. Maybe I will try again in the future. For now, I am wary of investing more time to hunt down external tools to get this to work.

2. Using the simplest test case that is needed.
I can't seem to keep track of all the test case classes. Here are the ones I use in order of increasing complexity and dependency on Android APIs:

TestCase > AndroidTestCase > ActivityUnitTestCase > ActivityInstrumentationTestCase.

For any given class that I'd like to test, I try to use the simplest test case that works. It seems like this would be the best way to isolate issues and keep things running as fast as possible.

3. Refactoring my code
In the hope of making each class as simple as possible, I have been refactoring my code. In the least, I have been adding comments to say what dependencies a given class has which tells me which test case class is required.

4. Waiting.
I started developing an Android App just to see how things work. It's a learning adventure, not a business one. This is why I can afford to simply wait for the product to improve.

In the future, I may upgrade my machine, which will speed things up. Google may add more libraries, update Android Studio or modify the testing framework to make things easier.

Thursday, July 3, 2014

Google permissions

A list of items Google Search needs access to. Devices, Identity, Phone, ...
This morning, the Google Search app on my Android phone had an update. Upon reviewing the update, I saw that the app wanted access to just about everything.

I tried to take a screenshot of the things it wanted access to, but it wouldn't fit in one screen. In addition to the picture, it wanted access to "Device ID & call information" and "Other". 

It seems like they asked for permission to access just about everything on my phone. They will know who I am "Identity", where I've been "Location", who I've been in touch with "SMS" and "Phone", what I look like "Camera", and they can send it all back to the cloud "Wi-Fi Connection". 

If it were any other company, I wouldn't install an app that requires this many permissions. But they are Google, and I've already gotten used to the idea.

At what point does Google Search become spyware?

Disclaimer
After I took the screenshot, I, obviously, accepted the conditions and updated the app. 

Related Post

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.

Monday, June 16, 2014

Playing with MEAN

I heard about MEAN some time ago, and today I finally installed it and played with it.

There's lots of reasons why I wanted to get into using MEAN. It's all Javascript, which means, it's good Javascript practice for me. Every self-respecting Javascript-developer should try to build at least one Node.js backed app, right?

It calls itself a Fullstack framework. I like the sound of that. I think it means that I'll have to think and learn about all the pieces involved in building a web application. Hopefully, MEAN makes the learning curve a little less steep, yet doesn't hide so much that I depend on the framework too much and never learn anything.

Just to hedge my bets, I also have a simple app that I'd like to build for myself. If all goes well, I'll 1) build an app that I find useful 2) learn. What more can a developer hope for?

And finally - the results of day 1:

The Good

I got the application running on my local machine. I was also able to set up a database on MongoHq and then I deployed the app with Heroku. My app, which is the same as the starting test app, is up on http://pocketfeeder.herokuapp.com/#!/ .

The Dumb

For quite a while, I couldn't figure out how to log into the test app. After an embarrassingly long amount of time, I realized that I just need to register a username first. When trying new things, it's impossible to not feel dumb sometimes; you just have to embrace it.

The Frustrating

Googling things with the term "MEAN" is horrible. If you didn't notice, MEAN is a real/common word, and searching with it gives pretty shoddy results. I know MEAN is a catchy acronym, but searching for a more unique word, perhaps NEMA or something like that, would have made Googling a lot easier. 

The Conclusion

The experience was positive, and I plan on playing with it in the future. So, there is no conclusion, just yet.

Sunday, June 15, 2014

Android Studio - review after a few months

I've been using Android Studio for a few months now, and I've been enjoying the experience. Here are a few things that I have liked about this IDE.

I love Vim, and IdeaVim brings Vim to Android Studio as a plugin. I'm not sure how long I can tolerate using any IDE if it doesn't have Vim support. This isn't an indictment on any IDE that doesn't support Vim, instead, it's more of an handicap of mine.

A terminal is available as one of the windows in the IDE. I use it for doing quick unix commands like grep and git log. Screen real estate is always scarce, and having it inside the IDE is just a little bit tidier for me.

Viewing a layout in "Design" mode is great. You can drag and drop from a selection of Android widgets, which automatically updates the the layout xml. Conversely, if you update the xml layout file, you can see the changes in the layout in the design editor. This allows you to quickly browse through different widgets without having to manually type in names, and to see changes in real time.

Android studio allows you to create multiple run configurations. For any project, I create one configuration for running the app and one configuration for testing the app. I suppose it is just philosophical, but I like a single project to hold all of the stuff needed for running and testing.

One downside of moving from Eclipse to Android Studio is that it seems like an irreversible change. Maybe if you are an expert in migrating files, you can easily jump back and forth between them, but it seems like a one-way street to me.

After 6 months of usage, I have like using Android Studio. We'll see how I feel about it over some more time ...

Related Posts:

Android Studio - Preview of Future

Taking notes

In this post, I'll review the tools I use for taking notes. This is what I have been using for the last few months. It's been working for me, maybe it will work for you.

I start with Google Keep on my phone. With the on-screen widget, this app is the fastest thing for jotting down a note. It seamlessly syncs to a cloud backend without having to press save or send. Writing a note down as quickly and easily as possible is probably the most important thing for me. If it's too hard or slow to jot down a note, I will inevitably: 1) forget what I wanted to note, 2) forget what I was doing before I was writing the note, or 3) give up on writing down notes. 
 
With that said, another "killer" feature of Google Keep is the ability to set reminders. This feature transforms Google Keep into a light-weight appointment calendar. Another nice feature is the ability to archive notes. This helps me keep the most important notes in the foreground, while letting old notes fade into the background. I often combine these two features to push a thought into the background (archive a note), but knowing that I will revisit the subject later (by setting a reminder).

At the end of every day, I transition my notes in Google Keep to files in my Dropbox folder. I do this by opening the web version of Google Keep and using the terminal to view my local Dropbox folder. I review notes in Google Keep and update corresponding files in Dropbox. Where Google Keep is used for the more recent things that were on my mind, I use the files in Dropbox for more long term notes. Of course, the nice thing with Dropbox is that I edit local files that I know are being backed up in the cloud (all auto-magically). 

The last thing that I haven't found a good solution for is an app for sharing notes. Trello seems like the leading candidate, but I haven't used it enough, with others, to be sure. 

Monday, June 9, 2014

Display link issues

Today, I am giving a status report on my experience connecting my Macbook Air (running OS Mavericks) to a Anker USB hub with usb to display link adapters to 2 external Dell U2410. 
See the image for a schematic of the major pieces. 

DisplayLink has issued warnings that things aren't perfect: "Unfortunately there are still issues using multiple DisplayLink displays on OS X 10.9. A summary of these known issues can be found in this article."

My experience has been random. 
Sometimes, it works perfectly. 
Sometimes, only one of the external monitors get a signal. 
Sometimes, things work fine and then one of the monitors just goes blank. 

I think things work better if I start with my laptop completely OFF, and things work a bit worse if I start from a laptop that was just in Sleep Mode. 

I'm living with it, but I hope things improve in the next version of Mac (OS Yosemite).

*Update* - July 4, 2015 - I tried to use this set up today, and it didn't work. The external monitors were recognized, but they would show a blank screen. I tried restarting, unplugging, etc... but it was to no avail. I finally got it to work by reducing the resolution of each monitor several notches worse than their optimal settings.

Monday, May 12, 2014

Configuring

As a programmer, I only spend some of my time actually typing code. This weekend, I spent time on one of the more painful parts of programming, configuring. 

I wanted to try switching from Eclipse to Android Studio. I thought, or at least hoped, switching over might be a seamless process. There are deceptively simple buttons in each program for Exporting and Importing projects. So, I pressed those buttons, and voila, my project was viewable in Andriod Studio. Unfortunately, but not quite unexpectedly, the project wouldn't build. 

Build dependencies weren't correct. I was missing some. After adding them, I then created "Multi dex" duplicates error. While resolving the dependencies issue, I must have pulled in some updated and incompatible libraries. Incompatible libraries meant I had to update some code.
Eventually, I was able to run my projects in Android Studio, so Mission Accomplished. 

Configuring a system helps expose leaky abstractions. As you program, it is easy to just include/import anything just to make things work. You eventually forget what code you are pulling into your package. By creating explicit dependencies with gradle, I became a bit more aware of what is going on under the covers. 




Saturday, May 3, 2014

Falling behind

It's been a while since I posted.
So what has this programmer been doing?

I went hiking and camping along the Inka Trail.
I got busy with researching a home improvement project. (It looks like I will be doing home renovations in the near future.)
I spent more time on my work projects.
The last thing that has drained the remainder of my time is the 2048 game, which I have beaten and hopefully gotten out of my system.

So blogging, writing hobby code, and studying programming have all fallen by the wayside.
I'd like to say that I'll start picking it up again, but I'd rather not promise something that I'm not sure of. As they say, time will tell.

Saturday, April 5, 2014

Can I program

When I was in college, I took an entry level computer science course, something like Java 101. I don't remember what I got, but I think I did OK and I wanted to learn more. So I signed up for the next level class, something like Java 202, which covered things like sorting, data structures and algorithms. I had a much harder time in that course, somehow managed a B-, and decided that computer science wasn't for me.
GOAT SHEEP by jlwelsh, on Flickr
Creative Commons Attribution 2.0 Generic License  by  jlwelsh 
Later on in life, out of necessity, I began writing some basic shell scripts. Because it made my life easier, I kept at it and began writing some python programs. Since I didn't know any better, I interviewed and got a programming job. To recap, I started as a mediocre computer science student, evolved into a hobby programmer, and now I find myself as a professional programmer.

There is fascinating blog post from Jeff Atwood which suggests that there are people who can learn to program and those that cannot. After my brief computer science forays in school, I would've resigned that I'm one of those people who cannot program. Luckily, I didn't read that article until after I started programming.

Instead, I will go with the advice of Mr. Descartes, who famously said, I think, therefore I am. For me, I program, there I can program.

At least, that's what I said whenever I get a case of Impostor Syndrome.

Friday, March 21, 2014

Components to my home office

After some consideration, my wife and I have decided it is about time ... to upgrade our home office.

Our current situation is composed of laptops used on the living room couch or dining room table, which can be very uncomfortable. So, I've been researching the components needed for a home office. Here are the things I will get in the order in which I'd get them. 

Step 1. Desk
Img of Elfa Desk
We are thinking of getting an Elfa setup from the Container Store. For us, the key features are its dimensions - narrow (to fit in a small space) and tall (to effectively use all of the space).

Another consideration, which didn't quite make the cut was getting a desk that supports sitting and standing. I gave on the idea, due to cost and the amount of space it would take up.

After we have a desk, one of us can at least use the desk instead of the couch or dining room table. 

Step 2. Monitors
I bought two 24" Dell Ultrasharp monitors (U2410). We bought them refurbished from Dell, and they are a few years old. For these reasons, we ended up paying just under $200 each for them, which is a lot less than the full price.
Shopping for monitors is difficult. How much do you want to spend? What level of performance do I need for what I do in my apt ... ?  Rather than rehash the technical info, I'll boil it down to these reasons for picking these monitors.
  • These monitors are supposed to be good for office work and programming, which is our primary use case.
  • They are from Dell, and Dell has a good reputation for monitors.
  • While these are still widescreen monitors, they are slightly taller and less wide than a standard HD television, which is better for us (1920x1200 as compared to 1920x1080, if that means something to you).  
As an aside, I really wanted a PLP (portrait-landscape-portrait) 3 monitor setup, but I couldn't make it work for me (not enough desk space).

Step 3. External Keyboard and Mouse
I got the Microsoft Wired Keyboard 600 and a Logitech M100 USB Optical Wired Mouse. These are just about the simplest and cheapest options you can find.

So far, the mouse has worked with my Macbook air without any problems, but the keyboard hasn't worked so well. I can't seem to map over the ctrl, alt, and other modifier keys to things that the Mac likes. 

Step 4. USB Hub
In order to connect my laptop to the monitors I got two Anker USB 3.0 to HDMI / DVI Adapters and this Anker USB 3.0 7-Port Hub. I'm already using 5 of the ports (2 for 2 monitors, 1 for a mouse, 1 for a keyboard and 1 for a cell phone charger). The best thing about a hub is that I can easily swap out my wife's laptop with my laptop by switching one plug.

The usb to dvi adapters depend on software from DisplayLink. So far, this has been a bit buggy. With my Macbook Air, only one of the 2 external monitors work at a time. Things work better with my wife's windows laptop. However, we still haven't figured out how to make things work seamlessly when connecting to our work computers over Citrix.


Step 5. Computer
Since we have laptops already, getting another computer for a home office isn't necessary. If we feel that the constant plugging and unplugging of laptops is difficult, maybe we'll get a standalone computer. Getting a computer opens up another can of worms, so I'll just put it off for now and let my future self think about it.

The end or the start.
So far, the home office is nice to have. I think spurs me on to work more. The worst part about it, other than the cost, is setting up multiple monitors. The current level of hardware/software feels a bit hacky.

Sunday, March 9, 2014

A programmer's review of Jiro Dreams of Sushi

Last night, I saw Jiro Dreams of Sushi. It is a beautiful documentary about Jiro, possibly the best sushi chef in the world. I'd recommend this movie to anyone, especially if you are looking to be inspired.

Naturally, I compared Jiro's life as a chef with my life as a programmer. Here are some of my takeaway thoughts.

What's love got to do with it? More than love, I think effort, practice and reflection are the important inputs to Jiro's success. Some people may hear this line from Jiro, "You have to fall in love with your work", and think he is talking about the cliche, "You should find a job that you love". It may be a bad translation, but I think these are vastly different statements.

Finding (and looking for) a job that you love is nearly impossible. Love takes time to develop. How can you love being a chef or a programmer after one day or one hour? It takes a long time to understand something to know it enough to fall in love with it. The effort and associated pain of learning then mastering a skill creates a love.

Natural talent is very important, but you can still succeed with hard work. Jiro talks about another famous chef who has a better sense of smell and taste than he has. With better natural skills, Jiro believes that he might have been a better chef. Nonetheless, because of his incredible work ethic, he is still the greatest sushi chef in the world.

I know there are blogs and studies about people who can program and those who simply cannot. Maybe it is a case of Impostor Syndrome, but I often feel like I am one of those who cannot. And yet, somehow, I am a professional programmer. If you work hard, you can accomplish something.

Think about the client. There is a scene where Jiro is serving sushi. A food critic notes that Jiro watches his clients eat. If a diner is left handed, Jiro will place the next piece of sushi on the left side of the plate to make it slightly easier to eat. Does the client notice or care? Probably not. The important bit is that Jiro is always trying to improve the dining experience.

Practice, practice and practice. There are many more gems that you can take away from this movie, but this is my favorite. Whatever you do, practice it. You should improve, and that improvement is very rewarding. Of course, you need to practice smartly. Every night, Jiro reflects on the day and thinks about ways to improve. What a great lesson. Even the best chef in the world, at over 80 years old, is trying to improve.

Wednesday, March 5, 2014

Learning on the internet

In the few years that I have been programming, I have learned a mountain of stuff; yet there is an ever expanding galaxies of things that I don't know.

I'm always trying to bridge this gap by learning. Lately, I've tried out two platforms, Codecademy and Coursera. These are both excellent and free resources. The material on both sites is amazing. Neither are magic. You still have to work to learn the material, but the fact that this sort of material is out there is amazing. Stop surfing the web and try it yourself.

Coursera
Coursera has a number of courses given by college professors. The courses have video lectures, homeworks and exams. There are also online discussion forums where students are asking/answering questions moderated by administrators of the course.

I've worked through a few courses (Computer networks, Algorithms, and Databases). I cannot say I completed the courses, because I didn't do all the lectures and exams, but I think I still learned a lot, which is the purpose of it all.

Coolest things about Coursera - the video lectures are insanely good. You get lectures from professors from the best schools in the world for free. If I were a paying student, I'd feel a little bit cheated!

Worst thing about Coursera - I'm not sure why, but some of the courses start and end on a fixed schedule. Once the video lectures and other material is created, I'd like for the material to just stay online so that I can go at my own pace. I found that some weeks would go too slow, and I'd be waiting on material and some weeks would go too fast. But this is a minor gripe, as many of the courses repeat.

Codecademy
Codecademy has a much narrower focus, to teach people how to code. Instead of video lectures, homework and tests, they have a very nice text editor that you can use to interactively code and learn.

I took the web course which focuses on HTML and CSS. Relative to my experience it was a little bit too basic, so I wanted to skip ahead a bit. In any case, due to the fact that it was gamified (I got points and badges along the way), things felt fun and I continued until the end.

Coolest thing about Codecademy - as mentioned before, the editor is great. It allows you to immediately try out the code you are learning without setting up a test development environment.

Worst thing about Codecademy - I haven't encountered anything bad yet. I wonder how things will go as I advance. I will take the JQuery course and see what that's like.

Conclusion
I plan on continuing to use both Coursera and Codecademy. I can't believe such great resources are free.

I imagine that this will be the future of learning. It is much more efficient, convenient and scalable. I am not sure if it is as effective as the traditional mode of learning, but it's working for me. Give it a try!

Sunday, March 2, 2014

Posting flickr photos

I have been trying to add more pictures to my blog. The problem is that I have so few good pictures of my own to share.

As usual, the internet has the solution. Using Flickr, I can find interesting, apt, and free pictures. For example, the image in this blog is from Flickr.

As a good netizen, I'd like to give proper credit to whoever has generously created and shared this image for anyone to use. For any image I post (if all has worked well), you should see a few things:
  • a clickable image that links back to the original.
  • a creative commons attribution.
  • a credit to the original artist linking to their flick account page.
As you might guess, getting this image with all the proper credits is a bit more difficult than just cutting and pasting, but it's not so hard either. Here are the steps I take.
  1. Do an advanced search on Flickr.
  2. Enter your search terms. 
  3. Scroll down to the bottom of the page, and make sure you turn on all these options (Only search within Create-Common-licensed content, Find content to use commercially). 
  4. Click Search.
  5. Click on one of your search result images. It should bring you to another page. Copy the web address.
  6. Go to http://www.imagecodr.org/get.php, and paste in the web address. 
  7. When you hit submit, you should get further validation that the image is free to use, and some html code that you can cut and paste into your blog. 

Saturday, March 1, 2014

Enough with the statistics

For the last couple of weeks, I have been rolling out a change where my Android app would connect to an App Engine Backend.

The reason for this change (as always) was for me to provide better functionality and for me to learn.

Unfortunately, an unintended consequence of this change is that I have become totally obsessed with tracking the statistics related to my app. (I'm hoping that if I write about it now, I can clear my head of these thoughts and move on.)

Before, I didn't really pay any attention to how many users installed my app. The numbers were always so small that there wasn't really that much to examine.

After connecting my Android app to this cloud application, I noticed that I was exceeding the free datastore limits everyday! In particular, I was trying to do more than 50,000 datastore write operations per day. This was surprising. I checked the number of people who installed my app, and it was an order of magnitude higher than when I last looked. It still is a pretty small number, but geez, I couldn't believe that I had a real life scalability issue!

I then went on a downward spiral of religiously checking stats related to my app. This can be very addicting. Also, the marginal benefit of looking at your stats every day as opposed to once a week or month was very small for me.

I eventually pulled my head out of the mud and started thinking about solutions for my resource limitations problem.

Technical fix. I've made a bunch of changes. I removed nice-to-have but not necessary attributes (like update time), removed indexes created by default that I didn't need, and modified indexes to optimize for minimal writes but slower query speeds.

Financial fix. I haven't made any changes yet. If the trend continues, I may need to start paying for some support above the free quota. Ideally, I hope that my small ad revenue could pay for this app, so that it was self sustaining.

In response to these statistics, I've spent a decent amount of time optimizing my code, way too much time day-dreaming, and not enough time working on something else. I want to move on now. Getting cool stats feels good, but it's not what motivates me to build applications.

Onto the next buggy feature!

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. 

Sunday, February 16, 2014

Am I a spy?

In a recent blog post, Scott Hanselman denounces "Adware, Malware, Spyware, Crapware" as pure evil. I totally agreed with him, or so I thought.

Recently, I updated one of my apps, and one of the reviewers said that the app now contained SPYWARE. Hmm, since I don't think I'm writing spware, maybe the issue isn't so black and white.

I can go into the my specific details, but I'll discuss a more well known example.

Google Now is an Android App that delivers personalized 'cards'. The cards give me information on the local weather near me, websites (that I read) that that have new blog posts, the latest sports scores of my favorite teams, and they even used to show how many steps I walked in the recent past.

Google Now was creating this content by reading my email, tracking my browsing history, and more or less spying on my life. The app is doing things that I don't know about and that I may or may not want. I think it's fair to say that Google Now is a type of spyware; yet, I think Google Now is a pretty great app.

Name-calling seems to always trivialize things, so I shouldn't get too hung up on whether someone calls me a spy or not. Even if they do, maybe it's not so bad.

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.

Sunday, February 9, 2014

Opportunities

If you build it, they will come. 
It's a classic line from Field of Dreams, and it happens to be true for software development.

I have a small app on Google Play Store. As of now, less than a 1000 people have even tried the app. Despite the humble statistics, I've begun to get more and more inquiries about the app.

They are coming. Who are they, you may ask. Well, here is what I've been seeing so far.

Clients. I've had some bad and some good feedback. Once, someone told me that the app was crashing and how to reproduce the crash. I immediately (well, in the next few days), worked on the fix and thanked them for the help. The best feedback is when I hear of new features to implement. It's great to know that you are building something that matters.

Promoters. (Scammers?) Since the moment of my initial publish, there have been people asking me if I'd like my app reviewed by them. They'd promote my app, and I'm not sure what I'd have to do for them. This always felt disingenuous to me. If you want to review my app, you certainly don't need my permission to do so. I'm not sure if all of these solicitations were actual scams, but it's best to be cautious with these sort of things, so I typically just didn't reply to these folks.

Developers. Other developers have asked me if they might build some new feature for me. This is cool. In true open-source fashion, the project takes a life of its own and is built by a community. But this is a project that I'd like to build. I fear that I give others access to the code to build on and bug fix, I'd end up maintaining more than building. I guess I haven't fully adopted the open source spirit.

It's pretty cool that I can work on something at home and then generate interest from people all over the world. It motivates me to keep building, as it accumulates to be something that can take a life of its own.