Kip Vidsplosion

It’s been a while since I’ve posted here. What can I say, I’ve been busy. If you’re interested, I’ve put up several new photo albums: Easter, May-July 2011, Beach Trip 2011, Grayson’s first birthday party, and some old photos that I never took off my old digital camera from Thanksgiving 2009.

And I’ve also got lots of videos to share. First up is my role as Cat In The Hat at Emma’s third birthday party:

Here’s a random video of the kids playing in the backyard:

Here’s a video of Grayson eating cake at his first birthday party:

Here’s Grayson opening a present at his party:

And last but not least, here’s Grayson playing in the pool during his pool party:

I apologize for the videos from Grayson’s birthday being so dim. For whatever reason, when recording video, my camera uses the exposure compensation setting from the last time you were in manual settings mode. And usually when I’m in manual settings mode it’s because I want to try a long exposure, which always turn out too bright, so I turn the exposure compensation all the way down to -2.

No Comments
Kip Password tips for non-geeks

I’ve been thinking about passwords recently, as I have gone and changed passwords for pretty much every website that I can remember having a password for. For me, this was prompted by the hacking of PlayStation Network, which led to my PSN password being compromised. And, like most people, I used the same password for PSN that I used for many other sites. This is generally a Bad Thing, but what are you going to do?

Well, for geeks, the answer is “have a separate, randomly-generated password for every site, and the password must be long and contain numbers, lowercase letters, uppercase letters, and symbols.”

I realize that this is impractical for normal people.

So here’s my advice for non-geeks. Come up with a sentence. A really random sentence. Try to include some numbers in the sentence. Then take the first letter of each word. This will be your base password. Here, I’ll make up an example:

forget about the last 7 things u Heard 2-day

That gives us: fal7tuH2d

Believe it or not, it’s really easy to remember a sentence like this! You can leave out articles, conjunctions, and/or prepositions if you like, and you can replace “are” with “r”, “you” with “u”, etc. Whatever is most natural for you to remember. Making at least one of the letters uppercase and including some kind of punctuation is good. Make sure there are at least 7 characters, since a lot of sites use 8 characters as the minimum length of a password.

Next, come up with a rule for how you will include the company name in the password. For example, “use the last letter of each word in the company name, and capitalize the last one”. Using this rule, my password for Amazon, PayPal, and Gmail might be as follows:

Amazon: fal7tuH2dN
PayPal: fal7tuH2dyL
Gmail (Google Mail): fal7tuH2deL

Now, if someone somehow obtains your password to one site, they won’t have your password to every site you use. And hopefully they won’t be able to figure out the rule for the last few characters (this is why using something other than the first character of the site name is a good idea). And no one’s ever going to guess a password like that.

Of course, this isn’t fool-proof. But it is a lot more secure than using the same password for every site, and it’s a lot more secure than using a word that can be found in a dictionary or your pet’s name or your birthday or something like that.

Note: If you really want to do it the geeky way (a long, random password for each site), you can get applications that will generate random passwords and store them securely. This makes it so you only need to memorize one password, and that password lets you access all your other passwords. I like KeePass, and it runs without an installer on PC and (I think) Mac. I keep it in my Dropbox so I can use it from home or work. But I don’t do it for every site; mainly, I just do this for really sensitive sites (like bank and credit card websites). And remember, if someone really wants your password, they can probably crack it in a few hours with just five dollars of equipment.

No Comments
Kip Race Day

As I write this, I can hear race cars finishing up the final laps of the Coca-Cola 600, the longest Nascar race, held every year on the night before Memorial Day. You see, about four years ago, we bought a house about a mile away from Charlotte Motor Speedway (which was called Lowe’s Motor Speedway at the time). Let me let Google Maps help you out:

Now, when I tell people I live near the speedway (“Garage Mahal”, as some call it), usually the first question people ask is either “Can you hear the races?” or “How bad is the traffic?”. So I figured I’d provide a nice, canonical answer here on the internets.

First of all, to be clear, I was fully aware when I bought the house that there was a speedway, a dirt-track, and a drag strip about a mile away. I understand that this means I have no right to complain about the noise, any more than if I had bought a house next to the airport. This post isn’t here to complain, just to provide an answer to a question I get a lot.

So, there are three types of events: drag races, dirt track races, and Nascar races. The drag strip was built most recently, amid quite a bit of controversial local politics. A lot of people were concerned about the noise. Dragsters are loud. But here’s the thing: dragsters only run their engines for about a second. Two seconds tops. Then it takes about ten minutes till they are set up for the next race. Of the three types of races, even though the drag race might be the loudest in terms of decibels, it is easily the least disruptive to my life. It’s less annoying than when a Harley drives down the street.

Next, the Nascar races. There are three events each year: the All Star race, the Coca-Cola 600, and the Bank of America 500. These are pretty loud, but it’s not so bad that I can’t tune it out while I’m watching TV or something. And it’s kind of neat being able to see the Goodyear blimp from my backyard twice a year.

So finally, we get to the dirt track. The way I usually describe the sound is that it’s kind of like someone standing in your back yard with a chainsaw. I don’t know why dirt track cars are so much louder than Nascar cars. But they are super loud. When there’s a dirt track race, you basically can’t watch TV in your living room that night. It’s the only time the noise from the races is bothersome.

As for the other question—traffic—it is usually not a big deal because we know when to avoid the races. We’ve even found that going to the nearby mall during the races is really nice, because all the race fans are at the race, and most of the locals who aren’t at the race are afraid to go anywhere near the race. The biggest traffic concern is actually the auto fair that occurs twice a year, where (as far as I can tell) people who collect and build antique cars get together to buy and sell cars and car parts. The traffic is really bad from these events because people are coming and going all weekend long. There’s not one particular event that everyone shows up for. And it’s also not as well-publicized, so there are more people who would steer clear of the area on race weekends that don’t know to do the same on car show weekends.

So there you have it. A long, boring description of life lived near one of the largest sporting venues in the world. Hope you have a great Memorial Day!

No Comments
Kip HTML5 video

I’ve supported HTML5 video on this site for something like a year now. I don’t think I have commented yet on just how much of a pain it is. This post isn’t a tutorial; other people have already written very good tutorials on HTML5 video. Don’t get me wrong—HTML5 video is a nice thing to have. The videos on this site can play on Flash-less devices like iPhone, iPad, and Android. For current versions of every desktop browser, the video plays nicely without the overhead of loading a Flash container. (And let’s face it, everyone hates Flash.1.) And the syntax is backward-compatible, allowing older browsers to see a flash video player that newer browser will ignore. All-in-all, it’s pretty nice.

Except for the fact that I’m required to convert my video to 4.1 different formats! To play properly everywhere, the video has to be served in:

  • MP4 - for Safari, iPhone/iPad, and Android

  • OGV - for Firefox, Chrome, and Opera

  • WebM - For IE9

  • FLV - For flash player fallback in older browsers (IE 6/7/8 mainly)

  • JPG - Okay, so this isn’t a video format, and it’s not required. But if you don’t pre-load your videos, you need a jpeg to use as the background letting the user know there is a video there they need to click on. (When I said I need 4.1 formats, this was the point one.)

This is pretty ridiculous. If the img tag didn’t already exist, and it were to be added as a new HTML5 element, the syntax would probably look something like this:

1
2
3
4
5
6
<img>
  <source src="/images/whatever/whatever.jpg" type="image/jpeg" /> <!— for Chrome/Safari —>
  <source src="/images/whatever/whatever.gif" type="image/gif" /> <!— for Opera —>
  <source src="/images/whatever/whatever.png" type="image/png" /> <!— for Firefox —>
  <srouce src="/images/whatever/whatever.bmp" type="image/x-ms-bmp" /> <!— for IE —>
</img>
No Comments
Kip Joining together for better queries

Here is a tip for writing better SQL queries—specifically, the FROM/WHERE clause.1 I only work with SQL Server and MySQL, so the syntax may be different in different engines.2 I’m writing this because I often see very smart and experienced developers write some downright ugly SQL. I don’t mean to call anyone out; I just want everyone to know there is a better way of joining.

Rule of thumb: If you have a comma in your FROM clause, you’re doing it wrong.

Let’s take a query I just made up as an example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT AVERAGE(Grades.score)
     , Departments.Name
     , Students.Gender
FROM Students,Grades,Departments,Teachers,Courses,Classrooms,Buildings
WHERE Students.id = Grades.Student_id
  AND Courses.Period = 3
  AND Courses.id = Grades.Course_id
  AND Buildings.Building_id = 11
  AND Classrooms.id = Courses.Classroom_id
  AND Buildings.id = Classrooms.Building_id
  AND Grades.Grade > 0
  AND Teachers.id = Courses.Teacher_id
  AND Departments.id = Teachers.Department_id
GROUP BY Departments.Name, Students.Gender

So what’s so bad about this? First of all, it’s tricky to see what exactly we are trying to do here. The WHERE clause is huge, and it’s full of stuff that isn’t really relevant to what we are trying to return. If you were told that this query was returning the wrong values, you would have to stare at it for quite a while to figure out what’s going on here. You know what tables the data is coming from, but you don’t have any simple way to tell how those tables relate to each other. You have to reverse-engineer that information from the monster WHERE clause.

And here is where developers are most likely to mess up: if you forget just one of those AND predicates in the WHERE clause, you end up with a cartesian product. This means if one table has n rows, and another has m rows, you will get n×m rows. This is pretty much never what you actually want. If the developer is working on a small database, with very little data3, he might not even realize this is happening. He checks in his code, and goes on to the next problem. But then the system goes into production, and the tables get a few hundred rows each, and now the query runs for twenty minutes and then the database server crashes! Ouch.

So, what’s the solution? Like I said, if you see a comma in your FROM clause, you’re doing it wrong. JOIN to the rescue!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT AVERAGE(Grades.score)
     , Departments.Name
     , Students.Gender
FROM Grades
JOIN Students    ON Students.id = Grades.Student_id
JOIN Courses     ON Courses.id = Grades.Course_id
JOIN Teachers    ON Teachers.id = Courses.Teacher_id
JOIN Classrooms  ON Classrooms.id = Courses.Classroom_id
JOIN Departments ON Departments.id = Teachers.Department_id
JOIN Buildings   ON Buildings.id = Classrooms.Building_id
WHERE Buildings.Building_id = 11
  AND Courses.Period = 3
  AND Grades.Grade > 0
GROUP BY Departments.Name, Students.Gender

In this version of the query, we JOIN each of the tables together in the FROM clause. This has several advantages, but the biggest by far is that it forces the developer to specify how the tables are joined together. This makes it extremely difficult to accidentally create a cartesian product. It also cleans up the WHERE clause, stripping it down to conditions you are actually filtering on. In this case, we are just looking at third-period courses in some particular building where students are at least attending the class. Whenever I make a change to an existing query that doesn’t use joins, I usually rewrite with joins. I’ve done this for dozens of queries, and the WHERE clause is reduced to a single statement probably 80-90 percent of the time. This makes the query much easier for the next developer to understand at a glance, especially since the join conditions aren’t likely to change over time. As far as performance goes, there is a slight benefit because you’ve already told the database how the tables are joined together. But the database was already figuring this out on its own, so there’s not much of a difference. But it certainly doesn’t perform any worse.

Update 4/18: I forgot to mention one other benefit of this approach. There is a type of error that comes up every once in a while looks something like this: “This query doesn’t return online courses because Courses.Classroom_id is 0/NULL for online courses.” This is easy to solve with joins. Just change the “JOIN Classrooms” clause to “LEFT JOIN Classrooms”. I’ve seen some ugly code that tries to accomplish the same thing with UNION. Union is worse for performance than left join, and left join is specifically designed for this purpose.

1 I already know what ORM is. Some of us are working on code that doesn’t use ORM and we can’t do anything about it.
2 As I recall, this works in DB2, but I haven’t used it in 2 years. It works in Access if you replace JOIN with the more explicit INNER JOIN. And I’m pretty sure Oracle uses some other kind of crazy syntax. Edit: I’ve been told Oracle supports the same syntax.
3 Bad development practice, but don’t pretend like you’ve never done it.
Kip Emma’s third birthday

Hard to believe it, but tomorrow marks three years since Emma was born. She had a Cat in the Hat themed birthday party. A few pictures have been posted!

Also, she got a functional digital camera. Except, whenever I see the camera, it makes me a little uneasy. I think it is going to hop at me sideways. I have the urge to fire a missile at it. What is he talking about, you ask yourself? The camera bears an uncanny resemblance to a Dessgeega!

See what I’m talking about?

No Comments
Kip Disney World

I just posted a ton of pictures from our recent trip to Disney World. There are also some miscellaneous pictures from January and February that I posted a while back but never mentioned on this blog.

No Comments
Kip Donkey Kong Country Returns

I finished Donkey Kong Country Returns a few weeks ago and I thought I’d share a few thoughts. Overall, it’s really really good. The most notable thing about it is the difficulty. When a patent filed by Shigeru Miyamoto was discovered a few years ago, describing a system where the game would help players get past tough parts, it was pretty harshly mocked by the gaming community. Since then, the feature has come to be known as “Superguide” and it has been included in New Super Mario Bros. Wii, Super Mario Galaxy 2, and now Donkey Kong Country Returns1. The last two in particular have shown that the feature doesn’t result in super-easy games aimed at the lowest common denominator. The effect has actually been pretty much the opposite—Nintendo has been able to make really challenging games that they can still market to a broader audience. So getting back to DKCR: the game is really challenging. But it’s not challenging in the same way that NES games were, throwing things at you just for the point of killing you. In those games, when you fail you usually feel like the game was designed in a way that was bad or just unfair. In DKCR (or SMG2 for that matter) when you fail it is usually your own fault. I’m not sure I articulated that well enough. I guess what I’m trying to say is the game didn’t feel cheap. EXCEPT...

The bosses were universally awful. Just the worst. I find it hard to believe that these are the same guys who did boss design in the Metroid Prime games.

The Rocket Barrel stages were also awful. The whole control mechanism felt like it was introduced late in the dev cycle and just didn’t get enough testing and tweaking. The worst example was level 4-5: Crowded Cavern. I died something like sixty times in that level.

Another thing that was nice about this game was that I could play it when Emma was in the room. (Most of the other games I have played lately focus on creative murder, which is inappropriate for 2-year-olds.) One of Emma’s favorite things to do was see the “monkey house” in the very first level. And this is something too cute not to share.

1 Superguide may be in some other games, but those are the only ones I know of.
Kip Side projects

Here’s an update on a few side projects I have going. First, you may remember QuickReplace. As I used it myself, I realized that there were some limitations, which I set out to address. So now we have QuickReplace 2.0. One thing I found myself doing with QuickReplace was opening it in several tabs, pasting text in the first tab, copying the output and pasting it in the next tab, because each tab could only run one filter at a time. But now, instead of having a fixed number of filters, which are executed in a fixed order, you can add as many filters as you want. The filters can be dragged and dropped in whatever order you want. And, if you want to save a filter and run it later, there is now a permalink option to do so. As before, the tool was written for me by me, with the assumption that the user (me) knows what they want to do. If you’re a programmer and you understand regular expressions, you should be able to figure it out. I’ve been using the new version for about a month and I think I’ve ironed out all the bugs, but if you find one let me know and I’ll take a look. Unless your “bug” is that it doesn’t work in a browser other than Firefox or Chrome. In which case the bug is that you’re using the wrong browser. (That being said, it seems to work just fine in IE, Safari, and Opera, but I haven’t tested extensively.) Also, the HTML file is self-contained, so you can save it locally if you’d like. (But you can’t run it offline because of a dependency on Google-hosted jQuery.)

The other side project I’ve made some updates to is my gradient generator. The previous version would generate horizontal or vertical gradients. But then I started thinking, wouldn’t it be better if it generated diagonal gradients too? So I worked out the math and made it happen. Now, instead of an “orientation” parameter that takes either “h” or “v”, we have an “angle” parameter, which takes a number in degrees (from 0 to 360, inclusive). It still takes “h” or “v”, for backwards compatibility—”h” is converted to 0, and “v” is converted to 90.

I added an extra parameter, “extend”. If it is false, the image is only as large as it needs to be to hold the gradient. This is OK if the image is being used as the background of a fixed-size element, but otherwise you won’t see the whole gradient. This is where the extend parameter comes in. If it’s set to true, you will see the whole gradient.

So here’s what it looks like without the extend parameter:

You might also notice that the y axis is inverted. That’s just how images are oriented, and I didn’t correct for it since I figure the most common case is a gradient oriented in the top-left corner. Now, if the gradient is extended, it will look like this:

You can view the gradient generator source code here.

Of course in a few years, when CSS 3 gradients are fully supported, my gradient generator will be obsolete. Oh well.

No Comments | Add Comment
Kip ImageSizer update

If anyone is using ImageSizer, my unimaginatively-named multi-monitor image resizing and cropping tool, I’ve made some minor-but-long-overdue updates. Namely, it can operate on a list of input files, instead of just one. And the list of input files can be anywhere in the parameter list. So you can do something convenient like this:

1
java -jar ImageSizer.jar -monitorWidth 1024 -height 768 *.jpg

Download it here!

The source is also included in the jar file, if you are interested. And if you don’t know what ImageSizer is, I wrote a pretty extensive description with the initial release, which should answer all your questions.

No Comments | Add Comment
RSS feeds: Kip's - Stephanie's - Both