I was asked to photograph my friend’s wedding…

I work with Chee Yi at Expedia- we write Swift code for 8 hours every day and often discuss other topics and hobbies we have. We both have a love of photography.

He had been planning on getting married to his long-time girlfriend Zen-Zi, and they decided to elope at the local county courthouse. He bought a Canon EOS 5D Mark III, but he can’t photograph his own wedding.

So he asked me to do it. How could I turn him down? I’ve been taking photos and portraits of family and friends, and also doing some street photography for years. So now I can say I am a wedding photographer!

Before the ceremony, I took a few photographs of the couple and the bouquet.


The ceremony was short and sweet. The judge read the vows, and the bride and groom’s parents watched the ceremony on a FaceTime call.


After the ceremony, I took some shots of the newly married couple in the Government Center.


Now that the ceremony was over, we walked through the Minneapolis skyway and stopped for some portraits along the way to the restaurant for dinner.


After braving the cold for only one block, we made it to the restaurant for dinner. Everyone but me ordered seafood. Zen-Zi’s sister Wen-Qi baked a very fancy wedding cake, and after dinner the wedding couple fed each other some of it!


It was a great day, and I wish all the best to the happy couple. It was an honor to photograph the event for them!

Vikings VS Patriots at TCF Bank Stadium

I had seats in the first row at the recent NFL football game between the Minnesota Vikings and the New England Patriots. I brought my camera and took as many shots as I could of the action since I was so close. I did my best impression of a sideline photographer.

The game was at noon, so we left at 10am, thinking that would be plenty of time to get there. We were wrong. The Vikings are currently playing at TCF Bank Stadium, home of the University of MN Golden Gophers while the new Vikings stadium is under construction. Traffic was very heavy getting to the game.

We had pre-paid parking at a lot near the stadium. When we got there, we realized we were parking in a tailgate lot, and had to slowly, carefully, and awkwardly drive past football fans in the lot who were happily drinking beer, grilling, and playing catch. Then we just parked in a space where previously people were playing catch after they moved their beer. Embarrassed, we hurried out of there to get into the stadium.


Our seats were right by the tunnel where the visiting team enters the field, which we were not aware of, but it was a very good surprise to see the Patriot players up close.

Tom Brady entering the stadium

The view from our seats was great. We were so close that the cheer leaders could obstruct our view of the game with their pom poms! Thankfully I only have one shot where this happened.

Cheerleader blocks my view

I did get a shot of Greg Jennings making a catch in the front corner of the end zone, but he only got one foot in bounds.  I didn’t see that particular foot myself because a cheerleader obstructed my view.

Jennings Makes a Catch in the End Zone

Another thing I experienced (that I did not expect) is that a lot of fans ask for mementos from the players as they exit the field. Lots of shouts for gloves, head bands, etc. from the players on their way out. Here’s a photo of Aaron Dobson throwing his gloves into the stands. I couldn’t bring myself to take part in the mayhem since I was wearing a Vikings shirt and asking Patriots for mementos just seemed wrong.

Dobson Throwing Gloves

Unfortunately, the Vikings lost the game, but it was a great experience.

TCF Stadium after the game

All of my photos can be seen on my Flickr account here.

Taking photos under a bright sun

You may think that you do not want the midday sun behind your photography subjects. With the sun behind them, they would be in shadow.

But then if you put the sun behind you and have your subjects face the sun, this photo is what you get. It was impossible for anyone to keep their eyes open!

If the sun is extremely bright and overpowering, your best bet is to put the sun to the side of you and your subjects, or take the photos at a different time of day if possible.

Debtor version 1.5 with support for iOS 8 and the new iPhone 6 and 6 Plus is now available!

Debtor version 1.5 is now available in the App Store.

Debtor Calculations iPhone 5s

The keyboard functionality has changed in this version to use the full keyboard instead of the number pad keyboard. This way, I was able to eliminate the need for an accessory bar above the keyboard with Navigation and a Done button. This frees up more space for content, which is needed on the iPhone 4S. The standard keyboard already has a Next/Done button. Plus, tapping anywhere in the background on the Calculation screen (the first screen in the app) will dismiss the keyboard!

Debtor Comparisons iPhone 6

Support has also been added for the new iPhone 6 and iPhone 6 Plus, and for iOS 8 as well. Feedback and reviews in the App Store are appreciated!

Debtor Comparison Results iPhone 6 Plus

Debtor version 1.2 now available!

Debtor 1.2
Debtor version 1.2 has been approved for sale in the iTunes App Store. This version adds a compare feature. Compare the current monthly payment to any number of other payment scenarios, or compare the current number of months to any number of months. Debtor will show how much money can be saved by paying more per month, or paying off a debt in fewer months. Conversely, it will also show how much extra money will be owed by paying less per month, or paying off a debt in more months.

Numerous bug fixes are also included in this update.


I saw Prometheus in glorious IMAX 3D on opening weekend, and thoroughly enjoyed the film. It starts off with sweeping vistas of pristine landscapes, which look beautiful on the big IMAX screen. There were a lot of callbacks to the original Alien movie, most of them subtle. Some as simple as the Prometheus having a similar interior architecture and design as the Nostromo. Prometheus had scenes of futuristic sci-fi gadgetry, sequences of fast-pasted action, and a few horrifying and terrifying moments, and I enjoyed them all. I won’t say too much more about the content of the film, because I don’t want to give anything away for anyone who hasn’t yet seen the film.

Prometheus is a stark contrast to the Avengers, both in tone and content. The Avengers is a PG-13 fun comic book action movie that doesn’t take itself too seriously, while Prometheus is an R-rated epic science fiction film, with lots of imagery and dialog that is intentionally vague, so that after the film ends, the audience is left with plenty to discuss as they parse what they just saw and what it meant. Once the Avengers ended, although I enjoyed it very much, I simply left the theater and left the movie behind.

I had high expectations for Prometheus, and have been following a lot of the discussion on Twitter and the greater internet. Eventually I did stop to avoid spoilers as the premiere date approached. I even stopped reading Roger Ebert’s review because I felt it was getting too far into the plot. Now that I’ve seen the film, I am free to participate in the discourse and watch all things related to Prometheus. Prometheus definitely lived up to the hype in my opinion, and I will see it again as soon as I can.

The Art of Programming Without Programming

As I have been working on Debtor, my iOS app, I’ve come to realize that half of the work of programming is done away from the computer.

It’s a cycle, and it goes like this:

I spend many minutes, perhaps hours, coding and reviewing API documentation to build my application. I get stuck on a certain problem, and all the documentation, googling, and fiddling around in the code is not going to solve the issue. I need to stop and THINK.

So I step away from the computer, and go do something else.

While I am away, my programming problem is still there in the back of my mind, and if I’m not actively engaged in some other activity, I will go back and think of different ways I could possibly solve it. Meanwhile I’m in the shower, walking up the stairs, driving in my car, whatever. And then all of a sudden, a solution will come to me.

I can’t wait to get back to my computer to try out my proposed solution. Often times it is the correct solution, and I just needed time to process the problem in my mind before I could find a solution.

So if you find yourself stuck on an issue with your code, and you don’t know how to solve it, just walk away, find something else to do, and your brain will continue to process your problem, and solve it for you while you go about your daily business.

Concrete example:

Problem: I have a tableView with a textField inside each cell. I need to find a way to update the data source for my table with the data entered in the textField. How does the textField know which cell it is in? Do I have to keep a separate array around to keep track of the textFields? Should I just loop through the tableView cells when I really need the data later, or should I capture the data as the user enters it?

Solution: Go take a shower. In the shower, I remembered that each view can get an array of subviews, so there must be a way to get a superview of each view as well!

UIView * parentView = textField.superview;

This gets the parent view of the textField. Then cast the UIView to a UITableViewCell, which I know it is, because that is the only thing that has a textField in my class. The text field delegate method

-(void)textFieldDidEndEditing:(UITextField *)textField

is the perfect place to get the textField’s superview, because at that point the user is done editing the textField. I can grab the text in the textField at that time, and update the proper array element in the table’s data source. But then how do I get the array index that I need to update? From the UITableViewCell, which is the superview of the textField, I can get the index path from the table view by sending it the indexPathForCell:(UITableViewCell *)cell message. From the index path, I can get the row, and send the data source array the objectAtIndex:[indexPath row] message to get the correct entry in my data source array. Then I just update the data source with the textField.text, and my data and view are in sync!