I got an email from a local rider yesterday, telling me that my Cycling climbs webpage was broken. I did some investigation and found that Google had rev'd their software, and I would need to make some small changes to get my site up and running again.
I also found out that they released an official API for their maps. This is great news.
While I enjoy the intellectual aspect of doing a bit of reverse-engineering (which is something I've been doing in both hardware and software since... well, since I was a lot younger than I am now...), being at the whims of something that has no docs and can change under you isn't the best situation. I spent some time looking at their stuff last night, and while it looks like they don't have everything available from the API, it does enough for what I want. And there are some good examples for how to do things.
You do have to sign up to get a key for the API to work, which I think is more than reasonable. The key is associated with your website root, you put the key in your webpage, and then the google server will talk to you.
If you want to convert your existing maps, here's a decent post from somebody who's done the conversion.
There's also a new discussion group on the mapping api.
If you do anything particularly cool with the api, please link and/or comment so I can take a look.
I posted this on Monday, but it got eaten during a server upgrade. Luckily, the lemmings post didn't.
I'm very pleased to report that the third edition of my book has now shipped. As I've noted in the past (in a post I linked to in the first version of this post, but am too lazy to link to right now), the bulk of the work on the update was done by Nick Wienholt, a C# MVP. When the time came to work on an update, I had neither the time nor the mental ambition to spend time on it (ie I was burnt out), and Nick ably stepped into the breach, while I reviewed his additions and added a bit of seasoning here and there.
So, it's sort of a bittersweet moment for me - I'm unhappy that I wasn't as closely involved as I might have been, but happy that there's a new edition of a book that had become more than a bit dated - the second edition was completed shortly before Beta2 of the C# 1.0 shipped.
The second edition fixed a lot of problems in the first edition, but because it was only a second edition, Amazon wouldn't reset the reviews, so lots of the reviews were for the first edition. This time, they've decided for some unknown reason to consider the third edition to be a new book (probably because of the change in authorship).
For the most part, being involved in blogs has been very positive, but every once in a while, something happens that makes you question the judgement of humanity. It's especially bad when it's somebody you know. I guess at my age, I shouldn't be surprised when people I respect - or, to put it more correctly, people I *used to* respect - exercise bad judgement.
It all started when Dare (who I'll now have to post on my list of ex-friends) made a post, which I somehow missed on his blog.
Then Chris compounded the mistake by linking from his blog.
C'mon guys! I already have enough distractions in my life. At least the number of levels are limited...
I've heard that tickets are going fast to PDC 2005, so if you're thinking about maybe going, it would be a good time to sign up.
I also bring you PDC05 Road Trip - Episode 1
Which I think is pretty good, except for two things:
1) I don't understand the recurring bathroom scenes. It was good in the TechEd one, but seems redundant here.
2) The verisimilitude of these things is usually ruined for me, as I usually get about 30 seconds into it before I say, "I know that dude!"
Last August, I wrote a post talking about my efforts to create a remotable version of Windows Media Player from within C#.
It's pretty easy to use COM interop to embed an instance of the windows media player in a C# application, but there's a class of applications where you'd like to be able to control the full instance of WMP.
I got my stuff to work with a C++ shim that an acquaintance wrote for me, but it wasn't terribly elegant and made the project more complicated, and I'm by no means enough of a COM expert to consider trying to write it in C#.
Luckily, there are people who *are* experienced enough in that area to do so, and a week or so ago I got an email from Jonathan Dibble, a Microsoft Consultant who works in New York, saying that he had written this, and asking me if I was interested.
So, courtesy of Jonathan, I'm pleased to present Remoting Windows Media Player in C#.
Another in my series of time-waster games links:
Hint: Watch for the shadow...
Jim posted a comment on my century ride, talking about what I ate. He totalled up what I ate during that time period, and remarked on how small it was. I agree, though I get a number that's even smaller than the one he got:
Input: 330 calories in Clif Bars 520 calories in Accelerade 250 calories bagel 55 calories Newton 250 calories pretzels ____ 1400 ingested
That takes us onto the calories that I expended. The only good way to measure this is with something like a PowerTap, which is a wheel hub that measures how much force you're putting into your back wheel. Integrate that over time, and you get power, and you can make a good estimate of how much energy you expended.
Without that - and I don't think I'm likely to spend the money for a PowerTap or other power-measuring system, at least in the near future - you're stuck with estimates, which suck. The number of calories you expend vary depending on the speed you're riding, whether you're riding in a group, whether it's hilly, etc. I'm going to choose 500 cal/hour as a ballpark estimate. That means that for 5.5 hours, I spent:
5.5 * 500 = 2750 expended.
That doesn't seem so different from what I ingested, though I didn't eat my regular meals during that time (I ate less for breakfast and didn't eat lunch), which adds something like 900 calories.
2750 + 900 = 3650 expended.
for a net of:
3650 - 1400 = 2250.
So, where did the extra come from? It came from my fat stores. I've been doing some reading on this - Chris Carmichael's "Food for Fitness" (very good, by the way) and a few research studies - and it turns out that fat transport can supply a lot of calories over a long period, under two conditions.
The first is that the system is trained. The second is that there's sufficient glucose available to keep things going. To simplify, you need a constant supply of glucose to keep your metabolism going and your brain happy - if you get low on glucose, your brain will hoard it and you performance will tank, with the dreaded "Bonk".
Making another assumption - that I was getting approximately 80% of my energy from fat and 20% from carbohydrate, you'd expect that of the 3650 calories, 2920 came from fat and 730 from carbohydrates (okay, there's some in there from protein, but not a large proportion).
With the exception of the Clif bars, most of what I ate is at least 75% carbohydrate, so there's plenty of carbs to keep me going, assumming that it can get into the bloodstream quickly enough. That's where the Accelerade helps.
At this point, I should note that I'm not an expert at these things *and* that I've made a ton of simplifications along the way. For example, the brain uses a fair amount of carbohydrate, but that use can be supplied by conversion from fat to carbohydrate, so the carbs that I took in didn't need to support that part of my base metabolism, and were therefore free to be used towards the exercise.
Yesterday, I participated in my first Century of the year, a hilly 100-miler (hence the term "century") known as the Flying Wheels Summer Century (alternately known as the "Screamin Thighs Summer Century").
In last year's edition, I rode by myself and finished in 6:49:22, averaging about 15 MPH.
This year, I was hoping to do better. Though I had only broken the 50 mile once this year, I had been riding hard with some faster riders, I had a new bike ("the beauty") that was nearly 10 pounds lighter than my last bike (the rain bike, aka "the beast").
I did the 50 mile version with a group a week ago, and then rested my legs for the week. I prepared Friday night by getting about 3 hours of sleep and arose Saturday at 6 feeling groggy, dehydrated, and a bit queasy. The almond Clif bar and 16 oz of water I had for breakfast did nothing to improve the situation, but at least I made it to the starting line with all my gear, including my shoes.
We ended up with a group of about 12 riders, and headed out. The first section of the ride (about an hour or so) takes you on two major climbs, and I wasn't feeling much better at the first food stop. I drank a large chunk of my Accelerade, and we headed out in a paceline across the valley towards Duvall at a bit over 20 mph. I wheel-sucked mercilessly, as there was no way I was going to be doing a turn at the front the way I was feeling. By the time we got to the third climb at Stillwater hill, I was feeling okay, and I spun up it in my lowest gear (yes, buying the triple chainring was a good choice, even though it's not quite as manly) with one of my friends. We worked our way past a detour, and then flew back downhill on the descent down Cherry Valley Road. The 19th century pavement combined with the high redneck quotient make this an exciting section, especially when there are a hundred riders on it and you're trying to pass them, but it was better than last year, and we made it to the next water stop.
At that point, I decided I might just live, so I at half a Clif bar and mixed another bottle of Acclerade. We headed north on High Bridge Road, which is when things started to deteriorate a bit.
There's an interesting feature of group rides. If you've watched racing on TV, you'll know that the big breaks happen on the climbs, so you might expect that the climbs would break apart the groups, but nearly all groups have a "regroup at the top" policy where you wait until the group gets together. If you don't do this, you end up without a group, as a good hill spread out the group pretty well.
It's rolling hills that break up a group, mostly because of the way that pacelines work. The lead rider is trying to maintain a steady pace, warn the group of hazards/turns/stops, and not puke his lungs out. The second rider has an easy job - he drafts closely behind the first rider usually at around half a wheel diameter. Because the lead rider's speed isn't constant, he needs to adjust his speed up and down, but that's pretty easy to do - you pedal a bit harder, or soft pedal. It's a cushy place to be, except that you know that in a short period of time - somewhere between 2-10 minutes - the lead rider will peel off, and you'll put in your time.
The third rider has a harder job, as he keys off of the second rider, so instead of the small speed variations of the leader, he has the larger variations of the second rider to work with.
And so on, back through the paceline. As you get farther back, you have to make harder efforts to stay on the wheel of the rider in front of you, and you also have to be more careful not to hit the person in front of you. Ideally, you never use brakes in a paceline, but realistically, if pulling a bit to the side to slow you down (from the wind) isn't enough, you sometimes have to feather your brakes.
Obviously, the longer the paceline, the harder it is to stay one, and we had 12 people at that point. If there's a short climb, and your leader doesn't drop the pace a little at the top, you'll break off 3 or 4 people on the back. They then need to regroup and try to get back to the lead group, but 1) it's 4 people vs 8 people at that point and 2) a couple of those people likely just finished their turn at the front.
That happened twice on the hilly part to Snohomish, as there were a few people pushing the pace (ie 23-24 mph). After the second break, our group of 3 or 4 decided not to bother chasing, and took a slightly more sedate pace into Snohomish. I pulled a section at about 20-21MPH, though it was near the airport and my wireless computer couldn't decide whether my speed was 20, 45, or 67. We picked up a couple more people in Snohomish, and went about 20-22 into Monroe, which is a pretty good speed as it's very flat.
This put us just a hair over halfway through the ride, and with the exception of the ominous "it's going to rain really hard very soon" raindrops, we were doing fairly well. We took a 15 minute break, I made my last bottle of Accelerade, and we headed out. The first part of this section is flat, and we cruised at around 21MPH. Steven (one of the organizers of the group) took a turn, I took a second turn on the flat part, and then as I pulled off the front as we came to a short hill, one of the fast guys came to the front, sped things up, and the group rode both Steven and I off the back, leaving us to ride by ourselves to the next rest stop.
We were not amused.
It's not that we were ridden off the back of the group. I don't begrudge the fast guys their speed, and I know what it's like to be with a group that's riding slower than you want to. It happens to me all the time... Well, occaisionally... Okay, I read about it in a book.
So guys pulling fast at the front is not a problem. What is a problem is that there were a few people who were curiously absent from the front of the group for the whole ride. Because of the distances and times between stops, if you grab the 7th or 8th position consistently and put your effort in on hills to maintain that position, you can hang back and not do any of the hard work.
This behavior may be acceptable, depending on the group. If you have one or two riders who aren't up to speed that day but you want to keep them in the group, the rest of the riders may not mind carrying them along. I've certainly done that on some of our Wednesday rides.
The underlying problem was the size of the group. If we could split our group in half, the fast guys could ride at a speed they were comfortable with, and we could ride a bit slower. Steven and I decided that it made sense to split the group, and we told people that we thought it was a good idea to break into smaller groups, and that the two of us were going to ride a bit slower.
We'd hoped that a few others would join us, but nobody did, so we headed off towards Fall City at around 19MPH, a bit faster when Steven was on the front, a bit slower when I was there. Before the final hill in Fall City, we met up with three more guys who'd decided the fast group was a bit too fast for their liking (without Steven and I keeping the speed down at the front, they'd picked up their pace), and we headed up the hill, hit the last rest stop, and ended up with 4 of us for the spin back into Redmond along East Lake Sammamish.
A great ride overall. Given that my goal was to finish in around 6 hours and I felt so bad at the beginning, a great day.
Distance: 100 milesTime: 5:34Average Speed: 18 MPHElevation Gain: 5375 feet
The elevation gain at Flying Wheels is usually given as 3200' of vertical. One of our group had a GPS with him, and he came up with 5400' of vertical. I did the route in Topo USA, and came up with 5375' for the course.
My guess is that this is the difference between measuring elevation gain with a barometric altimeter and a GPS or topo mapping program. My guess is that the barometric sensor is doing a lot more data smoothing, and is missing a lot of the little ups and downs.
1.5 Clif bars56 oz Accelerade1 bagel1 newton33 pretzels70(ish) oz water
The switch to Accelerade has been a huge success. It really doesn't have that many calories - only about 10 per ounce - but they are very easily accessible. The Accelerade gave me enough glucose to keep going, and the rest of the energy came from my fat stores.
Being a little behind in my blogs, I just today read that Sara Williams has left Microsoft.
You may not have heard Sara's name before, but you certainly know about the projects she's worked on. Sara had the ability to go against the current and do things that changed Microsoft for the better. Things like GotDotNet, developer centers on MSDN, the developer feedback center on MSDN - Sara was involved in all of these things, and in many cases, she was *the* driver behind them.
In addition, she was a genuinely nice person.
She will be sorely missed.
Pocket Lint has a short article on office pranks, with a few examples.
Such pranks have been a tradition at MS as long as I've been here. One guy on my corridor has a pink office as a result of such attention. Over the years, I've seen people's rooms turned into group lounges, their offices redecorated in a Crocodile Hunter Motif (sorry Joe), including a large talking Steve Irwin, and another office turned into a beach, complete with sand, fake palm tree, lights, and a pool with two fish, one functional, one... well, "less than functional" is the nice description.
Offices turned upside down or on their sides. Computers replaced with Fisher-price models. Pictures replaced. Lots of options there.
My personal favorite is one that looks really bad but isn't. Take a room, and put paper across the window. Fill the space between the wall and the window glass with popcorn. Do the same with the relight (that little window next to the door). Then, build a little cylindrical popcorn holder that hooks to the door, so that popcorn comes out when you open the door. Put something behind the door so it's hard to open. Fill the popcorn holder through the drop ceiling.
Looks like the whole room is full of popcorn.
Microsoft's Hejlsberg touts .Net, C-Omega technologies
A tale of a dangerous hacker, attacking in real time over IRC.
Note the IP address that the victim gives to the hacker.
Every once in a while, I switch my music player app from "mix em up" mode to "album mode", so that it plays albums all the way through. This morning was one of those onces.
(Note to the younger folks: you may have heard of something called a "record". It's from the olden days, back when music either came over the radio (in FM, if you were lucky) or in analog format on an easily-damaged large vinyl disc. A record that had more than one song per side was known as a "record album", or simply an "album", as in "hey, can I borrow your new Loverboy album for Friday night? I can? Sweet....")
The move towards CDs has already gotten rid of the concept of sides, where half of the album hung together thematically, and then the B side of the album had other stuff (often good, but usually more variable than the A side).
Now, the world of downloadable music may lead to, if not the death, the severe injury of songs that are meant to be listened to in a series. And that's a shame. So, as a sort of pre-wake, I thought I'd list a few of my favorites.
The obvious ones are concept albums. Good ones that I own:
You can also argue that American Idiot (Green Day) is also a concept album.
Then there are songs that just beg to be listened to at once. One could argue that the reason I want to listen to them in this order is that I have heard them that way so many times, but I think there's more to that. You may choose to differ, if you don't mind being wrong.
What did I miss? What are other great songs that you have to listen to in order?
I've been working on a project that could benefit from an online mapping component, so I've been playing around with Google Maps. I'm not quite ready to unveil the project yet, but I do want to talk about what it takes to do the mapping portion - especially since the information out there is a bit scattered.
Basically, the Google Maps technology allows you to overlay your own information on top of a map. If you haven't seen it before, take a look at the link above, read the article in Wired, or take a look at a site like CheapGas. The things that you can do with this are pretty cool - you can also do the overlays on satellite maps, and generate routes as well.
I'd like to note up front that this is currently not officially supported by Google. Though I have heard discussions with Google employees who say that they're researching whether they can do a real API for this, they haven't yet, and they could change the details and/or discontinue the service at any time. So, with that out of the way, here's how it works...
There's a little component that runs in the browser and handles rendering the map. You give it a location to render in, and then an XML file that describes the information you want to overlay, the part of the map you want to show, etc. When you click on one of the points, the component locations the bit of XML that describes that point, extracts the "<info>" section, passes that off to an xsl for formatting, and then shows the result in a nice pop-up bubble. Pretty cool, and simple, to boot.
It did, however, take fair amount of time to get running. I relied heavily on the examples at Unofficial Google Maps Embedding How To, and I suggest you get them working on your server and then start modifying them. Trying to do both at the same time can only lead to heartbreak.
Now that I have the simple map working, I'm going to be modifying the info popup and looking at the advanced map (with sidebar).
Caveats/Warnings/Stupid things I did:
For the first time in about 4 years, there's a TechEd going on, and I'm not there to speak, answer questions and interact (aka play Halo) with customers.
So, I guess that puts me in the same boat as many of the rest of you. This year, you can see a whole bunch of videos that are created at the show. The behind-the-scenes view of the Balmer keynote is very interesting...
Oh, and I would be remiss if I didn't mention that many of them are edited with Windows Movie Maker...
Last weekend, my offer to pay for lunch with my VISA card was declined. A call on Monday to VISA sent me to my bank, who told me that it had been reported as lost or stolen.
To which I replied "Huh?"
There are two physical cards and both my wife and I have them in our possession. But there's no telling VISA that, so they cancelled the account, and I'll get a new card that I'll have to set up for Netflix, Xbox live, etc. Plus a new number to memorize.
Anybody have this happen to them? The conspiracy theory says that my card showed up in one in an "accidental information disclosure", and that's why VISA cancelled it...
Last summer, I got invited by one of the C# PMs to go to a "Quiz Night" at an English pub in the Wallingford area of Seattle. I thought I would do okay, since I know a fair amount of trivia.
I did poorly.
Today, I came across PodQuiz, a quiz podcast, and tried a few of their quizes.
I've done pretty poorly on that as well, though I will note that the quiz comes from the UK, and therefore has some things that are a bit obscure to most Americans. I didn't, for example, do very well on the "name the country of the person speaking".
Gregg writes about his response to a recent Joel article.
I had the precise same response, based on some conversations I had with Jay a while back. To sum it up, the utility of creating a small class to encapsulate a specific "kind" of thing (as Joel describes it) is vastly underestimated.
In my current code, I have a need to deal with time durations (and remember that I'm in C++...), so I wrote a little class named CDuration, and then pass durations around. It's really convenient.
Erich Gamma on Flexibility and Reuse
I really like what Erich says here - I feel strongly that speculative development is the root of many evils, whether it be speculative frameworks, or speculative optimization.