Boot-Repair tool for Ubuntu

I installed 32-bit Gentoo Linux on my computer in 2002, and kept running that same OS install without reinstalling (but with nightly updates) for over a decade. (It's morally the same computer even though I've incrementally upgraded every piece of it except the keyboard and floppy drive. Kind of like George Washington's axe.)

But I finally ran into a problem with KDE that I didn't have the patience to solve, and decided it was time for a reinstall anyway so I could use a 64-bit OS and run processes larger than 4 GB. I went with Kubuntu 12.04 rather than Gentoo this time, to avoid having to recompile the world.

Kubuntu installed fine and worked fine for a few weeks, then I needed to reboot to apply a kernel update. And when I rebooted, it didn't come back up.

So I booted from the install CD into rescue mode, and Googled for "ubuntu fix boot" or somesuch. Ran into the page for the Boot-Repair utility. It's not in base Ubuntu yet, so I had to install it from a ppa. Then I ran it, and it fixed my boot problem, and I rebooted and all was well.

Normally this kind of problem takes about half an hour of web searching and/or reading man pages then a magic incantation using fdisk. Having a mostly idiot-proof program do it for me was pretty nice. Recommended.

Linux

Comments (0)

Permalink

DC Randonneurs Wilderness Campaign 200 km brevet

The 200 km Wilderness Campaign route through some Virginia Civil War battlefields (Wilderness, Spotsylvania, Chancellorsville) had been a popular permanent, but this was the first time it was run as a brevet. 30+ riders showed up, not bad for March. The weather was forecast to be unseasonably nice, which didn't hurt.

I hadn't done a long ride since early December, and I'd been traveling in California last week without a bike, so I didn't even have my usual 125 miles of weekly commuting to build on. So I was a bit worried that I'd show up but my legs wouldn't. Luckily it was only 200 km, so I figured I'd be okay as long as I didn't do anything completely stupid.

The start was at a Caribou Coffee in Bristow VA, a few miles southwest of Manassas. When I was a kid, Bristow was all farms. Now it's an exurb, and there's been so much new construction lately that my older GPS didn't know half the roads and kept getting confused and thinking I was off-roading. I hadn't actually printed out directions or anything, relying on the GPS, so I was a bit worried about missing the start, but I eventually found some roads that were older than my GPS and made it to the start with about 15 minutes to spare. I was pre-registered, so I was ready to go in plenty of time.

It was about 45 F at the start, cold enough that I had tights and a balaclava and a long-sleeve jersey, over the summer clothes I'd need later in the day. (There were a few he-men who wore shorts from the start, but I would rather carry a bag to stuff my tights in than have a lighter bike but frozen knees.) I started off near the front, behind the usual leaders Greg and Andrea. The lack of hills near the start, plus the slower than usual pace of about 18 mph, meant that almost the whole pack stayed together for the first 20 miles. A few cars had a very hard time passing the gigantic group (partly due to people not getting single-file quickly enough, but mostly due to the sheer length of the line combined with twisty roads), and one of them buzzed us unsafely close when he finally got by, so I decided to play safety cop and try to split things up.

I went off the front hard, not actually thinking I could actually stay there for long (not with Greg and Andrea and Chip chasing), but to try to drop the slower half of the pack off the back. I only managed to break away for a little while before Chip caught me, but then we hammered up there together for a couple of miles, until I looked back and there were only about a dozen riders left. Mission accomplished. At that point I was hot and worried my legs wouldn't last much longer, so I dropped back to the newly formed second group to chat. But with the morning rapidly warming, the brief exertion had me sweating hard, and the first control wasn't for over 20 more miles, so I decided to stop and strip.

After taking off the balaclava and heavy jersey, putting my ugly fluorescent green reflective vest back on in honor of St. Patrick's Day, and unwrapping a Clif Bar, I resumed riding, alone and at a much saner pace. I didn't see anyone from the two groups ahead until the first control in Locust Grove at mile 48. I did, however, encounter an old lady in a Suburban, who rolled down her window at a traffic light to tell me that it really wasn't safe to be riding a bike on these roads and that I'd probably be killed. (This was on a road that was fairly low-traffic that was actually signed as a designated bike route.) Sigh.

At the first control I got my card signed, bought a bottle of Gatorade to refill the one I'd finished (the other bottle was still full), ate a vanilla Gu packet, and got right back on the bike, "passing" a bunch of riders who were taking an extended break. (It takes hard work and athletic ability to ride hard, but anyone can go through a control fast, even me.) I rode alone down busy Route 20 (which annoyingly alternated between a decent half-shoulder, an insufficient quarter-shoulder, and no shoulder at all) until the entrance to Spotsylvania Battlefield.

Spotsylvania Battlefield is a very nice place to ride. The roads had a bunch of pedestrians but very few cars. (Unlike, say, Gettysburg, which is swarmed with cars, most of whose drivers are paying more attention to the memorials than the road.) The signage isn't so great, though, so it's a challenge to stay on course. And some of the roads are one-way, so if you do go off course it's a problem. I somehow managed not to make any wrong turns, and came out of the battlefield onto busy VA 208, then made it across two lanes of fast traffic to the left turn lane leading into Spotsylvania at mile 68, a bit more than halfway through the ride.

Spotsylvania was an open control, meaning we could eat wherever we wanted, but I didn't know the town so I just stopped at the 7-11. The cue sheet said "no services for 37 miles" so I bought two big bottles of Gatorade, filled both my bottles to the brim, and forced myself to drink all the rest. I also bought an Italian sub, which was pretty good by 7-11 standards. Once again I "passed" several riders who were resting at the control, as part of my goal to make up for slow riding with fast stops. (It doesn't really matter for a 200, but I'm planning ahead for the 600, where every minute I waste during the day is a minute I don't get to sleep that night.) By then it was downright warm, so I took off my tights and wool socks and vest and was down to just summer bike clothes. (At that point I also should have put on sunblock, but I didn't think of it, since my brain was still in winter mode.)

After leaving Spotsylvania I rode another 10 miles to Chancellorsville Battlefield, paying close attention to my liquid consumption to avoid running dry before the 37 miles were up. Over-drinking at the 7-11 seemed to help, as I wasn't thirsty yet even thought it was getting warm, but I did have to stop to water some trees. There was a nice long stretch on Elys Ford Road, then some less nice bumpy descents, and then I passed the Inn at Kelly's Ford (which is technically services within 37 miles, but since it's a fairly spiffy restaurant it's maybe not appropriate to just run in to grab water), and finally missed the right turn onto 620 despite the cue sheet marking it as easy to miss. Fortunately I realized I'd missed it after only about a tenth of a mile, no big deal.

By mile 100 my arms (not my legs!) were aching. I was switching hand positions constantly but it didn't help much. I'm starting to understand the appeal of R-12 — by forcing yourself to ride a 200 every month, you never need to do a get-back-in-shape 200 where something invariably hurts. I still had half a bottle left, so I was able to skip the first couple of stores and make it to the mile 112 control in Bristerburg. Three riders caught me within sight of the control, and I rode in right behind them. With only 17 miles left, I bought two small bottles of Gatorade to refill my bottles, figuring I probably wouldn't finish them but better safe than sorry. Then I left quickly, with the goal of not being caught again until the end.

The last 17 miles hurt. I was having a hard time maintaining even 16 mph, despite the lack of significant hills or wind. Another cyclist (unaffiliated with our group) and I approached the red light at Route 28 and Fitzwater Road from opposite sides, and signed our displeasure that neither of our bikes set off its sensors. It would have been legal for either of us to treat the defective signal as a stop sign and proceed, but visibility isn't great there and traffic on 28 is sometimes very fast, so we waited for a couple of minutes until a car came up behind me and tripped the sensor. I was sure the three riders who I'd left at the last control would catch me at the light, but they didn't, and I rode the last 5 miles with horse-approaching barn speed (okay, very-tired-old-nag-approaching-barn speed) in an attempt to finish in less than 9 hours and not get caught again. I finished in 8:57, pretty slow for this very easy 200, but good enough.

Lessons learned? Do more long rides in the winter, to keep from losing my endurance before spring brevet season. Break up and/or get out of 20+ rider packs in populated areas earlier, for everyone's safety. Buy some 32-ounce water bottles and bring them the next time there are 37 miles between services. (I have a Camelbak, but I hate riding with one on my back, and it was March so I didn't think I'd need it.) Always bring sunscreen, even in March. (I'm a bit pink today.)

Bicycles

Comments (1)

Permalink

PyCon 2012

I'm back from PyCon in Silicon Valley. (If you don't know what PyCon is, it's 2000+ nerds talking about the Python programming language for a few days.) Here are some highlights I remember, in case you're looking for recommendations of videos to watch. (Of course, it's fantastic that they record everything and make it all available for free, here )

The introduction featuring dancing robots was impressive. I remember that just a few years ago it was hard to teach robots to walk, and now you (or your rich friend) can buy a robot that can be programmed to dance (among many other things) for a few thousand bucks. They ended up giving away one of the robots at the end, a pretty nice prize.

Paul Graham's keynote about ten really-hard-but-not-quite-impossible startup ideas was awesome, probably the best thing I saw at the conference.

Stormy Peters' keynote about freedom and privacy and stuff was okay; I agreed with her about pretty much everything, but I don't know if someone who didn't would actually have been swayed.

Guido van Rossum's keynote about "trolls" who whine about Python didn't do much for me.

Katie Cunningham's intro to hosting a web site in the cloud and using Fabric to maintain it was very good. I've never used Fabric but I plan to start.

Raymond Hettinger's talk about subclassing was predictably excellent. It was a very balanced talk about when it makes sense to subclass (because it lets you write less code) and when it doesn't, not the typical object oriented programming 101 nonsense where they explain how to subclass but not why it's not always the right thing to do. But since I pretty much already agreed with everything he said, I don't think I got anything out of it.

Larry Hastings' low-level stepping through Python was fun for a very select audience. Most people probably don't need that level of detail.

Paul McMillan's talk about security was very good, and useful for any web programmer who doesn't know this stuff.

Chris McDonough's talk about PDB (the Python debugger) was pretty good. I picked up a few tricks I didn't know, even though I've used PDB a bunch of times.

Moshe Zadka's talk about writing resilient programs that recover from crashes was great. He mentioned several techniques I hadn't even thought of, let alone used.

Geremy Condra's talk about security testing was good, but not quite as mind-blowing for me as his previous talk about timing attacks.

Glyph Lefkowitz's talk about low-level networking (and not Twisted) was great, though I already knew pretty much everything he covered so I probably should have been elsewhere.

The PyPy survey talk by Maciej Fijalkowski, Alex Gaynor, and Armin Rigo was actually more like two talks. Maciej and Alex gave kind of a general introduction to PyPy, then Armin talked about software transactional memory, making an analogy to garbage collection. I already follow PyPy so I didn't get too much out of this talk, but it's worth watching if you don't.

Benjamin Peterson's talk about the PyPy just-in-time compiler was more in-depth and thus more interesting to me. I'd heard most of the material before but it's complicated enough that I needed to hear it again.

Michael Bayer's talk about SQLAlchemy was okay. It was more advocacy of the right way to do a flexible database toolkit (make it flexible) than practical advice on how to use SQLAlchemy.

Both Geographic Information System talks I attended were excellent. Jason Scheirer talked about GIS and maps at a more theoretical level, covering the basic terminology and map projections. Zain Memon's talk was more practical, basically how to use a bunch of libraries to quickly create a map-oriented web site. I need to do some GIS stuff at work, so these two talks definitely justified the money my employer spent to send me to the conference.

Jacqueline Kazil and Dana Bauer's talk about mining public data released by local governments was really good. I wasn't at all familiar with most of the tools they used, so I'll need to watch the video and take notes.

Chris Lambacher's talk about cross-compiling Python and C extensions for embedded systems covered something else I need to do at work, so I was really hoping it would solve all my problems. Unfortunately, his slides showed a big mess of low-level hacks around tools that aren't really designed for cross-compiling, rather than the magic bullet I wanted (but didn't expect to find.) It's a hard problem, but maybe the emergence of ARM devices will make cross-compiling more mainstream and the tools will improve.

Erik Rose's talk about parsing MediaWiki files (which are too complicated to parse with simple regular expressions) gave us an entertaining survey of Python parsing libraries. He covered a handful in some detail, and has a survey of lots and lots more on his web site.

Ryan Kelly's talk about frozen standalone programs didn't really go much into running programs like py2exe, but rather dealt with secondary issues like auto-updaters, binary compatibility with old operating system versions, and code signing. It was interesting, but didn't solve my short-term need to make PyInstaller and PyGTK cooperate on 64-bit MacOS.

Brandon Rhodes' talk about linkers and virtual memory was really excellent, but unfortunately covered things I'd already learned, so I should have been somewhere else.

The lightning talks were a mixed bag. I enjoyed many of them, but certainly don't remember enough to review them all. I'd kind of like to attend a conference that was nothing but lightning talks, five minutes each on hundreds of subjects.

The poster session was good. There were about 30 posters, with their authors handy to talk, and about half of them covered subjects that interested me at least a bit.

The Expo Hall showed that the tech economy is doing fine, even if the larger economy is still kind of bleak. There were dozens of sponsors with booths, and at least half of them were desperately trying to hire people. If you're an out-of-work Python programmer, definitely go to PyCon.

Finally, I spent a day and a half at the sprints, hacking on PyPy. I fixed 3 or 4 minor bugs and learned a bit in the process. I would love to have spent another couple of days at the sprint, but work and family called. (I had actually planned to spend a couple of days playing tourist rather than coding, but changed my mind. So I'll have to go back and look at redwoods some other time.)

In some ways, this was the best PyCon I'd attended since the very first one in DC. The WiFi worked really well for me for a change, even though I only brought a cheap netbook. I managed to avoid attending any really bad talks. I got to write some useful code and talk to a lot of people and even play in a free poker tournament. And I caught not one but two door prize frisbees. (Unfortunately, I only won a couple of books, not a robot or an iPad, but maybe next year.)

Programming
Python

Comments (0)

Permalink

PyPy 1.8 speed

I reran my Project Euler benchmark with PyPy 1.8, PyPy 1.7, Psyco 1.6, and CPython 2.7.2. (On Gentoo Linux x86.)

Total runtime for 127 small programs was 184.18s for PyPy 1.8, 185.55s for PyPy 1.7, 343.51s for Psyco, and 533.09s for CPython.

Or in relative terms, PyPy 1.8 was less than 1% faster than 1.7. Both versions of PyPy were almost twice as fast as Psyco, and almost three times as fast as CPython.

Full results follow:

script PyPy 1.7 PyPy 1.8 Psyco 1.6 CPython 2.7.2
euler1.py 0.34 0.31 0.23 0.10
euler2.py 0.10 0.10 0.10 0.10
euler3.py 0.21 0.21 0.41 0.41
euler4.py 0.20 0.21 0.21 0.20
euler5.py 0.10 0.10 0.10 0.10
euler6.py 0.10 0.10 0.10 0.10
euler7.py 0.10 0.21 0.10 0.31
euler8.py 0.10 0.10 0.11 0.11
euler9.py 0.10 0.10 0.10 0.20
euler10.py 1.43 1.21 1.72 7.09
euler11.py 0.10 0.10 0.10 0.10
euler13.py 0.10 0.10 0.10 0.10
euler14.py 3.44 3.64 1.42 3.03
euler15.py 0.10 0.10 0.10 0.11
euler16.py 0.10 0.10 0.10 0.10
euler18.py 0.20 0.20 0.10 0.10
euler19.py 0.10 0.10 0.10 0.10
euler20.py 0.10 0.10 0.10 0.10
euler21.py 0.10 0.10 0.10 0.20
euler22.py 0.10 0.10 0.10 0.10
euler23.py 2.93 3.03 4.85 12.33
euler24.py 2.12 2.73 7.48 5.36
euler25.py 0.51 0.51 0.91 0.20
euler26.py 6.27 7.07 9.50 4.25
euler27.py 0.91 0.91 1.21 8.99
euler28.py 0.10 0.10 0.10 0.10
euler29.py 0.10 0.10 0.10 0.10
euler30.py 0.61 0.51 4.75 3.23
euler32.py 2.12 1.62 4.85 4.04
euler33.py 0.10 0.10 0.10 0.10
euler34.py 2.43 2.53 11.12 14.15
euler35.py 3.84 4.04 6.37 26.71
euler36.py 1.93 2.14 2.95 2.63
euler37.py 4.39 4.08 14.90 15.31
euler38.py 0.72 0.61 1.33 1.63
euler39.py 0.31 0.31 0.21 0.41
euler40.py 0.61 0.41 0.41 0.61
euler41.py 2.55 3.77 5.00 4.48
euler42.py 0.10 0.10 0.10 0.10
euler43.py 10.00 10.82 38.13 36.13
euler44.py 0.61 0.51 0.82 3.37
euler45.py 4.80 3.98 2.86 2.35
euler46.py 0.21 0.31 0.31 1.12
euler47.py 0.61 0.61 0.61 3.45
euler48.py 0.21 0.20 0.10 0.10
euler49.py 0.31 0.31 0.41 0.71
euler51.py 6.78 7.08 42.35 33.36
euler52.py 0.41 0.31 0.91 1.01
euler53.py 0.20 0.31 0.20 0.31
euler54.py 0.31 0.41 0.31 0.20
euler55.py 0.81 0.71 0.41 0.41
euler56.py 0.41 0.41 0.91 0.81
euler57.py 0.41 0.41 0.41 0.81
euler59.py 6.06 2.93 16.37 15.66
euler61.py 0.30 0.20 0.10 0.22
euler62.py 0.20 0.31 0.20 0.30
euler63.py 0.20 0.31 0.20 0.10
euler65.py 0.10 0.10 0.11 0.10
euler66.py 1.42 1.31 8.80 15.67
euler67.py 0.20 0.10 0.10 0.11
euler68.py 0.10 0.10 0.10 0.11
euler69.py 0.20 0.10 0.10 0.20
euler70.py 0.51 0.41 0.91 0.71
euler71.py 0.30 0.20 0.30 1.11
euler72.py 6.07 6.27 7.98 58.81
euler73.py 2.63 2.33 2.73 29.21
euler75.py 6.23 9.58 0.51 2.23
euler77.py 0.51 0.41 0.31 0.41
euler79.py 0.10 0.10 0.10 0.10
euler80.py 0.71 0.71 0.71 0.51
euler81.py 0.41 0.10 0.10 0.10
euler82.py 0.41 0.20 0.31 0.31
euler83.py 0.20 0.20 0.41 0.61
euler84.py 1.42 1.42 4.85 20.72
euler85.py 6.27 1.72 10.21 12.63
euler87.py 1.11 0.61 0.51 0.91
euler89.py 0.10 0.10 0.10 0.10
euler93.py 2.86 2.86 6.12 12.96
euler94.py 30.64 31.95 28.95 23.43
euler97.py 3.13 3.34 3.13 3.94
euler98.py 0.30 0.31 0.51 0.61
euler99.py 0.10 0.10 0.10 0.10
euler100.py 0.10 0.10 0.10 0.10
euler101.py 0.41 0.30 0.10 0.10
euler102.py 0.10 0.10 0.10 0.10
euler103.py 0.10 0.10 0.10 0.10
euler104.py 1.01 0.81 2.12 2.02
euler105.py 1.42 1.32 0.41 0.41
euler106.py 1.32 1.62 0.51 0.41
euler107.py 0.20 0.51 0.20 0.41
euler108.py 3.13 3.34 7.99 11.02
euler109.py 0.41 0.30 0.41 2.02
euler111.py 3.13 3.34 4.95 20.11
euler112.py 2.43 2.93 13.34 15.46
euler114.py 0.20 0.11 0.10 0.10
euler115.py 0.20 0.10 0.20 0.41
euler116.py 0.10 0.11 0.10 0.10
euler117.py 0.10 0.10 0.10 0.10
euler119.py 0.10 0.10 0.10 0.10
euler120.py 0.10 0.10 0.10 0.10
euler121.py 0.10 0.10 0.10 0.21
euler123.py 4.96 5.56 8.40 7.80
euler124.py 0.71 0.71 0.61 2.63
euler125.py 1.32 1.52 1.42 1.32
euler126.py 1.73 1.52 3.94 18.40
euler135.py 3.34 2.93 2.53 3.94
euler142.py 0.22 0.21 0.21 0.34
euler143.py 0.10 0.10 0.10 0.10
euler150.py 0.62 0.51 0.93 0.82
euler162.py 0.10 0.10 0.10 0.10
euler171.py 0.10 0.10 0.10 0.10
euler172.py 0.51 0.41 0.51 0.51
euler173.py 0.61 0.71 0.61 0.91
euler174.py 3.34 3.13 3.23 3.23
euler181.py 0.10 0.10 0.11 0.11
euler188.py 0.72 0.21 0.10 0.21
euler190.py 0.10 0.10 0.10 0.10
euler202.py 0.10 0.10 0.10 0.10
euler205.py 0.61 0.51 1.32 0.71
euler207.py 0.41 0.51 0.20 0.91
euler222.py 0.10 0.10 0.10 0.10
euler230.py 0.10 0.10 0.10 0.11
euler233.py 0.10 0.10 0.10 0.10
euler234.py 3.44 4.04 8.40 9.40
euler235.py 0.20 0.10 0.31 0.30
euler240.py 7.90 7.98 13.14 23.24
euler267.py 0.61 0.51 0.20 0.51
total 185.55 184.18 343.51 533.09
wins 73 75 66 49

Python

Comments (0)

Permalink

DC Randonneurs Woodbine Wallop 200 km brevet

The last couple of 200ks were routine enough that I didn't bother writing ride reports. But I'll summarize before I forget what happened.

North by Northwest was a new brevet based on an existing permanent route, and only featured two hard climbs, a rarity for that area of Maryland and Pennsylvania. We got a pretty small field for such a nice route on a nice day, only about 22 riders. I rode up front with no-cue-sheet Jeff and Dave from SPP until the first big climb when I got dropped, and ended up finishing behind those two and Matt from PA. I rode in alongside Bill at the front of the non-mountain-goat category. I was disappointed, but not surprised, that I couldn't climb with the lighter guys.

And the Flatbread 200 was flat and windy as usual. We had a huge field, over 70 riders. I rode up front with Greg and Andrea and Mark V., and Dave and Bryan from SPP, until the Delaware border, when I realized that 20 mph into a headwind just wasn't something I could sustain all day. Plus I really needed to eat (I never remember to eat while sucking wind that hard) and find a bathroom. (Not nearly enough woods or cornfields in Delaware.) I ended up dropping way back and finishing an hour and a half behind the front group. Also, my brain was kind of fried and I missed a hard-to-miss turn. Luckily Ed and Mary on the tandem were close behind and yelled me back on course, and I followed their wheel for the last few miles. In hindsight, while chasing faster people is good exercise, I should have dropped off after 20 miles rather than 35.

And then I had a fun mechanical on a Crista century a couple of weeks ago. Just Riding Along on a small hill about halfway through the ride in the middle of nowhere, my back tire insta-flatted. I found that the wheel had actually cracked near the valve stem hole, and a sharp piece of the wheel had knifed through the tube. Luckily Chuck was close behind, and helped me fix it with duct tape and a tire boot to stiffen the broken rim, and I inflated it to only 55 psi to minimize stress on the rim and took a 29-mile shortcut and managed to make it back to the start in Warrenton without further problems. Didn't hit a significant bump or use my rear brake for the rest of the ride. I couldn't figure out my new cue sheet holder while stressing about my wheel, so I relied on new guy Mike from Google to lead the way, which he did flawlessly. The rim was a 2-year-old Velocity Aerohead OC with about 12000 miles on it. The consensus was that it was probably corroded from the inside from lots of rain riding. I'll try to replace my rims more often.

So I showed up for the hardest 200k of the year with a new rear wheel that had only done a few commutes. We only got about 15 riders, not too surprising for a very hilly ride on a 30-degree day that was forecast to be windy. At least it was dry so we didn't have to worry about snow or ice. Against my better judgment I started up front with Greg and Andrea and Chip and tall fast David, but I came to my senses and dropped off voluntarily on the second small hill about 8 miles in, rather than trying to stick to their speed until Mar-Lu Ridge at mile 37, when I would have definitely been dropped regardless. And, unlike Flatbread, this ride was hard enough that wasting energy chasing them could have rendered me unable to finish. I got passed by Bryan around mile 12 while I was taking it easy on a small descent with my untested wheel, then didn't see anyone else all day except at controls.

I was wearing a summer jersey and shorts, cotton and heavy wool socks, polypropylene long underwear top and bottom, thermal tights and my warmest winter jersey. Plus my Lake winter boots, a balaclava under my helmet, a reflective vest, and lobster claws. That was warm enough, except on fast descents where the wind went through all those layers. But if I'd had a jacket on top I would have got too sweaty everywhere but the descents, and constantly putting the jacket on and taking it off would have been too annoying, so I think I got it about right. I would have liked a warmer helmet, though, since my Bell has a zillion vents and fits too snugly to put a decent-sized hat underneath, so I ordered a Bern Brentwood winter bike helmet for the next cold ride.

At the first control at mile 26 I saw the 5 riders in front of me, and 2 or 3 of the riders behind me, and drank a chocolate milk. (It was cold enough that I should have had something hot, but I don't like coffee and didn't see any other quick hot options.) The wind was gradually picking up and was cold and right in our face. Mar-Lu Ridge came at mile 37 and it was as hard as usual. At least this time my derailleurs were correctly adjusted, so I had no problem getting into my 34×28 and staying there. The thing about Mar-Lu is that it's pretty steep most of the way up (4 mph for me, faster for the climbers), then gets steeper near the top (3 mph for me). And then there's a little notch and a second summit, though the little second climb is actually quite easy. There's a big descent down the back side, which I took mostly riding the brakes (to minimize the wind chill, and because I didn't fully trust my new wheel, but mostly because I'm a big wuss).

After Mar-Lu the course rolled for a few miles into Burkittsville and then up Gapland. Usually this part is easy, but today there was a huge headwind whipping through the valley so it was slow going. On many rides Gapland would be a feature climb, but after Mar-Lu it doesn't seem that bad, and the hill broke the wind. I stopped at the top to make sure I was going down the correct way (Townsend is the second right, not the first), then went down carefully. I remembered Townsend being bumpier; maybe they repaved it at some point.

The 15 miles from Gapland to Shepherdstown is usually a nice easy bit, but not riding alone with a big headwind. I kept looking down and seeing 12 mph. I had to pedal down hills that looked coastable. I just hoped the wind would be behind us on the way back. Crusing from Sharpsburg toward Shepherdstown I saw the lead foursome coming back the other way, probably 20 minutes ahead of me.

Shepherdstown Sweet Shop is the best control ever, because they have yummy food and clean bathrooms. I overshot it by a few feet, then turned back around and saw Bryan leaving as I arrived. I had some kind of strawberry danish (yummy) and a slice of chocolate torte (delicious) and a bottle of Nantucket Nectars lemonade (sickeningly sweet, like badly mixed Kool-Aid, with no real lemon flavor or tartness.) Mike, the next rider behind me, came in while I was about to leave, with RBA Bill and his camera trailing behind. Bill hadn't caught the lead riders with his camera, so I warned him of how far ahead they were. I refillied my water bottle (singular; I had only drank 28 ounces of Gatorade and a bottle of chocolate milk in 60 miles) and headed back toward Maryland. Well, actually I headed the wrong way, since I'd overshot on the way in reversing my path led to heading the wrong way, but I eventually got pointed the right way.

I made it all the way through Shepherdstown without any near-death experiences with the local bad drivers (college towns have the second-worst drivers in the country, after Florida). After the halfway point the wind was no longer in my face, though it was only a direct tailwind for a few wonderful miles. (We really need to figure out how to rig sails to bicycles so that we can benefit from the wind from more directions.) About ten miles of rollers led to Reno Monument Road and the worst climb of the ride. (Before the ride my opinion was that Mar-Lu was worse, but I'm changing it.) It was about noon and warming up a bit, so I stopped before the climb and took off my balaclava and my long underwear top and my reflective vest, and swapped my lobster claws for lighter gloves. Equipped to climb without roasting but probably to freeze on the descent, I did the first short steep bit and then the downhill, and thought I remembered Reno being longer than that. It is. The next part is brutal, winding up at 3 mph for a long way. Right before the top my heart rate hit about 180 and I decided to stop and catch my breath, the first time I've needed to stop on a climb in a while. I knew I was only about 50 yards from the summit, which made it worse. I stood there for a minute breathing slowly, then I drank half of my second bottle of Gatorade, then I rode up the rest of the hill. Getting started on the steep slope in my hard-to-clip-in winter boots wasn't easy, but once I got going the last bit wasn't hard in my newly rested state. I stopped again at the top to put my balaclava back on and zip up my jersey, and admired the bit of snow on the ground up there, then bombed down the descent for a bit, got scared by a blind curve and hit the brakes way harder than I meant to and almost went over the bars. That was the end of fast descents for the day, except for dead straight ones with the bottom fully visible and no cars in sight.

There was a 50-mile gap between controls so I was a bit tempted to stop in Middletown around mile 75, but I had a full bottle of water and a half bottle of Gatorade and some Gu and Clif Bars, so I kept going. Without the headwind I made a decent pace, around 15 mph, until the next big climb up the shoulder of US 40 and then up Shookstown Road. The cue sheet said the descent after Shookstown was twisty, and after my near-mishap on the previous descent I used a lot of brakes. The ride then wandered through a lot of familiar exurban roads around Frederick. A rider caught me from behind and I said hi, but he turned out to not be from our group, even though he had a bright orange reflective vest in broad daylight that was dorky enough to scream "randonneur." I dropped him on a little climb and then stopped to get some food out of my bag (embarrassingly, I can't open Clif Bar packages with gloves on while riding), and he passed me and then turned the wrong way onto Bloomfield Road. I almost yelled at him to get back on course, when I remembered he wasn't actually riding the brevet. (Good thing I didn't draft him, as it's illegal to draft people who aren't on the ride.)

Many of our rides end in Frederick, so I felt like I was heading for the barn, but there were actually 30 miles left. My new goal was to make it to the finish before dark, but I just didn't have much left after fighting the wind and hills. I went through the 7-11 at mile 111 fast, bought a bottle of Gatorade and a big Snickers, and ate them while some silly teenagers with especially stupid hair whined about not having enough money for all the cigarettes and lottery tickets and candy they wanted. Get off my lawn!

Just to be mean, the finishing stretch went over Buffalo Road. Not as bad as Reno or Mar-Lu, but still a pretty bad climb. I really had to pee and eventually found a stretch of woods out of sight of houses. It was approaching dusk so I put my reflective vest back on and turned on my lights. This made me safe and legal for after-dark riding, but my goal was still to finish before sunset. The sun went down when I was climbing Watersville Road, so I missed it by a few miles. It was too dark to easily see the street sign for Old Frederick Road and I hadn't put on my helmet light, but I eventually spotted the sign and made the last turn. From there it was a quick little ride into Pizza Hut in Woodbine. Volunteers Bill and Mike were there, but the five riders in front of me (four fast finishers and one DNF) were already gone. More pizza for me.

That was probably the hardest 200k I've done. My lungs were okay (except on the top of Reno) but my legs and lower back were beat. We had 2 DNFs out of 15 riders, one at the front (Went too hard and ran out of gas?) and one at the back (knew he couldn't make the time limit and shortcut his way home). Hills and wind and cold are a bad combination. In hindsight I should have slowed down a bit and waited for the next rider to catch me, to have a partner in the wind. But I didn't want to slow down, since I already felt like a slug. Probably exercise-induced testosterone poisoning.

Total climbing: somewhere over 10000 feet, depending on whose GPS you believe. Total food intake: 2 Clif Bars, 2 Gu, 88 ounces of Gatorade, 16 ounces of chocolate milk, 16 ounces of (vile) Nantucket Nectars lemonade, one strawberry danish, one slice chocolate torte, one large Snickers, and 3-4 slices of post-ride pizza. At the airport in Frederick they said the peak winds were 16 mph sustained with gusts to 22, but I think it was worse than that up in the mountains.

Goals for 2012: finish the 600 and get my weight down to 180 so I can go up hills faster. (Some people bike to lose weight; others lose weight to bike.)

Bicycles

Comments (0)

Permalink

git bisect for the impatient

I was testing Slugathon last night and found a bug.  Unfortunately, it was a GUI bug so my unit tests didn't catch it.  Luckily, the bug was easy to reproduce (I could see it in about ten seconds from the start of a new game).  So here's how I used git bisect to find which commit had the bug.  (Note: I had a clean tree with no uncommitted changes at the start of the process.  If I had uncommitted changes I would have used git stash first.)


$ git bisect bad

You need to start by "git bisect start"

Do you want me to do it for you [Y/n]? Y

$ git checkout HEAD~10

$ ./setup.py build; sudo ./setup.py install; ./slugathon server

(Did not see the bug.)

$ git bisect good

Bisecting: 4 revisions left to test after this (roughly 2 steps)
[b1b94b6253ad506cb03199bea6ff52e76ebedfb9] Remove some obsolete TODO comments.

$ ./setup.py build; sudo ./setup.py install; ./slugathon server

(Did not see the bug.)

$ git bisect good

Bisecting: 2 revisions left to test after this (roughly 1 step)
[cb7b8c2553f48a6d2a8c8eca5cb538927720874c] Rename Player.legions to markerid_to_legion

$ ./setup.py build; sudo ./setup.py install; ./slugathon server

(Did not see the bug.)

$ git bisect good

Bisecting: 0 revisions left to test after this (roughly 1 step)
[d0a783c61eba6ba5f70b3021252a46f301293727] Update legion and marker counts after StartMusterPhase.

$ ./setup.py build; sudo ./setup.py install; ./slugathon server

(Did not see the bug.)

$ git bisect good

69efbfd5e19220e46f588944a8692140933cb303 is the first bad commit
commit 69efbfd5e19220e46f588944a8692140933cb303
Author: David Ripton <dripton@ripton.net>
Date:   Mon Dec 5 21:34:36 2011 -0500

Rename Player.markerids to markerids_left for clarity.

$ git bisect reset

And that's all; it found which commit had the bug. I did a git log -p on that commit to see exactly what I'd changed, found a suspicious part of the patch a few minutes later, fixed it, verified the bug was fixed, and committed and pushed the fix. Easy.

Of course you can do this without git bisect; it just saves you the effort of manually doing the binary search through the range of possibly-bad commits.

Programming

Comments (0)

Permalink

DC Randonneurs Cacapon 200km Brevet

This one went perfectly, so it'll be a short and boring ride report. (Except for the bear.)

I packed my stuff the night before, including putting my bike inside my car. (My old car, a BMW M3 sedan without fold-down rear seats, wouldn't hold my bike without totally taking it apart, so I had to use a trunk rack. And the car didn't fit in the garage with the bike on the trunk rack, so I had to wait until the morning of the ride. But my new car, a Honda Fit, can hold my bike without taking any wheels off. Pretty amazing for such a small car.) So all I had to do was wake up at 5 a.m. (yuck), eat some breakfast, and drive to Middletown VA. Got there around 6:30, well ahead of the 7 a.m. start, which gave me time to listen to some stories about Paris-Brest-Paris last month. It was around 50 degrees, but felt chillier than that since it was 90 on Wednesday, and I was decked out in tights and a long-sleeve jersey and wool socks and a bright green reflective vest with the zipper on the wrong side for a right-hander to draw his sword. (Oops, I got a girl's vest. Luckily, anyone that can tell is automatically less manly than me for knowing too much about fashion, so it's okay.)

We only got about 15 riders for this brevet, a pretty small turnout for DC Randonneurs. Probably because most of the people who rode PBP are still resting. As we rolled off, I noticed my speedometer wasn't working, so I had to stop and reseat it in its bracket, which meant I started next to last. (Roger didn't bring lights and waited a few more minutes to make sure the sun was totally up.) Honestly, starting at the back is probably smarter anyway since I've missed the second turn of this route not once but twice in the past. I started off slow, but after a few miles decided everyone around me was just moving too slowly, and started passing people. Pretty soon I was all the way in the front, next to George. We rode together for a while, until he noticed that others were creeping up behind us. I decided I didn't want to be caught, and took off. Most of the fast people didn't ride today, and the fast people that did ride weren't feeling fast today, so nobody caught me before the first control at 17 miles.

At the first control I drank a 20 ounce Cherry Coke, turned off my lights, and took off my long-sleeved jersey. About five riders caught me while I was there, and Kelly realized he forgot his tubes, so I lent him one. While I was doing all that, George out-controlled me and retook the lead. But I took off second and caught him after a few miles. We rode together for a bit, until the first big hill which he climbed at his typical slow-and-steady-good-for-1200-km pace, and I climbed at my stupid going-to-burn-out-before-100-km pace, which meant I was back in the lead. I didn't think it would last long, but I didn't see another rider from our group on the road for the rest of the day.

The second control on the porch of a closed store in Siler was labeled an information control, but when I got there RBA Bill was there to take pictures and hand out food and sign cue sheets. I was happy to still be in front, though the rollers were starting to hurt a bit. I felt like I was descending better than usual, despite a few drops of rain. I'd recently (but not the night before the brevet, for once) adjusted my brakes, which gave me more confidence in my stopping ability and let me go faster without feeling like I was taking excessive risks.

When I got to the mile 61 control at Greg's Restaurant in Capon Bridge, I saw another bike parked out front. Hmm, I was sure I was in front. Then I saw it had a cue sheet for our ride. How did someone pass me? It turned out to be Leslie, who had shortcut the course to turn a 200k into a century. (This is of course cheating if you do it with fraudulent intent, but she told Bill she was doing it because she didn't feel up to 200 km that day, so it was okay.) So I was still in front. I had a chicken salad sandwich and took off toward Wolf Gap.

The 10 miles along Cacapon River road are the prettiest part of this ride, and also (as you can tell from the word "River") the flattest. I saw a few people canoeing on the river, and enjoyed digesting my lunch. The 8 miles along WV 259 were less fun, since they featured hills and traffic, but the traffic was pretty friendly and I got to the 7-11 in Wardensville in a good mood. This 7-11 was not a control (that'll teach 'em to not let us use their bathrooms) but my bottles were dry so I stopped anyway and bought some Gatorade and some kind of air-injected Hershey Bar I hadn't tried before. (Clever marketing — sell less chocolate and more air and call it a feature.) It was okay, nothing special.

I went down Trout Run road toward Wolf Gap, still ahead of the field. When I started climbing I got warm, so I stopped to take off more clothes and pee. Ten miles of (mostly) up and (some) down later, I reached Perry's Zoo. It was open for once, but I didn't need anything so I didn't stop. The climb up Wolf Gap proper is steep, but kind of anticlimactic after the ten-mile buildup. I stopped at the top to put my arm warmers back on, then zoomed down the descent. Well, zoomed by my standards, which is super-slow compared to any real descender, but I'm not that skilled and going too slow is better than crashing and losing teeth.

The descent turned into Animal Planet. First I saw a turkey vulture eating something on the side of the road. It saw me and took off, but went the same direction I was going at about the same speed I was going (maybe 27?), so I got a fantastic up-close look at a big ugly bird in flight for several seconds before it flew above the trees. Then I encountered a couple of pickup trucks going up the hill around blind corners in the middle of the road. Luckily bikes are skinny and I try to go around blind corners as far to the right as possible, so no head-on crashes ensued.

Near the bottom, the first dog of the day came out into the road to play. It wasn't that big, but it was brown and fast and had the angle on me and cut me off like a good defensive back. I was a bit worried that I was going to hit it, but it left me enough room to get by, and I was going downhill, so let go of the brakes and pedalled hard and zipped by. I was still a bit pumped from the dog when I saw something in the road ahead that looked like a *huge* black dog. Wait, that's not a dog, it's a bear! (And while it was huge for a dog, it was actually pretty small for a bear, probably less than a year old.) Luckily the bear was as scared of me as I was of it, and ran off into the woods, so I didn't have to deal with going around it. Finally, at the very bottom of the hill a second dog decided to chase me. It was tan, and a lot bigger than the first one, but also a lot slower, and probably more bark than bite, so I got past it without much trouble. That would be the end of the day's animal excitement, except for a couple of dalmatians on Back Road who chased me from behind their fence (thank you owners who actually keep their dogs in their yards), which hardly counts.

The last control of the day was at Larkins Store near Edinburg, where I bought another bottle of Gatorade and two Reeses King Cups. Apparently regular peanut butter cups are too small for Today's Fatter Americans, so now they make bigger ones, 200 Calories per cup. Yum yum yum. I ate my candy and refilled my bottles and drank the excess Gatorade and used the Porta-Potty and headed for Back Road. This ride features 17.8 miles of Back Road, which feels like forever, and I was sure someone was going to catch me from behind, but they didn't. The last 10 miles from Back Road to Middletown went by very quickly. There was no Civil War re-enactment this time (our ride is now scheduled not to conflict with it, for better hotel rates), so the scenery was less exciting than usual.

I finished first (for the first and probably last time) in a not-very-impressive 9 hours 55 minutes. Kelly got a flat right near the end, so we were both glad I loaned him that tube. Pretty much a perfect day for me — no flats, no wrong turns (!), I remembered to eat and drink enough, and my legs held up.

Bicycles

Comments (0)

Permalink

PyPy is still the fastest Python

PyPy 1.6 was just released, so I ran my Project Euler benchmark script again.

The script runs my pile of Project Euler solver programs across various implementations of Python available on my computer, and gives results only for the ones that finish successfully in less than a minute on all of them.

The contenders this time were PyPy 1.6, CPython 2.7.2, CPython 2.6.7 with Psyco, and Jython 2.5.1+. (Unladen Swallow appears to be dead, and IronPython is surprisingly painful to install on Linux, so I left them out.)

This time, 125 programs qualified, out of 197 working solvers. (Some programs require the gmpy library, which doesn't currently work on PyPy or Jython. And some use Python 2.7 syntax, which won't work with Psyco or Jython. And some are just too slow.)

Once again, PyPy is fastest, followed by Psyco, then CPython, then Jython. PyPy and Psyco are roughly twice as fast as CPython, and Jython is roughly twice as slow as CPython. (Though a lot of that is startup overhead; Jython gets more competitive for longer-lived programs.)

script pypy 1.6 jython 2.5 psyco 2.6 CPython 2.7
euler1.py 0.10 2.76 0.10 0.03
euler2.py 0.10 2.73 0.10 0.10
euler3.py 0.21 4.17 0.41 0.41
euler4.py 0.32 4.67 0.42 0.31
euler5.py 0.11 3.65 0.11 0.11
euler6.py 0.11 3.25 0.12 0.11
euler7.py 0.32 4.98 0.31 0.62
euler8.py 0.10 3.44 0.10 0.10
euler9.py 0.11 4.06 0.11 0.20
euler10.py 1.43 9.42 2.04 8.61
euler11.py 0.11 2.75 0.10 0.11
euler13.py 0.10 1.42 0.10 0.10
euler14.py 4.86 7.99 1.42 2.93
euler15.py 0.11 2.73 0.10 0.12
euler16.py 0.10 1.62 0.10 0.11
euler18.py 0.20 3.13 0.10 0.10
euler19.py 0.10 3.04 0.10 0.10
euler20.py 0.11 2.74 0.11 0.11
euler21.py 0.21 4.47 0.10 0.31
euler22.py 0.12 3.97 0.11 0.12
euler23.py 3.45 18.13 7.01 15.39
euler24.py 3.54 32.17 7.91 5.47
euler25.py 0.62 4.60 1.11 0.20
euler26.py 6.39 18.62 11.25 5.19
euler27.py 1.12 10.42 1.32 9.93
euler28.py 0.10 2.74 0.12 0.12
euler29.py 0.11 3.85 0.11 0.11
euler30.py 3.15 9.51 5.17 4.15
euler32.py 2.23 6.37 5.17 4.16
euler33.py 0.10 3.45 0.11 0.10
euler34.py 4.56 12.45 12.09 15.48
euler35.py 4.95 30.77 7.38 28.47
euler36.py 1.93 5.89 3.04 3.24
euler37.py 9.62 34.24 14.57 16.42
euler38.py 1.32 6.98 1.83 1.83
euler39.py 0.30 3.86 0.10 0.31
euler40.py 1.12 6.40 0.83 0.72
euler41.py 4.68 18.73 5.42 4.97
euler42.py 0.22 3.86 0.10 0.10
euler44.py 0.61 5.77 0.71 3.25
euler45.py 5.59 10.45 2.96 2.34
euler46.py 0.20 5.56 0.22 1.73
euler47.py 0.71 8.32 0.72 4.86
euler48.py 0.10 4.65 0.11 0.10
euler49.py 0.41 6.11 0.62 0.61
euler52.py 0.41 5.08 0.81 0.81
euler53.py 0.32 4.27 0.21 0.20
euler54.py 0.43 5.06 0.22 0.42
euler55.py 0.61 5.17 0.41 0.41
euler56.py 1.14 5.98 1.63 0.92
euler57.py 0.41 5.68 0.53 0.72
euler59.py 13.76 15.08 14.57 13.56
euler61.py 0.31 4.27 0.20 0.11
euler62.py 0.20 3.84 0.31 0.20
euler63.py 0.20 3.34 0.20 0.10
euler65.py 0.11 3.06 0.11 0.12
euler66.py 1.31 20.25 8.00 13.35
euler67.py 0.42 3.36 0.11 0.11
euler68.py 0.10 2.54 0.10 0.10
euler69.py 0.10 3.55 0.10 0.10
euler70.py 0.41 7.00 0.81 0.72
euler71.py 0.22 5.18 0.31 1.01
euler72.py 6.48 38.36 6.38 54.47
euler73.py 2.95 21.28 2.95 27.14
euler75.py 11.95 6.47 0.71 2.33
euler77.py 0.51 6.48 0.21 0.41
euler79.py 0.10 1.72 0.10 0.10
euler80.py 0.61 2.43 0.72 0.61
euler81.py 0.30 2.02 0.10 0.10
euler82.py 0.51 7.28 0.30 0.30
euler83.py 0.21 2.84 0.41 0.61
euler84.py 1.52 19.45 6.58 22.46
euler85.py 9.15 21.56 10.53 12.86
euler87.py 2.24 5.57 1.23 1.12
euler89.py 0.10 2.33 0.10 0.10
euler93.py 2.63 10.96 5.76 11.66
euler94.py 24.61 21.98 27.12 22.97
euler97.py 2.93 9.32 2.73 3.46
euler98.py 0.41 3.65 0.51 0.61
euler99.py 0.12 2.24 0.11 0.10
euler100.py 0.10 1.62 0.10 0.10
euler101.py 0.41 3.04 0.10 0.10
euler102.py 0.10 2.43 0.11 0.11
euler103.py 0.10 1.72 0.10 0.10
euler104.py 1.01 4.17 1.82 1.72
euler105.py 1.74 6.19 0.51 0.41
euler106.py 1.52 7.41 0.51 0.41
euler107.py 0.21 4.88 0.21 0.41
euler108.py 2.83 12.77 8.11 11.66
euler109.py 0.30 9.60 0.41 2.14
euler111.py 4.57 26.96 5.68 25.42
euler112.py 6.38 12.35 13.28 17.82
euler114.py 0.10 3.24 0.10 0.10
euler115.py 0.21 4.76 0.20 0.30
euler116.py 0.10 3.75 0.11 0.10
euler117.py 0.11 3.35 0.12 0.12
euler119.py 0.10 1.72 0.10 0.10
euler120.py 0.10 2.33 0.10 0.10
euler121.py 0.10 3.74 0.10 0.20
euler123.py 4.06 22.27 7.70 7.58
euler124.py 0.72 7.38 0.72 2.84
euler125.py 1.13 4.97 1.64 1.73
euler126.py 1.52 12.44 3.66 16.31
euler135.py 3.86 6.37 2.33 3.65
euler142.py 0.21 4.66 0.10 0.32
euler143.py 0.11 2.54 0.12 0.12
euler150.py 0.52 5.39 1.02 0.91
euler157.py 0.10 1.42 0.10 0.10
euler162.py 0.10 2.43 0.10 0.10
euler171.py 0.10 1.43 0.10 0.10
euler172.py 0.51 2.83 0.51 0.51
euler173.py 0.61 2.93 0.71 0.91
euler174.py 3.65 6.58 3.65 3.34
euler181.py 0.10 2.33 0.10 0.11
euler190.py 0.10 1.62 0.10 0.10
euler202.py 0.12 3.35 0.10 0.10
euler205.py 1.02 8.51 1.12 0.71
euler207.py 0.41 4.36 0.20 0.81
euler222.py 0.10 1.72 0.10 0.10
euler230.py 0.11 3.54 0.11 0.12
euler233.py 0.12 3.15 0.12 0.12
euler234.py 4.56 19.15 7.40 9.96
euler235.py 0.42 4.86 0.62 0.42
euler240.py 10.36 50.91 11.76 22.39
euler267.py 0.51 3.95 0.20 0.41
total 209.07 946.66 267.48 473.62
wins 82 1 57 55

Programming
Python

Comments (0)

Permalink

ROMA Leesburg 400 km brevet ride report

The Leesburg 400 starts 6 miles from my house, which is so convenient I had to ride it.  I actually wanted to ride to the start, but 400 km is a long way and 12 more miles might be the straw that broke the camel's back, plus (more importantly) I would have needed to get up a bit earlier, so I wimped out and drove.  The ride started at 5 a.m., but since it was so close I was able to wake up at 4, eat a bowl of cereal, and still make it to the Comfort Suites by 4:30.  There were 14 riders there, about 5 of whom I recognized.  It was about 50 degrees with a slight breeze at the start, pretty much perfect weather.

Matt sent us off with minimal ceremony at 5 a.m.  The route went down Route 7 Business, Catoctin Circle, and then up Dry Mill Road.  A few hours later these roads would be pretty crowded, but we were pretty much the only people silly enough to be out there that early.  We saw a few deer on Dry Mill, but nobody ran into any this time.  Gravel and potholes were more of a problem, but I didn't see any crashes.  We had some light traffic on Route 9, but had Clarkes Gap Road to Waterford to ourselves.  We zipped through Waterford with the group mostly intact, then through the circle in Lovettsville, and up Berlin Turnpike to the bridge over the Potomac.  Last time I crossed that bridge (the other direction, on last year's DC Randonneurs Frederick 400) it was a minefield construction zone, but this time the bridge was fine.  We zipped up Maryland 17 to Harmony, heading up toward Burkittsville.  By then the front group had dwindled to 8 riders.

Paul and Carol eventually dropped off, and then Alec noticed they were gone and slowed down to wait for them, and I was at the tail end of a group of 4 fast guys.  I stuck with them for a while, but around mile 27 it started warming up, and I wanted to take off some clothes, and I also realized that I hadn't eaten anything.  And of course if I tried sticking with the fast guys to the end I was sure to blow up.  So I stopped on the shoulder for a couple of minutes and let the fast group go, then continued by myself up Spruce Run (not very steep, but very narrow and thus not a great place to be passed by cars) and then Route 77 through Catoctin Mountain Park (the easy way through the park; not too much climbing.)

We came out of Thurmont on Route 15 North.  I will give props to Maryland for having really wide shoulders on some of their highways, but it's still not much fun to ride alongside lots of speeding traffic.  Near the end of the 7 mile stretch on 15, Alec and Carol and Paul caught me, and I fell in behind them as we got off the highway onto 15 business.

Unfortunately, there were Detour - Local Traffic Only signs on 15 Business.  We hadn't heard anything about the detour, so we didn't know if bikes would be able to sneak by.  Until we reached the missing bridge.  Oops, we had to reverse course and take the detour.  We gathered up a couple of other riders and took the detour, hoping it would end up back on 15 Business.  I got a bit too excited on a flat part and ended up dropping Paul and Carol, which was a really bad idea since we were off the cue sheet and Paul knew the area way better than the rest of us.  The detour signs eventually went away and we ended up on Confederate Avenue inside Gettysburg Battlefield Park, having missed our control.  Eventually Alec figured out that we should have turned onto Emmitsburg Road, and we backtracked, and found our control at Gettysburg Battlefield Resort, with 10 bonus miles.

The control didn't have any appealing food, so I just bought some water and ate a Clif Bar and a Gu packet, and took off some more clothes.  I left by myself after about 15 minutes, and started riding back through the battlefield.  I passed another rider, who hadn't found the control yet and was not happy about it, and gave him directions.  I guess April isn't peak tourist season, because thankfully there weren't nearly as many Civil War veterans in gigantic cars trying to run over cyclists as the last few times I rode through Gettysburg.  I rode through Fairfield, Sabillasville, and down the wide shoulder of Raven Rock Road to Smithsburg.  I was kind of annoyed about the ten bonus miles, since that would mean more riding after dark later, but my legs were okay.

Somewhere around Smithsburg I was caught by Alec and Paul and Carol again.  I rode with them through the pretty Mountain Laurel Road section, then over to Antietam Battlefield, which is much less tourist-infested than Gettysburg and thus usually much nicer to ride through.  We had a control at 116 miles at Battlefield Market in Sharpsburg, a really good control with decent food.  I ate some fried chicken and some coconut pie, and then hung around outside resting for a while.  We went across the Potomac into Shepherdstown West Virginia and then almost got run over by a left-turning geezer who never saw four brightly-dressed cyclists in broad daylight.  Have I mentioned that each cyclist should be allowed to yank one motorist's drivers license per year?  Luckily our brakes worked and nobody crashed, and we kept going down WV 480 and WV 9.

This was probably the worst part of the ride, because it's a two-lane road with too much traffic and a narrow pothole-infested shoulder.  Trying to dodge the potholes to your right without getting run over by the pickup tracks passing on your left isn't much fun, but there aren't always better roads available.  After about 10 miles we were far enough from Shepherdstown that traffic dropped off a bit, and then we turned off toward Summit Point and then over the Virginia border toward Winchester.  This is one of the few parts of the Virginia - West Virginia border that's not on top of a mountain, which was nice.  My chain had been squeaking all day (because I got caught in a thunderstorm on my commute home on Wednesday and had forgotten to lube it afterward) and Alec noticed and gave me some chain lube, which helped with both the noise and my shifting.  We skirted the edge of Winchester then took Middle Road and Back Road toward the 171-mile control at Matt's house near Strasburg, where there was some good food waiting.

Unfortunately, the recent rain meant the Stan Miller Memorial Low Water Bridge over the Shenandoah was underwater, so we had to take a detour through Front Royal where there's a higher bridge.  Yay, Saturday night traffic.  The detour wasn't on our cue sheets, but Paul knew the way, so I resolved to stay near him no matter what to avoid getting totally lost.  It cooled off fast when the sun went down, so I put on almost all of my clothes and turned on all my lights and followed the other three riders down VA-55 for what seemed like forever.  Then we had to ride in some traffic in Front Royal, and cross a bunch of lanes to make a left onto what eventually became Happy Creek Road, which featured some construction that made the lane too narrow for a car to safely pass a bike.  Luckily we had a good driver behind us, who patiently followed us through the construction zone, so it wasn't a problem.

We got back on 55 toward Marshall.  Traffic was light but fast, so we had to watch our back, but nobody passed us too closely.  We did have one big dog try to chase us, but we all dodged it.  It took forever, and we were starting to get cold and tired, but we reached the 213-mile control at the Marshall 7-11 around 11:30 p.m.  We bought and ate various imitation food; Coconut M&Ms are pretty yummy.  And we left around midnight to head back to Leesburg.

Marshall to Leesburg is only 38 miles, but it seems a lot longer when you're tired.  We went up Zulla Road toward Middleburg, then up Mountville and Snickersville and Watermill and Lincoln toward Purcellville.  I'd ridden all these roads before, but not in the middle of the night.  The good part was the lack of traffic; the bad part was finding all the potholes in the dark.  But we did our best to point out the road hazards, and nobody crashed.  We had one scary moment when some idiot came tearing down the road at easily double the speed limit, but luckily he was (mostly) on the other side of the road.  We all bailed onto the (nonexistent) shoulder anyway, then resumed riding.  Carol led a sing-along to keep everyone awake, though I didn't help much since I couldn't remember the words to anything.

Lincoln features one of those radar speed detection signs, which meant I had to sprint for it.  And I registered possibly the worst sprint of my life: 16 mph.  Hilarious.  At that point we were on really familiar roads: Route 7 Business through Purcellville and Hamilton, then down Dry Mill into Leesburg.  There's another radar speed sign on Dry Mill, so I gunned it again, and managed 28.  Alec claims the second sign was clearly reading high, while I think the first sign was reading low.  We're probably both right.

We got to the hotel at 3:13 a.m.  Though it took a couple of minutes to wake up our sleeping volunteer so we could officially finish.  I ate a few post-ride cookies and then left, before I had a chance to get too sleepy to drive safely.  My speedometer said I rode 258.8 miles (the course was supposed to be 251.4, so the first detour cost us about 10 miles and the second gave us about 2.5 back).  Average moving speed was 13.7 mph, a decent pace.  We had some hills, and some wind early, but it was calm late.  And I was lucky enough to follow people who knew the way in the dark, to avoid adding more bonus miles.

Other than the two bridge detours, it was a pretty uneventful ride.  I didn't bonk or dehydrate or have any flat tires.  Dropped my chain twice, so I need to do some front derailleur limit screw adjustments.

Thanks to Paul for navigating, Alec for giving me some much needed chain lube, Carol for keeping us all awake, and Matt for running the brevet.

Bicycles

Comments (0)

Permalink

DC Randonneurs Contrary Mother of All 300ks Ride Report

It's called the Mother of All 300ks because it's 300 km long (actually more like 309 km, but who's counting?) and really hilly.  And it's called contrary because we're riding it backwards from the way it was originally ridden.

The start was at 5 a.m., in Middletown Virginia, which is about 70 minutes from my house.  So I had to leave around 3:30, which meant I had to get up by 3, after about 4.5 hours of sleep.

The forecast was for about 40 at the start, over 60 in the afternoon.  So I wore my summer shoes with two pairs of socks, a short-sleeve wool jersey and a thermal jersey, my best cycling shorts with thermal tights, lobster claw gloves, and a warm balaclava.  I had a cycling cap, rain jacket, sunglasses, and lighter gloves in my bag.  The weather forecasters got it wrong; it stayed in the 40s all day, with a bit of rain and a lot of fog.  Should have worn my winter boots, or at least brought shoe covers.  But other than my toes I wasn't too cold; never needed to put on the rain jacket.  Also never needed the sunglasses.

I brought 2 28-ounce bottles of Gatorade, 4 Gu packets, and 4 Clif bars.  I had a bowl of cereal before I left the house, and then a big bagel at the start, so I figured I'd be okay until the sun came up.

Since an awful 8-flat century last year, I always carry 3 tubes and a spare tire on long rides.  A few days before the ride I put a 25 mm Gatorskin tire on the front of my bike, to match the one I put on the back a couple of weeks earlier.  I figured this would decrease my chance of a flat, and make rough roads more comfortable, compared with the 23 mm Krylion Carbon that was there before.  I also adjusted my front derailleur screws to avoid dropping my chain, like I did too many times on my last brevet.

There were about 40 riders at the start.  I managed to stick with the fast group, about 17 riders, for a while.  Probably not a great idea to burn energy riding at 20 mph, but I was fresh and the early hills were just gentle rollers.  One rider in the group hit a deer and was slightly banged up; after that I tried to give myself a bit more space, but stayed close enough that I didn't have to navigate for myself in the dark.  Trusting the herd to navigate was a mistake because we all missed a turn and did a bonus half-mile.  Then we had an information control at mile 17 before crossing a big highway at a traffic light, which bunched everyone together again until the second control in Siler at mile 34.

After that control the route got hillier and the faster riders flew off the front and I ended up riding by myself at a slower speed.  There wasn't a control with food until mile 60, so I ended up eating a Gu and a Clif bar and making myself drink more Gatorade than I really wanted.  And then the mile 60 control didn't have any food that looked good, so I just bought some Gatorade there to refill the bottle I'd drunk, and ate another Gu and another Clif Bar.  I left the control a bit behind three other riders, and immediately missed a turn because I was following them rather than watching the cue sheet.  Eventually they stopped to see if I knew where I was going, and I didn't but was sure we'd gone way more than 0.1 mile, and turned back around to find the turn right after the control.  Another 2 bonus miles.

The Slanesville control was a good one: general store plus convenience store plus restaurant with bathroom.  I'd only eaten about 1200 calories to go 82 miles, not nearly enough, so I had a slice of pizza (would have had two, but there were only two left and another hungry rider was standing right next to me) and a bag of Doritos and more Gatorade.  Still not enough, but I didn't want to gorge myself and cause stomach problems, so I resolved to eat more often and kept going.  I also bought some AAA batteries because one of my taillights was looking a bit dim.  (I never put new batteries in both of them at once, because I don't want them failing together.)  I caught up with Paul and Carol and rode behind them for a bit, but then they had to stop and I kept going alone again.

There were some more rollers, then a couple of miles on the shoulder of US 50, then a whole lot of empty rolling roads with bad pavement.  I gradually slowed down, probably due to not having eaten enough, and five or six riders passed me.  I was riding alone when I approached a turn that the cue sheet said would have loose dogs, and sure enough two dogs came running out into the road to meet me.  But it was a little dog and a medium-sized dog, both looking more playful than vicious, so not too bad.  But just to be safe, I whipped around the corner fast, not quite as fast as I wanted because a slow-moving pickup truck was blocking the road, but fast enough to avoid running into the pooches.  And continued down horrible roads at low speed.  I wasn't sure how much of the slowness was due to the road and the hills, and how much was due to not eating enough, but nobody else caught me from behind.

When I reached Lost River at mile 138 I was certain I was bonking, and the Lost River Grill had a menu that looked decent, so I ordered a real meal: onion soup, some kind of wrap, onion rings, and a milkshake.  Unfortunately a bunch of other riders came in right behind me, and there was only one waitress and probably only one cook, so it took a while to get all that food.  But it was good, and I probably needed the break.  I ate with the tandem team of John and Cindy, chatted with a couple of other riders, then left to climb Mill Gap and Wolf Gap.  I wanted to make sure to get down the steep side of Wolf Gap before it got dark.

Unfortunately I got a flat right at the top of Mill Gap, and it took me about 15 minutes to fix it.  I never found the cause, so I'm going to assume it was a pinch caused by the rough road, though that's surprising since it was a brand new 25 mm tire, I was going uphill (so not fast) and I don't remember hitting a particularly huge bump, just a zillion small ones. So maybe I have bad rim tape or something; I'll find out if I get another front flat soon.  While I was up there two tandems and two single bikes passed me, and sunset kept coming closer.  But it was 15 more minutes to digest dinner, and by the time I started climbing Wolf Gap the bonk was gone.  I stopped at the summit for a couple minutes to put on more clothes for the cold descent, and John and Eric caught up.  It wasn't dark yet, but there was very thick fog on the east side of the mountain, and I didn't fully trust my just-fixed tire, so I had to descend at 15 mph.  (Of course I don't descend windy roads very quickly anyway, so this wasn't a huge loss.)

I was almost out of food, so I went off-course a bit to the Sonoco station to buy a couple of candy bars, which I ended up never eating.  (But it was still a good idea to get them, because I was almost out of food, and really didn't want to bonk again.)  John caught up with me there, and we decided to ride back together.  On the steep hill when we first got on Back Road, I dropped my chain, for the second time that day.  A few miles later, two big dogs ran out into the road in front of us, but they backed off and let us by when we yelled at them.  And about halfway down Back Road, my headlight bracket got loose and my headlight started drooping and illuminating my front wheel instead of the road, so I pulled over into a church parking lot to fix it.  Carol and Paul and Chris went by while I was doing that, then John and I caught up with them and decided to ride with them the rest of the way, to avoid getting lost.  The five of us did the last 12 rolling miles or so of the brevet at a moderate pace, and finished just before 10 p.m., with a time of 16 hours and 51 minutes.

So what did I do wrong this time?  Two navigational errors (both when following other people, but still my fault) adding up to about 2.5 bonus miles, imperfectly adjusted derailleur limit screws resulting in two chain drops, one flat tire of unknown origin, cold toes caused by trusting the weather forecast and failing to wear my winter boots or bring shoe covers, and bonking from not eating enough.  The bonk probably cost me an hour, and the flat definitely cost me 15 minutes, so if I avoid those mistakes, I should be able to do this ride in 15.5 hours next time.  (Of course I'll probably make different mistakes, or it'll be windy, or something.)

Bicycles

Comments (0)

Permalink