Tuesday, November 30, 2010

iOS & Mac OS Development - Calculator tutorial

Calculator
So much has happened since this post, check out my new app on iTunes

Got my first Macbook Pro on November 16th. Since then I have been exploring the possibilities in iOS and Mac OS development. I was amazed on the amount of documentations on the subject compare to google app engine. Probably because of the fact that the amount of iDevices that people are using these days.

If anyone is looking into iOS development I would recommend looking into the Standford Developing Apps for iOS by Paul Hegarty on itune U. Don't worry it is completely free and you are basically getting a $13,000 per quarter Standford course for free. "It is a very exciting time for developers." as my buddy Money Mike would put it.

My first take on the framework and the Software Development Kit(SDK) environment is that it is a complete set of tools. Like any other framework it is extensive with lots of layers of technology and as my mentor Jason Wei would say "It takes about a month to learn the sytax of a language, however it'll take a lifetime to master a framework."

The current version of the development is Xcode 3.5.2 and iOS SDK 4.2. You can download it for free at http://developer.apple.com.

Objective-C is a superset of C and for those who grew up with C/C++ it should be intuitive to get around. On top of the Xcode development environment this is my first time owning a Mac and using the Mac OS. However, I feel pretty comfortable because of the vast amount of documentations and tutorials that are available.

"Learning - Welcome the unknowns and opportunities to make mistakes." ~ docchang



I completed a basic calculator with a few extra functions in iOS and Mac OS. You can find the source code for both builds below:
https://github.com/docchang/Calculator.iOS
https://github.com/docchang/Calculator.MacOS

I created the iOS version and ported the project to Mac OS. The calculator model stays intact, however a similar view needs be recreated using Mac OS objects. e.g UIButton -> NSButtonUILabel -> NSTextField. Obviously the controller needs to use the Mac OS objects and the logic stays the same. One interesting thing is that under Mac OS project the NSTextField can be mapped to Label and TextField in the view unlike an iOS project Label and TextField map to their own correspondents.

Monday, November 22, 2010

Displaying timestamps in client's(viewer's) timezone with jQuery date format 1.0

While I was going through the Google App Engine tutorial to create a nice looking guestbook. I wanted each message to display its timestamp in the viewer's timezone. Each message was already timestamped in the datastore in Coordinate Universal Time (UTC). My tasks are to format them into desire format "MM/dd/yyyy hh:mm:ss a" and display the times in the viewer's timezone.

I searched javascript utilities and came across the jQuery dateFormat 1.0. However, I had to modify a few things. The original code is here and below:

jquery.dateFormat-1.0.js
  132 case "hh":
  133     retValue += (time.hour === 0 ? 12 : time.hour < 13 ? time.hour : time.hour - 12);
  134     pattern = "";
  135     break;
  136 case "mm":
  137     retValue += time.minute;
  138     pattern = "";
  139     break;
  140 case "ss":
  141     retValue += time.second;
  142     pattern = "";
  143     break;



There are two issues within these lines of code:
  1. Notice on line 133 the triple equals (===) is used to compared. Ideally sounds and looks great, however the value in "time.hour" sometimes are "00" as string. To fix it I use the double equals (==) comparison operator instead.
  2. time.second contains the second information as well as the timezone information. Therefore, if you specified "ss" as part of your format it will include the viewer's current timezone information and it will just clutter your screen because there is no point displaying the same information for each message. To fix it I further parsed the time.second and made a "tz" format for displaying timezones.
Below are the changes:

jquery.dateFormat-1.0.dc.js
  132 case "hh":
  133     //time.hour is "00" as string == is used instead of ===
  134     retValue += (time.hour == 0 ? 12 : time.hour < 13 ? time.hour : time.hour - 12);
  135     pattern = "";
  136     break;
  137 case "mm":
  138     retValue += time.minute;
  139     pattern = "";
  140     break;
  141 case "ss":
  142     //ensure only seconds are added to the return string
  143     retValue += time.second.substring(0, 2);
  144     pattern = "";
  145     break;
  146 case "tz"://parse out the timezone information
  147     retValue += time.second.substring(3, time.second.length);
  148     pattern = "";
  149     break;

You can see my full version of the jQuery date format here. Once I fixed the format I then found a post on stackoverflow.com about converting UTC to local user timezone. Thanks to CodeGrue's help.
    3 (function ($) {
    4     $.fn.localTimeFromUTC = function (format) {
    5         return this.each(function () {
    6 
    7             // get time offset from browser
    8             var currentDate = new Date();
    9             var offset = -(currentDate.getTimezoneOffset() / 60);
   10 
   11             // get provided date
   12             var tagText = $(this).html();
   13             var givenDate = new Date($.format.date(tagText, format));
   14 
   15             // apply offset
   16             var hours = givenDate.getHours();
   17             hours += offset;
   18             givenDate.setHours(hours);
   19 
   20             // format the date
   21             var localDateString = $.format.date(givenDate, format);
   22             $(this).html(localDateString);
   23         });
   24     };
   25 })(jQuery);


http://emplementation.appspot.com is the final product. I'm currently working on OpenID integration and will blog about when it is finished.

Wednesday, November 10, 2010

My first Google Application: Guestbook Tutorial with enhancement


Besides the standard instructions from the tutorial I have enhanced my guestbook to display timezone information and timestamps conversion according to the client's timezone per message. I also added a stylesheet file for the look and feel.

I had to fix some jQuery date formatter bugs, but no big deal. I will blog about the jQuery bugs later. You can view all the code online except the Python code.

guestbook.py:
   17 import cgi
   18 import datetime
   19 import wsgiref.handlers
   20 
   21 from google.appengine.ext import db
   22 from google.appengine.api import users
   23 from google.appengine.ext import webapp
   24 from google.appengine.ext.webapp import template
   25 
   26 class Greeting(db.Model):
   27   author = db.UserProperty()
   28   content = db.StringProperty(multiline=True)
   29   date = db.DateTimeProperty(auto_now_add=True)
   30 
   31 class MainPage(webapp.RequestHandler):
   32   def get(self):
   33     greetings = db.GqlQuery('SELECT * from Greeting '
   34                 'Order By date DESC '
   35                 'LIMIT 20 ')
   36     values = {'greetings': greetings}
   37     self.response.out.write(template.render('main.html', values))
   38 
   39 class Guestbook(webapp.RequestHandler):
   40   def post(self):
   41     #if author is empty use anonymous
   42     if self.request.get('author'):
   43       userauthor = self.request.get('author')
   44     else:
   45       userauthor = 'Anonymous'
   46     #set greet object
   47     greet=Greeting(content=self.request.get('content'), author=users.User(userauthor))
   48     greet.put()
   49     self.redirect('/')
   50 
   51 application = webapp.WSGIApplication([
   52     ('/', MainPage),
   53     ('/sign', Guestbook),
   54 ], debug=True)
   55 
   56 def main():
   57   wsgiref.handlers.CGIHandler().run(application)
   58 
   59 if __name__ == '__main__':
   60   main()

Tuesday, November 2, 2010

Google App Engine(Eclipse PyDev Plugin) Tutorial Errors???


I followed the Google App Engine tutorial and was able to launch the web application using Google App Engine Launcher. However, I'm getting some errors in my Eclipse - PyDev environment when I run it.


I checked the Google App Engine Launcher Logs. It is also showing some errors.
Update 11-22-2010: datastore error is normal, because there is no data. However, python require PIL module. You can download most of the PIL binary installer here: http://effbot.org/downloads/#pil.


However, the web application runs fine.


Any ideas?

Saturday, October 23, 2010

Are you a TopCoder?

I haven't done a TopCoder algorithm problem for years. From what I remembered the 250-point level problems were a lot easier back then. I can't believe there are folks who can complete a such task within 15 minutes. I didn't time myself, but it took me about 4 hours to get this particular 250-point problem submitted. During my first attempt I tried searching all possible digits, but it didn't come out too well and it was difficult because I could not consider all the possible cases. After a few tries I knew there is got to be an easier approach. Since the problem is only interested in looking for the longest digits, I should start looking from the longest possible digits and if all the rules applied then I'm done. I started working through this greedy concept and still took me a few more tries and below is what I came up with.

Problem statement: SRM 192 DIV 1 250-point DigitMultiples
You are given two strings of digits, single and multiple. Your job is to find the length of the longest substring (which may be the whole string) of digits in single such that there is a corresponding substring (of the same length) in multiple which satisfies the following constraint. Each digit in the substring of multiple is the same exact integer multiple of the corresponding digit in the substring of single. So "48" is a multiple (4) of "12", but "72" is not a multiple of "36". Multiplication factors from 0 to 9 are possible. Leading zeros are *allowed* in single and multiple and all substrings.



class DigitMultiples {
    //Main rule logic
    private bool Rules(string subM, string subS) {
        int Factor;
        if (subS[0] == '0') {
            Factor = 0;
        } else {
            Factor = (subM[0] - '0') / (subS[0] - '0');
        }
        for (int i = 0; i < subM.Length; i++) {
            int iM = subM[i] - '0';
            int iS = subS[i] - '0';
            if (iS * Factor != iM) {
                if (Factor == 0 && iS != 0) {
                    Factor = iM / iS;
                    continue;
                }
                return false;
            }
        }
        return true;
    }
    //Feed all the possible digits from single and multiple
    private bool RuleHelper(string single, string multiple, int digit) {
        for (int m = 0; m + digit - 1 < multiple.Length; m++) {
            string subM = multiple.Substring(m, digit);
            for (int s = 0; s + digit - 1 < single.Length; s++) {
                string subS = single.Substring(s, digit);
                if (Rules(subM, subS)) {
                    return true;
                }
            }
        }
        return false;
    }
    //Search through string multiple using the longest possible digits
    public int getLongest(string single, string multiple) {
        int PossibleDigits;
        //Getting the longest possible digits
        if (multiple.Length < single.Length) {
            PossibleDigits = multiple.Length;
        } else {
            PossibleDigits = single.Length;
        }
        //Search from top down and quit once it is found
        for (int digit = PossibleDigits; digit >= 1; digit--) {
            if (RuleHelper(single, multiple, digit)) {
                return digit;
            }
        }
        return 0;
    }
}

Tuesday, October 19, 2010

Sharpen your skill as a programmer

The last couple months I've been involved with iPhone (2G / 3G / 3GS / 4) hardware and software repairs. Learning and practicing all the components that makes up an iPhone and reviving them even when it is completely dead from water damage. I've learned a great deal about them (You can read all about it on http://www.dociphone.com). However, I haven't had the time to do much coding at all.

I spoke with a very good friend of mine Money Mike about the issue. We brain-stormed on different ideas and we approached as if we were athletes training for an event. As a swimmer I practiced the fundamentals of kicking and breathing of swimming as part of my daily routine and I'm sure Kobe Bryant practices his basic free throws daily. As a programmer we ought keep our mind sharp and below are the routine that we came up with.

Updated on December 7th, 2010: I've revised the routine to something I've been doing.
First thing upon awake at 6:40am & last thing before going to sleep at 10:30pm (twice a day):


Prior watching a movie or a TV show:
  • Solve Rubik's cube 3x3x3 or 4x4x4 or 5x5x5 Rubik's Cube at least once


Once awhile:

To keep track of my progress. I have recorded my results on a Google doc spreadsheet and compiled the arithmetic portion into an annotated chart here.