Wednesday, May 18, 2011

Asking For Assistance While Minimizing Interruptions - How To Do It Well

It is always somewhat a dilemma when you have to interrupt somebody to ask him/her to help you. There is always a tension between the pressure or desire to solve your problems/issues/bugs and complete your task AND the realization that everybody has their own set of tasks to complete and you are just about to interrupt & tell them to drop what they are doing and focus their attention to help you.

Each person will have their own tendencies:

  • Some will just be too shy or reluctant to seek help and just keep banging their heads and hope miraculously or by luck that they will be able to resolve it. Therefore some issues can just linger in the bug list unresolved or taking longer than necessary to be closed.
  • Yet a different group of people will ask, discuss, and talk about their emerging problems/issues/bugs all the time with their colleague - and creating noise, constant interruptions, and annoying. 
We all know that the balance lies somewhere in between. We want to respect out friends/co-workers/colleague privacy, time, and work - while at the same time trying to find possible reasonable solutions or pointers in solving our issues.

This blog post is not about how long should you wait before asking question to others, but is about when you actually decided to ask somebody about your problem - and how to do it well.

One of the rule of thumb that I have heard and embrace is the 15 minutes rule - that if you encounter a problem and cannot solve it immediately, try to find some answers/pointers/hints on how to resolve it with all your might in approximately 15 minutes, and if you are still stuck, then get help from others. This works in theory but often what somebody does in that 15 minutes or so is just weird or not helpful at all. I have seen somebody basically just stare at their code up and down the screen and then declare a surrender. Or, hitting the same scenarios again and again, recompile, test with the same code again - which predictably yield the same errors/wrong results/problem as before. Some will Google their issue and read the search result and do nothing about what they read or just skim through the results.

To be able to ask for help well, I recommend doing the following:
  1. It is important to know and understand the error message you are getting - if any. You should not go to somebody equipped with "it does not work". It is really bad when somebody comes to you and just say "it's broken" and when you ask "What's the error?" that person replies "don't know".
  2. Do your own homework and reasonable research first. The 15 minutes above should be counted toward this. Trying possible scenarios and fixes, what works, what does not, noting them down, etc. Then communicate this to the person that you are seeking help from - so they don't have to waste their time in trying what you ave tried again. Bring screen shots, print out, examples, etc.
  3. When you are about to interrupt people, I recommend asking whether the person has some time to spare or whether they are free at the moment. I know some of my friends to away from their desks during lunches precisely because of this reason - so they are not interrupted during lunch. It's a good practice to respect people's time and space - and asking beforehand whether they can be interrupted or not goes a long way.
  4. If the problem is not that urgent, try email. Of course describing your problem in an email may take more time (screen shots, etc etc) and some times it is just not possible. But this also an alternative to get help from others without pressuring them to drop everything on their plate and solve yours.
  5. When people allow you to interrupt them, then describe your context, settings, cases, and ask your question decisively and quickly. It's confusing when someone just storm to your cubicle and say "It's broken, does not work at all!". OK - so what do you want me to do?? Here is an example: "Bob, I have been getting some errors in ELMAH about 'null reference error'. From the trace, it seems to be coming from ProfileEdit.ascx - which uses a custom editor template for a textbox for a string value. If I use a regular textbox, it works fine, only when using the custom template then the error shows up. The custom template uses same validation rules - which I am not familiar with - and the calculated null values come from that line. Do you have any ideas or hints that will help me?"
  6. At this point, we have to give them the freedom whether they want to respond now or later. Your colleague may say "Hm, let me look into it, I will let you know" - then we ought to thank him/her and leave, go back to our desk and do something else or do some more research. 
  7. Also try to ask for help during non-peak time. I like to ask help early in the day or right after lunch, before my co-worker get into their working zone mode. Since he/she is not in their zone yet, then it becomes less of an interruption for my co-worker(s).  
  8. If you have additional suggestions/recommendations, please post them in the comments!
I am not saying that I have been perfect in doing all these - far from it. So here are some of the mistakes or common error that I have done, or I have witnessed people did (if some of these describe you then You're Doing It Wrong!):
  • Send an email to co-worker about a partially described problem, then coming to that co-worker's cubicle/office and asking "Have you read my email? What do you think?". Why is this annoying? Because it's redundant and also pressuring the co-worker to immediately see/solve your problem. If you are going to send an email, send a intelligent and good description of the problem and your question. A good analogy is like creating a question/post on a forum (or StackOverflow) and then wait! If it's urgent (which is usually not), then why send an email?
  • Coming into co-worker's office/cubicle and saying "Can you come here real quick and check what I am doing wrong?" Why is this wrong in so many different levels? Because it shows an almost complete disrespect for the co-worker's attention/time/load - and expecting him/her to just drop whatever he/she is doing and solve my problem or help me. Plus, I am usually to lazy to do some research and try to articulate my problem to my co-worker - so bringing him/her to my workstation is just so much easier. 
  • Coming into co-worker's office/cubicle, describing the problem and just stand there, fully expecting the other guy to help RIGHT NOW - even some times when he already said that "give me a minute".
  • If you have additional scenarios, please post them in the comments!
Now, even if you follow all these recommendations - that does not mean your co-workers won't be mad at you and always help you with super-eagerness and save your life - I know I don't some times. But, the bottom line is that when you respect your co-workers' time, space, and attention (by minimizing interruptions), most of them will be more likely to return the favor and more willing to help you.

One exception to all of the above: if the issue at hand is URGENT (i.e. we pushing for production, crunch time, "server is down!", etc) - then all goes out the window and try to do whatever it takes to get the job done. But again, this is usually only occupies a small percentage of our work time and mostly preventable. 

Now, stop interrupting me!

-- read more and comment ...

Tuesday, April 19, 2011

Client-Side Validation with AJAX/Dynamic Form

One of the thing in my to-do list for MVC is "figure out how to do client-side validation". Isn't that supplied out of the box since like ASP.NET MVC 2? Yes, it is - but it only work out of the box if the form is not dynamically fetched.

In my projects, most of the form is a dynamic form - so user click an icon and then the form (empty or pre-filled) is fetched via AJAX and then displayed (some times in a jQuery dialog). This is a quite common scenario, for example: you are looking at your account profile screen and displayed there is a list of your phone numbers that you have registered. Let's say you then want to edit one of those since you changed your phone number. So you click the edit button/icon next to your phone number on the screen and a dialog box pops with the old phone number, you edit it, click "Save" and the list refreshes with your phone number.

To simply enforcing a "required" field validation in this scenario was quite complicated. Especially when your AJAX submit handler is a custom handler (instead of using the stock ASP.NET MVC AJAX Helper). But now, by adding less than 10 lines of code, add 2 lines of configuration settings in the web.config and including less than 3 javascripts - it is all possible!

-- read more and comment ...

Wednesday, April 13, 2011

Munchkin Strategy: Orc

An Orc card says this:

An orc who is hit with a curse can always choose to ignore the curse and lose a level instead - unless he's already at level 1.

When an orc fighting alone defeats a monster by more than 10, he goes up an extra level.
On the surface, these abilities seem to be superficial and not that powerful. Lose a level? What idiot prefers to do that instead of absorbing a curse? Extra level if defeating more than 10? Sounds either useless or extremely hard!

But, to a skilled Munchkin player, becoming an orc can be a powerful strategy in both early and late game.

-- read more and comment ...

Sunday, April 10, 2011

Utilizing pass-by-ref Parameters

I recently helped a friend of mine code an application and at some point I created a method using a pass-by-reference parameter. Apparently this is new to him. I asked several other programmer friends that I know and most of them either know about it but never use it or don't know about it. So - here is a post about it.

To illustrate the usage of pass-by-reference, I will create to a simplistic example - where we want to calculate a loan amortization: with initial loan, interest rate, and loan period - and resulting in: monthly payment and total interest over loan term

So in code, without the pass-by-reference, we have to do this somewhat in 2 steps/methods:

    decimal monthlyPayment = CalculateMonthlyPayment(initialLoan, rate, period);
    decimal totalInterest = CalculateTotalInterest(initialLoan, rate, period);
With the definitions:
public decimal CalculateMonthlyPayment(decimal initialLoan, double rate, int period) { 
        decimal result;
        // calculate monthly payment
        return result;
    }

    public decimal CalculateTotalInterest(decimal initialLoan, double rate, int period) { 
        decimal result;
        // calculate interest
        return result;
    }


-- read more and comment ...

Tuesday, March 29, 2011

jQuery update for IE9

When Internet Explorer was released, I downloaded it immediately and replaced my IE8. It works superbly except on a project that I was working on. For some reason, some javascripts are causing errors and won't work. I was using jQuery 1.4.x and jQuery UI 1.8.1.

After some investigation, the existence of the meta-tag to force IE compatibility and the outdated jQuery scripts were causing all the errors.

So I removed the meta-tag ("<meta http-equiv="x-ua-compatible" content="IE=8" />") and updated the jQuery reference to the latest greatest (1.5.1 and UI 1.8.11) - and all are happy again.

-- read more and comment ...

Monday, March 7, 2011

Munchkin Strategy: Wizard

Munchkin is a card game, where you play a character in battling monsters in order to get to the winning level (level 10 for regular or 20 for EPIC). The game involves some luck (drawing cards), strategies, a good amount of persuasion, trash-talking, and bantering back-and-forth with other players. That combination makes the game a lot of fun, interactive, and can be played again and again without getting boring.

For more information about Munchkin, you can read their website: http://www.worldofmunchkin.com/

If you are familiar with Dungeons & Dragons, then Munchkin should be somewhat familiar to you - a funny version of D&D. It has races & classes, curses, combat strength, charms, potions, etc.

The rest of this post assumes that you are somewhat familiar with the game, basic rules, and its vocabularies - outlining a basic strategy to use if you are playing as a Wizard class.

-- read more and comment ...

Wednesday, March 2, 2011

Integrating ELMAH into your ASP.NET MVC project

What is ELMAH? ELMAH stands for Error Logging Modules and Handlers. So it does what it says, logging errors. It's a plug-able stand alone module that you can integrate with your project quite easily.

From ELMAH's site:
Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:

  • Logging of nearly all unhandled exceptions.
  • A web page to remotely view the entire log of recoded exceptions.
  • A web page to remotely view the full details of any one logged exception.
  • In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off.
  • An e-mail notification of each error at the time it occurs.
  • An RSS feed of the last 15 errors from the log. 
Sounds awesome! Hell yes - beats writing your own any day! How do you integrate it with ASP.NET MVC project?

1. Download ELMAH
You can get the compiled assemblies or the source files here: http://code.google.com/p/elmah/

2. Reference ELMAH's assemblies
If you get the compiled assemblies, just make a reference to Elmah.dll. If you get the source, you will need to build it and then reference it (either by project or by binary).

3. Modify web.config
Open your web.config and make these changes:
a. Add this "configSections" within "configuration"
<configSections>
        <sectionGroup name="elmah">
            <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
            <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah"/>
            <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah"/>
            <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
        </sectionGroup>
    </configSections>
b. Add this "elmah" section within "configuration" under the "configSections". This will enable ELMAH to save the error log to the database using "MyAppConnectionString" connection string. If you want to save the log into XML files on a local disk, you can uncomment the second line (and comment the 4th line) and specify the saving location under "logPath".
<elmah>
        <!--<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data"/>-->
        <security allowRemoteAccess="1"/>
        <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="MyAppConnectionString"/>
    </elmah>
c. Within "system.web" section, add these lines:
<httpHandlers>
            <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah"/>
        </httpHandlers>
        <httpModules>
            <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
        </httpModules>
d. Within "configuration", configure the permission to see the log. Basically it will deny all users unless users are logged in and user name is listed in the "allow" list. Enable that by adding these lines:
<location path="elmah.axd">
        <system.web>
            <authorization>
                <allow users="admin,joe,bob"/>
                <deny users="*"/>
            </authorization>
        </system.web>
    </location>

4. Modify global.asax
Check in your global.asax whether this line exists:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
If it is, then no more changes are needed in the global.asax.

5. Preparing Database
If you elect to store the log in the database, then some tables and stored procedures must be created before ELMAH can be functional. Get the script to create all those tables & stored procedures here: http://code.google.com/p/elmah/wiki/Downloads?tm=2 and run it.

That should be it and ELMAH is ready to run - you can start accessing ELMAH under /elmah.axd from your root url.

But I went a step further - I want all exception, including handled one to also be captured in ELMAH. ASP.NET MVC provides an filter-attribute called "HandleError" to handle/catch all errors/exceptions happening in the controller or bubble all the way to the controller. So instead of using that, I made my own HandleError attribute that will log to ELMAH - and replace the stock [HandleError] with my [ELMAHHandleError] attribute.

6. Create [ELMAHHandleError] for all my controllers.
I took this code from NerdDinner example that ASP.NET team provides in CodePlex.
public class ELMAHHandleErrorAttribute : HandleErrorAttribute {
        public override void OnException(ExceptionContext context) {
            base.OnException(context);

            var e = context.Exception;
            if (!context.ExceptionHandled   // if unhandled, will be logged anyhow
                    || RaiseErrorSignal(e)      // prefer signaling, if possible
                    || IsFiltered(context))     // filtered?
                return;

            LogException(e);
        }

        private static bool RaiseErrorSignal(Exception e) {
            var context = HttpContext.Current;
            if (context == null)
                return false;
            var signal = ErrorSignal.FromContext(context);
            if (signal == null)
                return false;
            signal.Raise(e, context);
            return true;
        }

        private static bool IsFiltered(ExceptionContext context) {
            var config = context.HttpContext.GetSection("elmah/errorFilter") as ErrorFilterConfiguration;

            if (config == null) return false;

            var testContext = new ErrorFilterModule.AssertionHelperContext(context.Exception, HttpContext.Current);

            return config.Assertion.Test(testContext);
        }

        private static void LogException(Exception e) {
            var context = HttpContext.Current;
            ErrorLog.GetDefault(context).Log(new Error(e, context));
        }
    }

That's it!

For further reading:

-- read more and comment ...

Thursday, February 17, 2011

Mowbol Weekly: Using Corona

Mowbol.com (AWH's sister company), a company that focuses on mobile development recently did a series of videos about mobile platform. The last one was particularly interesting as it discussed using Corona to build a code once publish for both Android & iOS.

Chris Slee talks about Corona and the new Mowbol channel framework from mowbol.com.



So if you need to get into the app store fast on Android phones and tablets, iPhones, iPads, we need to talk.

You can go to mowbol's website here: http://www.mowbol.com
Mowbol also has a Youtube channel under mowboldotcom: http://www.youtube.com/user/mowboldotcom
-- read more and comment ...

Tuesday, February 8, 2011

Performance Tips (LINQ to SQL)

One part of the application that I am working on is performing poorly. According to the performance measurement that I get from using EQATEC profiler, it takes 3-4 seconds to load this page.

IIS / UI 
Since this is a web application, so I made sure all the IIS/non-application performance enhancements are in place:

  • IIS compression are turned on
  • Javascript files are combined and compressed
  • CSS files are combined and compressed
  • Images, scripts, and CSS files are cached
  • Conforming to YUI rules & Google PageSpeed performance rules
Setting all those boost some performance in my application - not really that noticeable in normal usage. It cut down about 0.5 seconds or about 13% or my load time. So now we are in 2.8-3.5 seconds range. So what else?

-- read more and comment ...

Monday, January 31, 2011

Using Except() Method in LINQ

There is a method that I rarely use in LINQ called "Except" - but it comes handy in my latest coding. So I thought I'd share how I use it. This method is for an IEnumerable and has multiple signatures: one that takes a second IEnumerable to exclude and the other one takes an IEnumerable and a comparer. You can read the spec in full here.

Here is an example:

int[] oneToTen = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] oneToTenEven = { 2, 4, 6, 8, 10 };
int[] oneToTenOdd;

// do some exclusion here
oneToTenOdd = oneToTen.Except(oneToTenEven);

// so that oneToTenOdd will have { 1, 3, 5, 7, 9 };
OK - that looks simple. But what about when the IEnumerable is of type T or some other complex type? This is where the second signature comes in handy. In this scenario, we will have to make our own comparer class to specify how we want both list items to be compared against each other.

Imagine this hypothetical situation where you are at a dealership and want to separate the cars that have been washed and ones that have not. Cars may have the same make, model, color, type, but each has different VIN number.

IEnumerable<Car> allCars = GetAllCars();
IEnumerable<Car> carAlreadyWashed = GetCarAlreadyWashed();
IEnumerable<Car> carNotWashed;

// do some exclusion here
carNotWashed = allCars.Except(carAlreadyWashed);

The above code which will normally work for simple comparison, won't work because the run-time will have no idea that it has to compare based on VIN number. We have to tell it to use that field to do comparison.

public class CarComparer : IEqualityComparer<Car> {
    public bool Equals(Car x, Car y) {
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

         //Check whether the Car' properties are equal.
        return x.VIN == y.VIN;
    }

    // If Equals() returns true for a pair of objects
    // then GetHashCode() must return the same value for these objects.
    public int GetHashCode(Car car) {
        //Check whether the object is null
        if (Object.ReferenceEquals(plan, null)) return 0;
        //Get hash code for the VIN field.
        int hashCarVIN = car.VIN.GetHashCode();
        return hashCarVIN;
    }
}
Now then we can modify our code to be such as this:

IEnumerable<Car> allCars = GetAllCars();
IEnumerable<Car> carAlreadyWashed = GetCarAlreadyWashed();
IEnumerable<Car> carNotWashed;

// do some exclusion here
carNotWashed = allCars.Except(carAlreadyWashed, new CarComparer());


-- read more and comment ...

Friday, January 7, 2011

Microsoft Certification exams

My employer (AWH - http://www.awh.net) encourages us (the employees) to take MS certifications. Not only this will benefit the company in maintaining our status as a Gold Partner, but also will benefit us as far as knowledge, new technology, etc. Plus the certifications are attached to the individual, so if you change jobs, those certifications certainly belong in your resume and can be leveraging points.

AWH will pay for the tests, including first failure. So if I take a test and fail, and then retake the test and pass, AWH will cover both exams. So I have to pass before the reimbursement can come through.

Anyway, so last November, I saw a promotion on Prometric's website for a 2/3/4/5 exam packets with discounted price and FREE retakes for each exams in the packet. With that good deal in mind, I decided that I will set a goal in this area: getting a MCPD - Microsoft Certified Professional Developer. This certification requires 4 exams:

  • TS 70-515 - ASP.NET 4.0, Web Forms, MVC, IIS
  • TS 70-516 - ADO.NET, LINQ, EF
  • TS 70-513 - WCF
  • TS 70-519 - Web application solution/architect
I took the first test early in December and passed it quite easily. Since ASP.NET is what I use daily, most of the questions in the test are familiar to me and I can answer them correctly.

I scheduled to take the ADO.NET test on Dec 23rd, but when I came to the facility, it was closed. I was not notified of any closing and Prometric also was not aware of the closing of the local facility (New Horizons). Prometric was able to reschedule me for Dec 27th at a different facility. I failed my ADO.NET test - probably by 2 or 3 questions, it was so close. Although I use ADO.NET stuff pretty much daily, but there are some things in there that are pretty new to me and I have not used them in production quality code - like Entity Framework. Those questions stumped me and resulting in a failing grade. Thank God for the free retake!

So I studied more EF, practice making some projects with with etc and retake the test on December 29th. I passed.

So next up is WCF - scheduled for Jan 12th. Hopefully by end of Feb 2011, I will have become an MCPD.

-- read more and comment ...

Tuesday, December 28, 2010

T-Mobile Customer Experience

One of my personal conviction is generosity. So that conviction, combined with good service (especially paid ones) usually produce a desire to reward the service giver beyond the typical means. I personally don't think this is unique to me - for example in tipping your servers in a restaurant, when you are getting excellent service, some people will give more tip, etc.

In this particular experience, I was getting superb service from T-Mobile and this blog post is a way of rewarding them of their excellent efforts to me as a customer.

-- read more and comment ...

Tuesday, November 23, 2010

Windows Phone 7 Experience

About 2 weeks ago, I bought a new cell phone. I am a T-Mobile customer (T-Mo FTW!) so I renewed my contract and got the phone at a discounted price. My previous phone was a T-Mobile G1 (the 1st Google/Android phone) and I bought it used from a friend of mine. That device served me extremely well and it is still running well and my wife is using it.

So for my new phone, I bought an HTC HD7, running the new Windows Phone 7. This blog post is about my experience with it so far - what I like about it, dislike, a little bit comparison to Android, etc. Nothing really scientific, but just sharing my experience, including an app development experience (since I am a software engineer). Obviously, my experience is a combined experience between the hardware (HTC HD7), the OS (WP7) - but when necessary I will mention the specifics.

What I REALLY Like
  • This is something that is hard to describe, but there is such a pleasant feeling in using the device with the WP7. Every scroll is buttery smooth, no lag, no stutter, snappy, and my user-experience for the 80% of my usage of the phone is superb (this includes making phone calls, receiving calls, speaker phone, contacts, searches, calendar, email syncs, twitter, browsing). 
  • Panoramic view is totally awesome. It helps to go through things quickly, less click/swipe/back, etc. The panoramic background in some hubs are also contributing to increase the niceness and pleasant of using the device. All this being carried in a 4.3" screen - superb. iPhone 4 screen is better with the Retine Display, but HTC HD7's is bigger.
  • The lock screen is also surprisingly well designed. I did not think about this before - but then I realized that showing all my notifications & next event on the lock screen is awesome! One of my cell-phone related habit is to look at my phone to see the time AND to see what is the next item in my calendar - which totally fits into the WP7 paradigm (and I have a feeling that I am not the only one with that habit).
  • The email interface is awesome, every email is delineated well, clear text, eye-pleasing font, easy to use (virtual) keyboard, the sync is also fast, and does not lock the screen, excellent progress bar with the dots, etc. As far as email related experience, this is probably the best I have seen (compared to iPhone/iPod Touch, WinMo, BB, Android).
  • The Calendar interface is also very robust and well done. It syncs seamless with my Exchange calendar, displays the next "event" on "Home" and "lock" screens, and for the extra kick, the calendar date "flips" when you scroll the events in the event list. Haha - I thought that was small but slick nonetheless. 
  • The "Tile" or the "Metro" design. I though it is awesomely done and intuitive. I am a bit biased to big icons - so the tile suits me well. Some also animate (changes in photos, people, news images, etc) - which added some "wow" factor to it. Some provide crucial information: the weather app gives the current weather summary, Outlook shows number of new messages, etc. There is no extra "widget" or differentiation between "widget" and "app shortcut" (like in Android) - which makes things simpler.
  • The Media hub is really nice, it combines radio (like iHeartRadio), YouTube streams, your videos, music, podcasts, etc, and organized well via panoramic views. They just works seamlessly. No need to open YouTube app separately or media player app or radio app separately. One hub and everything works.
  • Zune software. I HATE itunes - and Zune is awesome. Much better design, fast, unobtrusive updates, AND YOU CAN SYNC WITH MULTIPLE COMPUTERS! Yeay! Also, sync media over the air!
  • Developing an app for WP7 is very very easy. Well I am a bit biased since I use Microsoft tools for my work. But here is the thing - I experienced quite some pain to get Android/iPhone dev environment to be up and running and I did created a some kind of "hello world" app, but nothing beyond that. With WP7, in 2+ hours I cranked out a panoramic RSS reader with style and all. Certainly (subjectively) a huge added value for me.
What I Like But Consider Not As Important
  • XBOX Live is really cool. You can create/modify your Avatar from the phone, play some games, sync accomplishments, etc. But, since I am not a big XBOX Live player, I don't use this feature as much. 
  • Instead of paying per music/album, Zune allows you to pay subscription based: A $14.99 / mo gives you unlimited access to millions of songs you can stream on your PC, Xbox 360, Windows Phone 7, or Zune HD - AND you get to keep 10 per month FOR FREE FOREVER!
  • The WP7 OS is always stock and all the bloatware from carriers can always be uninstalled just like any other app without rooting or hack. This was not my experience with Android or WinMo.  
  • WP7 Bing's voice search/command seems to be able to pick up my voice better compared to my old Android. I don't think this is a big deal - could be just because my G1 can't go beyond Android 1.6. I think Froyo most likely has better support for this.
  • The robust kick-stand in HTC HD7. It's awesome when watching videos or reading on a table.
  • The camera is nice. Being able to take 720p video and take a 5mpix photos are good features to have. Plus, the camera software is really fast - you can go from "lock" to "save picture" in about 5 seconds or less. Although I consider this as "not as important" for now, but I do see that I take pictures more because of the quickness or the camera & its ease of use. 
What I Don't Like & Needs Improvement
  • Marketplace. It needs to differentiate the search between music, apps, games, etc. Right now, when I am searching for "News", it gives me ALL related with "news" instead of contextual search result. I am fine with the "all" search and there are times when it is useful, but there needs to be specific search filter too.
  • Map & navigation. Bing maps in WP7 is awesome and slick, but Android's turn by turn saved my ass multiple times. I heard some rumors that this is coming out in SP1 in Q1 2011 - at least I hope so.
  • Need more apps, FREE apps. I want my free "Alchemy" or "Angry Bird" like in Android ... Or QR code reader, Google Sky Map. More apps ... WP7 apps availability is nothing compared to iPhone or Android.
  • Twitter integration to People, like Facebook or MySpace or LinkedIn
  • Phone wide search. Search people, docs, emails, etc from a single place.
So there you have it - my conclusion? I like it - a lot. Probably the best device I have used to date. If I have to rate my OS of choice it would be like this:
  1. Windows Phone 7 - for those of you who are skeptical, I suggest you to try it. I was too a skeptics, but I am sold out now. Yes, it is not perfect, has room for improvement, but it is my device of choice for now.
  2. Android, probably the G2 - fast with HSPA+, excellent keyboard, stock Froyo, loaded with free apps, nice slick phone. (Or if you are on Verizon, go with Droid X)
  3. iPhone - only if iPhone is available outside AT&T.
I have to say, in all this experience, T-Mobile has been awesome. I have been their customer for almost 8 years and there are reasons for that. Their phone customer service is impeccable, their store people are great, their rate are the most economical of all, ultra-fast network, and great selection of phones, PLUS they are the first in many things (1st Android device, 1st Google provider, 1st big-screen-phone in HTC HD2, 1st in getting WP7 in US) - and they always use hot women in their ads. What more can you ask for?

-- read more and comment ...

Monday, November 22, 2010

Acadia National Park

In August, I went to a 10 day vacation, spanning over 11 states! We went from Ohio to New York to Vermont, New Hampshire, Maine, Massachusetts, Rhode Island, Connecticut, Pennsylvania and passing over West Virgina and New Jersey on our drive.

But the highlight of our trip was when we were at Acadia National Park in Maine. Acadia National Park is about 5 hours north of Boston, MA. When I planned our trip, I had some expectations about how beautiful this park going to be, but I was still blown away - it exceeded all of my expectations! I think all of our family and friends agreed that it was the best national park we've seen and the highlight of our trip. I eager to go back next year and spend more time over there.

Acadia National Park has everything - like from beaches (ocean sandy beach or lake beach), serene lakes, hiking trails, bike trails, rocky coastline, sandy coastline, mountains, and spectacular mountain top view.

Anyway - if you have the time, Acadia is a must visit. I think our family is going back there in summer 2011!







-- read more and comment ...

Tuesday, October 26, 2010

Smart Power Control

I setup an SSH server at home running on my Media Center box. ALL of the shows that I am recording runs at night, so during the day, other than the time it has to download updates or running some batch process, it usually goes to suspend/sleep mode - which of course makes my SSH to become unavailable.

Why not just turn on "Wake up on LAN"? Well, I tried that and it worked, but it also somehow wake up the PC when I don't want it - like in the middle of the night or on a Saturday morning, or several seconds after it goes to sleep. In the end, I basically turn-off "Wake up on LAN" and trying to find a different solution.

Basically, what I want is this:

  1. The PC needs to be on between 8am to 5:30pm - this the window where I usually need my SSH
  2. It also needs to be recording my scheduled recording in Media Center
  3. Other than those, it should be in suspend/sleep mode
A friend of mine suggest moving the SSH into a router running DD-WRT. This is probably the best solution, so I can operate my PC on "Power Saving" mode and just leave the router on. Since I am using a Linksys router that is compatible with DD-WRT, I tried it. The problem is that my router does not have much memory, so not only I have to put the micro_plus_ssh version, but also when SSH is running the router would lock up and I have to reboot it. So after playing with this option for about 2 days, I went back to running my SSH on my Media Center box. Maybe one day when I am buying a new router - I will get one that is much more capable to run SSH on. But now back to original plan.

So for a while I just put my PC to "Never" sleep and just turn it off at night and turn it back on in the morning. I moved all my scheduled maintenance stuff (virus scan, windows update, etc) to morning/afternoon. Obviously this gets to be a pain after a while - especially when I keep forgetting to turn it on or off.

So for now, I use a software called "SmartPower" - where I schedule my PC to be "ON" between certain times and/or when certain parameters are set. Here is an article in LifeHacker about it. The way to use it is basically setting your computer to "Never" sleeps, and let SmartPower take over the sleep management (instead of letting Windows doing it). So, to meet my needs, I set:
  1. In "Schedules" tab to awake / stay on during the weekdays between 8:15am to 11:55pm
  2. Under "CPU" tab, set to 27% - this is for watching recordings past midnight or on weekends
  3. I set my PC to awake when Media Center remote is used
That's it - works flawlessly. Oh - and I replaced the power supply unit into the one that is 80 Plus certified to conserve more power during idle or low processing time while it's on.

Additional readings:
-- read more and comment ...