Saturday, September 25, 2010

One day of a programmer

Last Friday I spent most of the time writing an application for Android. In short I was to write an application for Android and Foursquare (a location-based social network), for an assignment of CS3246 - Hypermedia and WWW. I feel obliged to record the experience.



I started with  trying an OAuth library for Java called Scribe to connect to Foursquare API. It was recommended by Foursquare that we use it instead of the Basic Authentication method, which just pushes the username and password to through http. The author offered a sample on how to work with it & Foursquare. The first step would be trying to deploy the sample on my computer. I copied the sample code, added the .jar library file to the project's BuildPath. No compile error. Good. Run. Boomz, I got ClassNotFoundException (or something like that). Admittedly, I didn't use external library (.jar file) before, so I wasn't sure if I did everything correctly. So I went to Google and researched on it. "So the BuildPath and the ClassPath during running time is different. I didn't know that," I thought in relief. However, it turned out that I've done the thing correctly; the library was in ClassPath already! Why did I still get error? I searched and searched again for more similar case. Spent quite some amount of time on searching, yet I couldn't understand why some class definition wasn't found. "I've included the library already!" I kind of screamed in my mind. I would then thought the problem was from the sample source code? So I searched about it on Google, but found little to nothing. After fruitlessly searched for solution, I came back to the project's page on GITHUB, found a link called Getting Started. I missed it before because the content looked mostly the same as the sample file, just broke into steps with instructions. "Ahhh, I need to download another library necessary for it!" (I wished it was Complile Time Error..) Thankfully, it solved the problem. Now I could authenticate and draw some personal information of the user from Foursquare.

However, as I'm developing a phone app, the authentication is supposed to be x_auth, which is a little different. Ehh, I'm not familiar with OAuth, and / or x_auth! I tried to imitate the code from the sample, and tried to find if there is any specific method for x_auth. There was one in the library for Ruby, so I expected similar thing in this Java library. But the library didn't have any documentation! I could guess little to nothing from the functions' signature, especially when all the parameter types were obscure. (Now I think it just doesn't support x_auth, which explains why there is no example using x_auth..).

Thinking that I advance any further with OAuth right then, I decided that I should familiarize myself with the Foursquare Java library first. I turned out to be a greater pain! The whole thing was a big mess. I didn't even know where to start. I guessed the first thing would be creating this Foursquare class. But the constructor takes in some random parameters that I had no clue about. So I dug a little further into these parameters. Ultimately, the parameters' type were String... What value am I supposed to pass in? I tried my luck by passing some value that I thought reasonable, but it wouldn't work. Now I appreciated the need of documentation. I hopelessly spent quite some time playing around with the library, only to gave up later.

I took a break and did a little research on Foursquare API, hope to get some small tutorial or sample application. It crossed my eyes from some article that the Foursquare application for Android itself is an open source application. "Why don't I read its code and see how it uses the library?" I went to its Google Code site, downloaded the application and tried to hack the code. I admit that it is a huge program, with lots of classes and libraries.

First step would be successfully logging in to Foursquare and extracting some information from the site. I proceeded to read its main program imitate the steps needed to do these things. I would go back and forth between the main program and the library, trying to decode what was happening, and what were the meanings of the classes, of parameters and stuff. I must say it was no where near comfortability.  Mostly because of the overwhelming amount of new information needed to process at a time. (Fun Fact: the first thing I noticed was that, Foursquare used Basic Authentication itself. So why did I try so hard to use OAuth? Sad.)

It would be easier if everything was simple and clear, however, sometimes things could be very misleading. Say, there was a version string should be passed into the constructor. I thought (when I tried to play with the library myself) it would be the version of the app, or version of the API, and might have the format of "1.0", or "1". Turned out it was Android package version, or something like that. The worser part is that, it had a very weird structure. I'd be genius if I knew I needed to part something like this: PACKAGE_NAME + ":" + String.valueOf(pi.versionCode);

Now I deeply appreciated the need of documenting the code. Guys, let's comment and document our code nicely, so that the next guy who uses it won't suffer so badly. Or at least he won't swear WT* every 5 minutes.

I kind of gave up with it already. Suddenly I saw a file named FoursquareAPI.zip on my Desktop. Uhm it was the Java API file provided by the teach staff. I thought it was the same as the thing I downloaded from the Foursquare official source, so I never touched it. Thankfully I tried it. To my delight, there was an API introduction file in the zip file. I opened it and found a sweet sort sample program using Foursquare API. Thanks god (& my lecturer), I'm saved. It turned out that the API provided wasn't the same as the Java API provided by Foursquare. However, it was much simpler and easier to use. It could be found here http://code.google.com/p/foursquare4j/. It doesn't always happen that the official thing is the best thing.

I quickly followed the sample program provided and deployed it to my Android application. Within 15 minutes I was able to login, print out the tagged venues around the user's location. I forgot to include the INTERNET permission so it didn't run the first time, but after few minutes I figured out and it worked seamlessly. Finally got something work. Compared to all the frustration & tiredness I faced before, it felt so good. Felt so delighted.

"Let's try to mark these location on the Google map," I continued. I've created a simple app to display and tag location in the map before, so this part is supposed to be easy and quick. I opened that app, copied the code that (I thought) necessary to my app, modified the code a little so that it would display venues extracted from Foursquare. And Ctrl + F11. Boomz. The app crashed. OnClassDefFoundException again! Ok sweet, maybe I haven't included some library? The problem wasn't the same because both of the map code & the piece of code using Foursquare API worked independently. I checked the RunConfiguration, but seemed that Eclipse itself got some problems, which added a little to the frustration I've got. I checked over and over again, but it wouldn't work. Started the debugger, added some breakpoint. It didn't even stopped at the first line of the main program! What I only found was some bizarre exceptions. Android couldn't find the definition of the main class itself. It crashed even before my program started running! What happened? I didn't know. It compiled! At least the class definition should be there!

I started to search for the problems on Google, based on the name of the Exception I found. I went through lots of forums, but still couldn't find anything work. They said check for classname, but apparently mine was correct. They said made sure the AndroidManifest.XML was correct. Good, I found that I hadn't stated that I used the Google map library in the XML; I thought adding it to build path & stuff is enough. However, it didn't solve the problem totally. I would open both the current one and the one from my sample Google Map app, compared line by line. No problem. It was even more frustrated than before. I thought the problem might be from the layout XML for Google map, because there was a warning that the tag "code.google.maps.MapView" is not defined. I hopelessly searched for solution in Google for some more. Still, couldn't find anything helpful. I did a lot of search, with lots of keywords, but none of the solution was applicable to my case. I tried to run the debugger millions time, but nothing happened, it just crashed right at the beginning. Somehow now it managed to reach the first line, but same thing happened afterward. Why : ( I dug deep into the stack track but also found nothing helpful.

Suddenly, in a flash light, I saw the first line of my code was "setContentView.." not "super(...)" (calling the super class to initialize itself). Hmm, I didn't expect it to made the whole thing fail; I didn't even see the foursquare app call super class' constructor. Still, I gave it a try and moved the call to super class' constructor on top. Magically it worked. (Now logically I think it happened (or crashed) like following: setContentView used some class that would supposed to be create by the super class' constructor, but the constructor hasn't called, so obviously setContentView can't find the class and crashed). Anyway, it worked, and the whole thing worked. Now I saw the map, with markers over the venues nearby user's location. Feeling relieved, but drained, I closed Eclipse and called it a day.




To summarize:

- Documentation & comments (of our code) are very important!
- Incremental testing is useful too! Code a little, test a little, then code a little more, test a little more. Restrain the desire to code the whole thing and debug all at one! It will go BOOMZ!
- Debugging is frustrating. It drains energy quickly.
- Google doesn't really helpful for debugging. Sometimes (most of the time) starring at the code, analyzing the errors and trying to figure out what went wrong is more helpful than go straight to Google and search for solution.
- I suddenly realized similar stories happened during CS3216 before: I wasted a lot of time on Google, but turned out I should just sit down, read my code, read the instruction carefully, and I would be able figure out what went wrong faster.
- I guess it is hard to avoid especially when we learn a new, complicated thing. We are clueless and wanted to search for light from people out there. However, it seemed that there were matches & wood just nearby, we should make use of them instead of searching for the light from faraway. After all, the people who wrote the instructions should provide enough information & correct steps to make the things work. We might just missed a small point, or introduced bugs in our own code.
- Still, I am awed by how dependent I am on Google now.

Tuesday, September 21, 2010

Victor

Suddenly I have this idea of blogging about the people around me. I don't know yet who I will write about, what I will write about them. However, I've got in my mind a handful of people, and most of the stuff will just be my random thoughts. This time it will be about Victor, one of the teammates in my ACM team.

Victor is a Singaporean. 2 years older than me. He is a math student. His favorite sentence is "It's crap only". Whenever I ask him what he is doing, he'd say, "nothing, it's crap only". "What is this module XXXX?" "Nothing. It's very boring. Crap only." He hates Java so much that every time we need Java (for BigInteger), he would murmurs "I hate Java" the start to the very end.

There is nothing special to say about his looking: a small guy, looking OK handsome. Not that kind of handsome that all girls will fall in love in the first sight, but I wouldn't say he looks bad in any way. He's the kind and trustworthy guy, would follow rules, instructions, etc. very carefully and dutifully. He's the kind of guy who can listen to people. In my team, while I can go crazy & childlike playful sometimes, Adhiraj might go detached and stubborn, he's clearly the one that do things the most careful and reliable.

That bring me to the next point. Though he is the math major, in a team of 2 IOI medalists, he is actually the main coder of the team. Many times I will find solutions for problems, explain to him, then he will handle the  coding part. It works quite well for us because, while I'm generally better at solving (hard) problems, he produces more reliable code. The funny part is that though he's a math major, I'm the one that usually solve math problems. I usually joke him, "man, you sucks at math."

I actually asked him several times why he doesn't major in CS. It makes sense when he always take few CS modules every semester, has scored well, tutored several CS modules. He has joined ACM the third year and he is very passionate about it. In fact, he is the most passionate about ACM in our team. He has given up his SEP to Canada to take the chance of joining ACM with us this year. His answer was that he didn't want to do the boring software engineering stuff a whole life.

Still, he has done quite a lot of programming. He has solved over 1000 problems in UVA live archive, a website that allows users to submit solutions to its huge problem banks. I must say he's very diligent. For now he is trying to solve past ACM regional contests to prepare for our competition.

This semester, I randomly met with some of his other friends -- friends outside the ACM circle. And I realized that despite what I thought, I knew very little about him (outside ACM). For example, I didn't know that he went jogging everyday (i guess it might be inspired by a book I sent him =P), has joined RUNNUS for 1 event at least (Well, I didn't expect him to join any CCA). I also didn't know much about his friends, and other stuff. I guess I still have some time to learn more about him.

I've ran out of thoughts already. Anyway, I'd say so far I've quite enjoyed being his companion.

Thursday, September 9, 2010

There's tomorrow.

In Prisoners' Dilemma, the expected outcome is that the prisoners will betray each other, leading to the result that both get the worst possible outcome (10 years sentence), while they treat nicely to each other, they both would have got a much better outcome (6 months). There is one way to alter the result of the game: repeating it infinite times. The reason is, in short, if one betray the other this time, the other will sure betray him next time, and both will get the wost case that both don't want. Expected that the other wouldn't betray him, he wouldn't betray either. If there is tomorrow, they should care about it, and they should better be nice to each other today.

One key thing that keep me optimistic is that I believe there is tomorrow. I thought about death (not suicide, but rather how it will be when I die) many times, but I know I wouldn't die very soon. Even when I faced the worst failure, even when I was all alone, when it was nothing but stress, when I thought it was the end of this world, tomorrow will still come. And I will still (likely) to be alive. Think, I still have the major, significant part of life ahead. Many things will come. Studying, Working, Friends, Family, Life. I couldn't be down forever; I should better live well today, so that I won't have to regret tomorrow. I should be nice to others (treat them honestly and nicely), be nice to myself (build up my strength and competence). Besides, it's then surprisingly easy to give up failures and move on. It's kind of a self-reconciliation system.(It saved me 2 years ago).

The more I go, the more I appreciate that future is more unexpected than I ever thought. Nothing stays the same for very long time. Hopes come and go. Chances come and go. And love might be too. Future provides a lot of hope and unexpected. Thus I stay optimistic. Moreover, I can't really chase after things that doesn't belong to me. Pretend to be something / someone else to grab a chance? It usually backfires myself (pride, confidence). Future might give a better, more suitable chance to me. I should better be myself. Does that mean I would never stop but continually expect something better would come? No. If it's something I really want, something I find myself suitable for, something doesn't require me to pretend (even though it might require me to pay in other ways), I would grab it. (There can be a whole heated debate on when's really the right time; honestly I don't know. Life's complicated. As long as I don't regret, I will do it).

What if at the end I will still be nothing, having no love and / or whatsoever? What if my life sucks? And I'm just an optimistic fool? It means I suck. But so far I think I'm not too bad. Let's just work with my all and wait for the future to come.