When do you give up and start over?

I’ve worked on many, many projects in my career. Some of the projects I’ve started, some I’ve inherited. There comes a time in every project, not just software, but also home projects and car repairs, where I have to decide to scrap what I have and start over. This decision is never taken lightly as I’d be throwing away something that works in exchange for a clean start.

I’ve done this with my NotifyMail program a few times as the application was quite small, but in the process I had to drop features and probably ticked off a number of users. In all my time working on ReceiptWallet, I asked myself a number of times if it was time to scrap the code and start over. While I never completely scrapped the code, I did rewrite chunks of it as I learned more and better ways to write code.

With many of the projects I’ve inherited, the decision to start over has pretty much been a non-starter as the programs had existing users and I was under time pressure to get things done. Unfortunately this sometimes lead to fixing lots and lots of bugs that I didn’t create and probably wouldn’t have been in there if I started over.

The same type of decision has to be made with respect to cars and even a lesser extent, houses. If you keep pouring money into a car for repairs, at what point do you decide to buy a new car? Granted the cost is much higher for a new car, but over time the repairs could add up to the price of a new car, not to mention the hassle of taking a car to the mechanic.

Paperless 2.0 Released

As my loyal readers know, I sold ReceiptWallet to Mariner Software about 2 years ago and they renamed it Paperless. Yesterday, Mariner released Paperless 2.0. I couldn’t keep away from the product that I started over 4 years ago, so I’ve been helping out with this release. This release is, in my very biased opinion, a killer upgrade. It has so many features in it, that the list on Mariner’s website doesn’t it to justice!

One thing that people ask me is “how should I setup my libraries in Paperless?”. That’s a question I have never been able to really answer and with 2.0, the question is even harder to answer. There are so many ways to customize a library that it is a solution for everyone, no matter how you want to stay organized.

If you’re a Mac user, I’d definitely recommend checking about Paperless 2.0 and giving it a whirl. For people that haven’t started storing documents electronically, there is no better time to start then now just as the tax season starts. I was talking to my tax guy today and was able to quickly pull up all documents I needed with just a few clicks.

Importing video into EyeTV

I use an Elgato EyeTV for my media center and it works quite well. My 3.5 year old son knows how to use it to watch his shows, so when my mom burned a DVD for him, I had to figure out how to get the video into the EyeTV to make it as easy as possible for him to watch it. As quality wasn’t really my concern, I looked for any and every available option for how to import it even if it required transcoding.

After reading a post on the EyeTV forum, I started to look for a way to convert an H.264 encoded file into an MPEG Transport Stream. I generated the H.264 encoded file using Handbrake. After a bunch of futzing (hours), I found an option in VLC that transcodes the video into an MPEG TS. I did not check the Transcode video and Transcode audio check boxes, selected MPEG TS and it quickly spit out a file that the EyeTV could read. The forum post said to hold down the command key while selecting Open QuickTime movie, and then basically treat the stream as an input and record. While it records in real time, I patiently waited and the video encoded. (Yes, the quality went down a little bit, but my son doesn’t care.)

While this process worked perfectly for what I wanted, it seems far too complex to just import video. I can understand that El Gato is a small company and doesn’t want to make EyeTV into a generalized media center; however, it doesn’t seem like it would be too hard to handle other media types.

SeaWorld hasn’t gotten the privacy memo

Today my family and I visited SeaWorld as we do fairly often. As I was waiting at the parking toll booth, I heard the attendant ask a guest for his zip code while swiping his credit card. Apparently this guy and SeaWorld staff don’t read the newspapers. This action is in direct violation of the recent (February 14, 2011)  California Supreme Court decision of Jessica Pineda v. Williams-Sonoma Stores, Inc. In a nutshell, merchants cannot ask for a zip code when processing a credit card transaction (with a few exceptions). The zip code can be considered personal information and is a violation of California consumer protection laws.

I mentioned this to the attendant and he said that they ask for it for a survey and also ask it for of cash visitors as well. Yeah, that’s kind of the point as the zip code could be used to link the survey directly to the credit card user.

We’ll see what SeaWorld has to say with the message I sent them. They better act quickly otherwise the fines could start adding up. Too bad I can’t get paid for reporting the issue!

When do the recruiters stop calling?

Over the last few months, I’ve gotten more inquiries via email and phone calls from recruiters than I recall ever getting in the past. Now that I’m gainfully employed by a large employer, I seem to be a target for recruiters. Is it recruiters’ MO to target skilled people working at large companies? I’ve only been in this job about 6 weeks; do people think I’m just going to jump ship? Of course I’m not going to do that.

How do I stop them from calling (at least for now :-))?

Review: ParkZone Night Vapor

My interest in RC flying vehicles hasn’t stopped at helicopters. My wife bought me a ParkZone Night Vapor for Hanukkah. This plane is advertised as an intermediate plane, but also could be flown indoors. As I don’t have a back yard large enough to fly other planes such as the HobbyZone Champ, I thought that the Night Vapor would be cool to fly.

The first day that I tried to fly it, I had very little success; I flew it in the living room and was not able to maneuver it to turn it. A few weeks later, my father, son, and I spent a few hours flying in my garage (it’s a great place to fly when both cars are removed) and I started to get the hang of the Night Vapor. Since then I’ve spent more time flying and have gotten quite good at making turns in tight places. Today I flew it outside and managed not to crash it too much! My only slight problem is that I almost landed it in the pool, but other than that, I was doing pretty well. Of course, flying an RC plane is a lot different from helicopters. Planes need more space, has no reverse, and can’t turn on a dime. It is taking me a bit of practice to go from frustration to having fun. The hardest part for me is to remember that if I want the plane to dive, I need to push the right stick forward and not back.

While I’ve crashed the plane quite a bit, I’ve only had to do minor repairs on it. I had to replace the main motor (I think it was defective from the factory) and one of the gears. In addition, my dog wasn’t too happy when it flew close to him and he bit it ripping a small hole in it; clear packing tape fixed it right up. I’m quite surprised how durable it is despite having cellophane wings.

Pros

  • Very durable.
  • Flies in small places.
  • Flies well outside.
  • Not too hard to control once you get a hang of it.
  • Long battery life compared to the helicopters (I can get about 15 minutes out of a battery)

Cons

  • None

Summary

The Night Vapor is a lot of fun to fly indoors and out. I’m not sure that there are too many RC planes that can fly in relatively small rooms or a garage. The plane takes a little getting used tobe, but after a few flights, it gets a lot easier to handle. While I really enjoy flying the helicopters, flying this plane is a different experience that has its own joys. The extended flight time (about 2.5 times longer than the helicopters) is probably the biggest reason I’ve been flying it more. I have multiple batteries, but having to stop and change the batteries takes some of the fun out of the helicopters. Beginners might get a little turned off when they crash and get afraid of destroying it, but once they get over this, this plane can probably be flown by beginners.

    Running with an iPhone

    A few weeks ago I started listening to audiobooks again and became very engrossed in a James Patterson book. I was running with an iPod Nano and walked the dog with my iPhone as well as had my iPhone with me while driving. In order to keep my position in the book, I had to sync the Nano after my run, then sync my iPhone and then before my run, sync the iPhone and then the Nano. This got old real fast (a few days).

    I had been eyeing the Fisica Fitness Sensor Key for my iPhone to hook up my heart rate monitor for use with RunKeeper Pro. I couldn’t resist as eliminating my iPod Nano from the equation would make my life easier. I received the Sensor Key about 10 days ago and did my first run the next day. RunKeeper Pro is a decent app that handles everything my Garmin ForeRunner 405 did and more.

    I thought that the weight of the iPhone 4 on my arm would be a problem (I also bought the case that Wahoo Fitness sold), but it isn’t that bad. The Sensor Key does exactly what it is advertised to do; it connects Ant+ devices to the iPhone. RunKeeper Pro integrates the heart rate monitor fairly well, but displays the current heart rate in a very small part of the display (almost unreadable). The iPhone is a bit unreadable in bright sun, but the large display is nice.

    After a few runs with the iPhone, I can’t see going back to my iPod Nano and Garmin ForeRunner 405. One of the best features that just came to light today was when I was happily running and the narrator of the book’s voice started fading and the phone rang! I was quite surprised, but saw that it was my boss (technically my boss’s boss) calling, so I slowed to a walk and answered the call. I don’t get many phone calls, so being able to get a call when I take a midday run is a great feature of using the iPhone for running.

    If I had been running with my iPhone last month, I would have been able to take a picture of the guy who had put a rope around his Christmas tree and dragged it behind him to take it to the recycling place instead of putting it on the roof of his Ford Explorer!

    I’d like for RunKeeper Pro to add the ability to bulk export the files and then this combination would be perfect.

    Mystery of poor iPad battery life

    Last week I started noticing that my iPad would go from 100% to about 10% battery life in one day with very minimal usage. This had me confused, so I decided to try 2 things to see if I could get the battery life back up. Unfortunately I tried both things in conjunction, so I’m not sure which one of the two made a huge difference. The first is I restarted the iPad. This sounds like a no-brainer, but I usually don’t reset my devices. I noticed that I couldn’t complete a call on my iPhone the other day, so I restarted it and it felt a lot more responsive; so I gave the iPad a restart to see if it would help.

    The second thing I did, which is kind of a “duh” is I turned off push notification, removed 1 email account, and switched to checking data every 30 minutes. The push notification system keeps a connection constantly open with Apple’s server so that if a notification comes in, it can be sent down the already open pipe. This, of course, takes power to maintain this connection. However, I leave push on for my iPhone and I don’t see a huge drop in battery life. There are, of course, many differences such as the size of the battery and I charge my iPhone every night.

    Well, my battery life is back up to several days of light usage and turning off push notification isn’t a huge deal on the iPhone. I’m not sure if the reset or the push notification was the problem. If you start see declining battery life on your iPad try one or both of these tips; it might just help.

    Synchronous vs asynchronous networking programming

    When I first started learning how to write code, everything I wrote was done sequentially with some goto loops; it waited for input, did something and then waited for more input. When I started writing network code on Mac OS, I had to fumble through Universal Procedure Pointers (UPP) in order to wait for connections and not block the user interface. Now that we’re into the golden age of Mac OS X and iOS, those days are behind us. Most network programming is done with NSURLConnection either the synchronous or asynchronous calls.

    The synchronous call

    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request
    	returningResponse:(NSURLResponse **)response
    	error:(NSError **)error

    is quite easy to use as it simply returns an NSData object. Anyone that has done iOS programming knows, you absolutely cannot use this call on the main thread as it blocks and won’t return until it times out, errors out, or returns data. The iOS watchdog timer will kill an unresponsive application as outlined in an Apple technote.

    So what many developers do is either wrap this call in an NSOperation or simply perform it on a separate thread. This allows the user interface to be responsive and won’t get the application killed by the watchdog timer.

    However, this is probably not the best way to handle network calls and I’m kind of disappointed that Apple has even provided the method. There are a number of things that the synchronous call can’t do (even in a background thread):

    • Requests can’t be cancelled. Once you issue the call, it only returns when it times out, when it gets an error, or gets the data back. There are many cases where you want to cancel a request; for instance, if you’re loading a bunch of images and a use exits a screen, you should cancel the outstanding requests.
    • Authentication can only be specified at the start of the call. Using NSURLProtectionSpace, the authentication can be specified as part of the request. If you want a user to enter a username/password based on an HTTP 401 error, you can’t do this with a synchronous call.
    • Responses can only be handled at the end. For instance, redirect (page moved requests) can’t be acted upon until all the data is downloaded whereas with an asynchronous call, you get the response once the header is downloaded. A former Apple engineer, Jens Alfke, wrote that basically the synchronous call treats many response as errors instead of recoverable conditions.

    The first point is my biggest problem with the synchronous call and people might say that if you never want to cancel the call, who cares? That seems a bit short sighted to me.

    Using the code that Dave Dribin wrote on concurrent NSOperations you can easily construct a nice asynchronous networking class and queuing mechanism. I’ve done this twice and there is no reason that I can think of to still use synchronous networking calls on iOS.

    I’m sure that some people will argue with my logic and that’s fine. I’ve been writing networking code for my entire career and while I’m not going to claim to be an expert on it, I’ve seen good and ugly (mostly written by me). The synchronous calls look quick and dirty while the asynchronous calls look like a lot of work. I agree with a friend of mine when he said in a StackOverflow discussion that asynchronous calls were the “The Right Way”.

    In fact, asynchronous networking calls really aren’t a lot of work. I was scared of asynchronous networking calls until I started writing Objective-C code; you just have to structure your code with delegates and handle the callbacks. I believe you should do this wrapped in an NSOperation to make sure that you only have a few networking calls outstanding at a time (you really only have so much bandwidth so trying to flood the channel with calls isn’t going to be all that effective). In addition, this will help properly display the network activity indicator on iOS.

    Can anyone think of a reason besides “it’s easier” to use the synchronous version of NSURLConnection vs the asynchronous call?

    Losing a customer

    When I setup the DBA for my company, Gruby Solutions, I went ahead and found a free business checking account with Washington Mutual. While I didn’t need a bank account as my company is a sole proprietorship, I figured it would look more professional and could have some benefits down the line. When Chase bought Washington Mutual, the free account transferred over. When my wife was looking for a bank account for her business, she also chose Chase.

    Things were fine until last month when Chase sent us letters saying that they’d start charging us $15 per month for our accounts, but with a minimum balance of like $5000 or a large number of debit card transactions, the fee would go down. As my company isn’t bringing in any money right now, I decided to simply close my account. My wife, on the other hand, needs her account for her business. She did some research and found that Comerica bank offered free business accounts; there is a branch pretty close to our house, so it was a no brainer for her to also start the process of closing her account. (They do charge for allowing us to hook Quicken to it which annoys me as I’ve gotten used to downloading transactions from my bank.)

    While I understand that Chase probably considered us freeloaders, they lost 2 banking customers that will likely never return.