<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Not Even My Wife Reads This</title>
	<atom:link href="http://www.ripton.net/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.ripton.net/blog</link>
	<description>Python, Linux, Bicycles, Books, Games, Etc.</description>
	<pubDate>Thu, 19 Aug 2010 03:39:09 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Old Rag 200km Ride Report</title>
		<link>http://www.ripton.net/blog/?p=56</link>
		<comments>http://www.ripton.net/blog/?p=56#comments</comments>
		<pubDate>Thu, 19 Aug 2010 03:35:39 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=56</guid>
		<description><![CDATA[Stan Miller and I rode the DC Randonneurs 600 together back in early June.  We didn't finish, mostly due to the heat.  But Stan was determined to do a full SR series this year, and emailed me a couple of days later, asking if I wanted to ride the New Jersey Randonneurs 600 [...]]]></description>
			<content:encoded><![CDATA[<p>Stan Miller and I rode the DC Randonneurs 600 together back in early June.  We didn't finish, mostly due to the heat.  But Stan was determined to do a full SR series this year, and emailed me a couple of days later, asking if I wanted to ride the New Jersey Randonneurs 600 with him in late June.  I wanted to, but I couldn't make it because our family vacation was already planned for that week, and I wished to remain married more than I wanted to do the ride.  So we decided to do the ROMA 600 in late September instead.</p>
<p>And then Stan was killed by a drunk SUV driver, near home, a few hours before the start of the NJ 600.  If only I'd been able to do that ride with him then he would have been hundreds of miles away from that drunk driver on that day&#8230;</p>
<p>Of course, that's the kind of irrationally warped negative thinking that leads people to quit riding, sit on the couch watching TV and eating Doritos instead, and die of a heart attack in their fifties.  So I got off the couch and signed up for the Old Rag 200.  Since I hadn't done a ride longer than 30 miles in a couple of months, I had no idea how I'd do, but it was only a 200k and the weather forecast looked nice, so I wasn't too worried.</p>
<p>I made it to the HoJos in Warrenton just a few minutes before the brevet was supposed to start.  I managed to leave with the main group, which was only 17 riders, not the 30 or 40 we usually get.  (It's vacation season, plus a bunch of folks are doing big event rides this month.)  The group quickly sped up to about 20 mph, and most of it passed me on the first big descent as usual.  If it had been a longer or harder ride I probably would have just let the group go early to spare my legs, but this time I decided to hang on as long as I reasonably could without frying myself.  We had a secret control about 20 miles in, which briefly fragmented the group, but things came back together and we still had a group of 12 at mile 40.  Then I started slipping off the back, and clawing back up, and slipping back again.  I wanted to keep the group in sight until the first control at mile 56, but then I really needed to pee, and that eventually (at mile 49) became more important than my pride, so I stopped, and didn't even try to chase back.  I averaged 18.2 mph to that point, pretty fast for me.  During that stretch I ate one Macadamia Nut Clif Bar, one orange Gu packet with double caffeine, and drank about 35 ounces of strong Gatorade.</p>
<p>I pulled into the control at Yoder's Country Store at mile 56 as the first two riders were pulling out.  Yoder's is a great control &#8212; good food plus a clean bathroom.  So I stopped to get a sandwich and refill my empty bottle with water that some nice faster rider had left.  I left alone a few minutes later.</p>
<p>The next stretch went through the nice little town of Madison and up the Blue Ridge Turnpike.  I reached the mile 71 control at Syria Mercantile still alone, riding about 16 mph, and feeling fine.  I was starting to wonder if this would be the first brevet I ever finished without a wrong turn.  I bought some cookies, refilled my bottle with more free water left by another nice rider, and put on some sunscreen.  Bennett came into the control while I was there, and I talked to him briefly, then left and immediately went the wrong way.  I mostly realized it within a half mile, but kept riding on in denial until I was really really sure before turning around.  2.6 bonus miles.  At least they were flat ones, unlike the hilly bonus miles I rode on the 600.  And the weather was nice, only about 78 degrees, about as cool as it gets in Virginia in August.</p>
<p>Leaving Syria for the second time I went up the short but steep climb.  A big truck with a big trailer was unable to safely pass me, and I really didn't want him right behind me all the way up the hill, so I bailed off the side of the road to let him by.  And then I got to the stop and went down the fun descent pretty fast.  And a few rolling miles later I reached Round Hill Road, home of the Three Meanies.  It's not really that big a hill, but it's split into roller, big hill, roller, big hill, roller, roller, big hill, roller.  (Maybe I got the order slightly wrong; feel free to check Google Maps.)  Lots of redundant grade, and the bigger hills twist so you can't see the top.  More frustrating than truly difficult.  The first time I rode this brevet in 2007, it broke my spirit and I actually stopped a couple of times to catch my breath.  It's a bad idea to stop halfway up a steep hill because then you lose all your momentum and have to struggle to clip in before you fall over.  This time, I rode it slowly but never even thought of stopping.  So I guess I'm still a better rider than I was 3 years ago, even if I'm in awful shape this summer.</p>
<p>After I reached the top, the next few miles featured some heavy-but-polite traffic on 522, and then the third control at Laurel Mills Store at mile 94.  I don't like this control because their selection of food and drink is subpar and they don't let us use their bathroom.  But I bought some Gatorade (no free water this time) and headed back out.  George rolled in as I rolled out.</p>
<p>It was about 20 miles of rollers to the next control.  I was tiring but not doing too badly, down to about 15 mph.  I needed another bathroom break but managed to reach the Orlean Store at mile 114 before needing to resort to the woods.  The Orlean Store is a very nice control &#8212; clean public bathroom plus good food.  Much fancier than most country stores.  I wasn't really hungry and it was only ten miles to the finish so I just bought a Coke.  Which I had a hard time drinking quickly &#8212; the carbonation didn't really agree with me.  George rolled in at that point and told me he'd lost his wallet at the previous control.  So he made some phone calls and I slowly drank my Coke, then we left the control together.</p>
<p>Even though I didn't feel really great, I looked at my time and realized that I could set a personal best time for a 200k if I pushed.  So when we got to the start of Piney Mountain, the last big climb of the day, I hammered.  George dropped behind &#8212; he always rides at a smart conservative pace, and often passes me after I overcook myself.  But this wasn't one of those days.  I made it over Piney Mountain in pretty good shape (though I got tricked by the false summit and thought I was done before I was), and rode pretty hard into Warrenton.  I finished in 8:45, 14 minutes faster than my previous best, set on this same brevet in 2007.  15.7 mph moving average, 14.6 mph including stops.  About 36 minutes spent stopped (Four store controls, one secret control, one pee break).  So not exactly fast &#8212; a bunch of riders finished an hour ahead of me &#8212; but not too bad for a guy who hadn't done a long ride in two months.</p>
<p>I hung around the hotel room at the end for a bit, talking to the riders and volunteers, but still wasn't hungry enough for post-ride pizza.  I left to go pick up my daughter, and right when I got my bike on the car, it started raining hard.  Perfect timing.  If I'd ridden my usual pace, I would have been soaked.  Not that getting wet in August is the worst thing in the world, but it still felt nice to avoid it.</p>
<p>All in all it was a good day.  Would have been a lot nicer if Stan were still around to ride with us, though.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=56</wfw:commentRss>
		</item>
		<item>
		<title>DC Randonneurs Many Rivers 600 km Brevet Ride Report</title>
		<link>http://www.ripton.net/blog/?p=55</link>
		<comments>http://www.ripton.net/blog/?p=55#comments</comments>
		<pubDate>Wed, 09 Jun 2010 04:01:19 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=55</guid>
		<description><![CDATA[This one is no fun to write because it's the first time I've failed to finish an organized ride.
Friday night, I did some last-minute work on my bike (which I should have done days before so I'd have time to make sure it was right).  Finished about 9.  Got to bed around 10. [...]]]></description>
			<content:encoded><![CDATA[<p>This one is no fun to write because it's the first time I've failed to finish an organized ride.</p>
<p>Friday night, I did some last-minute work on my bike (which I should have done days before so I'd have time to make sure it was right).  Finished about 9.  Got to bed around 10.  Fell asleep around 11.  Alarm was supposed to go off at 2.  It didn't (I set it to PM instead of AM), but I woke up anyway around 2:05.  So I didn't get nearly enough sleep before the ride.  The forecast was for 90 degrees and a 40% chance of thunderstorms Saturday, 82 degrees and a 50% of storms Sunday.  So I brought my raincoat and my Camelbak.</p>
<p>I drove to Warrenton, arriving about 30 minutes before the start.  Tech inspection and registration went perfectly, thanks to the volunteers and the nice facilities at the Hampton Inn.  (They gave us the Continental breakfast room in the lobby, so we had light to work with, plus some food.)</p>
<p>Over 40 riders turned up, a great turnout for such a long ride.  We rolled off at 4 a.m.  I resolved to not chase the fast group, and ended up in a slower group of about 11 riders.  Then fairly early in the ride we reached a group navigation crisis.  The cue sheet said to bear left.  There was a left turn there.  The signage was ambiguous.  About seven people decided to turn left, and four of us decided to go straight.  I think everyone still thinks they went the correct way and the other people got it wrong.  The two routes converged so we'll never really know, but our group rode an extra mile.</p>
<p>I was riding with Stan and Nick and George W.  Nick was on a mission.  He had expected times for every control and was trying hard to stay on schedule.  I figured Nick was pretty sure to finish so my goal was to stay with him and I'd finish too.  George fell off the back of our little group, and we were three.  A couple miles later we caught up with Larry, who'd been in the group of seven.  Which told us for sure that we'd been the ones who'd taken the longer way.  We were four again.  The sun came up, I made myself eat and drink, and eventually we reached the first control at mile 52 in Wolftown.</p>
<p>I bought a couple of bottles of Gatorade at the control, refilled my bottle with one and drank the other.  While I was drinking, Nick and Stan left.  (Like I said, Nick was on a schedule.)  I eventually finished my drank then decided to chase them down.  (Probably a dumb idea.)  I rode off at a pretty good clip and caught them around mile 61.  George M. caught us a couple of miles later, and we were four again.  George was faster than the others, and I decided to follow his pace rather than hanging back (you can always fall back to a group if you want, but it's harder to catch up to one), so I rode with George to the information control at mile 78.  A bunch of other riders were there already so we were briefly in a group of about 8.  But eventually George and I rode off the front of that group too.  It was starting to get hot and I was worried about whether I had enough liquid, so I stopped at a store at mile 84 and let George go.</p>
<p>I wasted a lot of time at that store, and Stan and Nick and Michael caught me, so I was in another group of four.  We continued into the heat.  Michael fell off the back and I rode with Stan and Nick for quite a while, to the Ashleys Market control at mile 103 and beyond.  Then I made a bad wrong turn.  On a long easy climb, Nick was pulling ahead and Stan was falling behind.  I decided to chase Nick (easy to fall back, hard to chase forward) but I missed the downhill turn onto Old Roberts Mountain Lane.  Badly.  After a bonus mile of climbing, Nick was gone.  I rode for a while by myself, and eventually caught up to Stan and Michael, both of whom were going slowly.  I said hello then continued past them, knowing I needed to go faster than that, but the heat got to me and I needed to take a bathroom break at the next store at mile 120.  I dawdled there for too long and Stan caught up and said Michael was going to abandon there.  So we waited for Michael to arrive and we made sure he was okay and had a ride before continuing.  And then I rode with Stan for the rest of the day.</p>
<p>Stan told me that he hadn't missed a turn all year, so we immediately missed the next turn and did a couple more bonus miles.  The next 50 miles or so were kind of a blur of endless rollers.  We were both hot and tired but we eventually caught up with Al, who didn't look so good and immediately made a wrong turn at a T intersection.  I yelled at him to get him back on course, and he confirmed to us that he was going to abandon.  So we rode with him to a grocery store in Palmyra, and wasted a lot of time there before continuing.  Michael eventually came out to give him a ride back to Warrenton; it was 90 miles and he didn't have the energy to make it.  So Stan and I set off again.  We reached the Louisa control at mile 182 at sundown.  We ate in a little Italian restaurant that had pretty good food, but it took a while to eat it, and it was fully dark when we left.  Then Stan had some lighting problems that took some time to resolve.</p>
<p>The last 70 miles or so were kind of a blur.  Stan was really tired and also short of water.  I had plenty, but it's not easy to dump water from a Camelbak to a bottle.  The convenience stores were all closed so we only had vending machines, which were all sold out of water so he had to settle for soda.  I had pain in my hands and left foot and saddle area.  Some pain is normal on a long ride, but this was far more than normal.  I think I had sweated a whole lot during the hot part of the day, and my own acidic sweat was attacking my skin.</p>
<p>We dragged into Warrenton about 4 a.m.  To have a good chance of finishing we really needed to start riding again almost immediately.  I asked for a 5 a.m. wake-up call, showered, and went to sleep.  Seconds later the wake-up call arrived.  My hands and saddle area still hurt, so I decided to go back to bed.  I think it was the right choice; it would have been a really painful last 200 km.  Better to try for the 600 again on a cooler day.</p>
<p>Anyway, what I learned from this one is that my sweat is evil and can eat my skin.  So I'll be bringing extra gloves and socks and shorts on any future long, hot brevets.  But I did manage to drink enough to avoid dehydrating in the heat.  And I ate enough to avoid bonking.  And I didn't fall asleep on the bike, despite not getting enough sleep the night before.</p>
<p>And I did quite a bit wrong.  I repeated the mistake of working on the bike right before the brevet.  (It had been popping out of the easiest gear.  I fixed that, but in the process loosened the front derailleur's low limit screw too much, so it could drop the chain to the inside on a hard downshift.  I think that happened four times on the ride.)  I stopped too long at the controls.  I made a couple of large navigation errors.</p>
<p>Oh well, maybe I'll do the ROMA 600 in September.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=55</wfw:commentRss>
		</item>
		<item>
		<title>DC Randonneurs Frederick 400k ride report</title>
		<link>http://www.ripton.net/blog/?p=54</link>
		<comments>http://www.ripton.net/blog/?p=54#comments</comments>
		<pubDate>Tue, 25 May 2010 00:42:46 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=54</guid>
		<description><![CDATA[Last year's 400 was really hard for me.  I got lost and I had stomach problems and I dehydrated and I bonked and I had 4 flat tires (1 blowout, 1 puncture, 2 bad fixes).  But I finished.  So I was a bit worried this time, even though I had a pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Last year's 400 was really hard for me.  I got lost and I had stomach problems and I dehydrated and I bonked and I had 4 flat tires (1 blowout, 1 puncture, 2 bad fixes).  But I finished.  So I was a bit worried this time, even though I had a pretty strong 300 a couple of weeks ago.</p>
<p>The things that went wrong for me in the 300 were arriving a bit late, minor mechanical issues (badly adjusted brakes and chain problems, on a bike I rarely ride), not bringing enough warm clothes, and ridiculous levels of wind.</p>
<p>So for the 400 I made sure to arrive on time, I rode my usual bike, and I brought a wool jersey and wool socks in addition to the synthetic jersey and cotton socks I usually wear in warm weather.  I also brought more food than usual: Clif bars, Gu, and Gatorade instead of plain water in my bottles.  I didn't bring my Camelbak even though I got dehydrated last year, because I hate wearing one and it wasn't supposed to be very hot.  I just resolved to completely fill my bottles at every opportunity and also to drink heavily at the controls.  (Not that kind of drinking heavily; that'll make you crash your bike.)  I think a bike with space for three full-sized water bottles is in my future.  I couldn't do anything about the weather, though.  The forecast was for a 50% chance of rain in the day and 60% at night, so I figured we'd probably get rained on some.  (This is called foreshadowing.  I learned about it in middle school English class.  You probably did too.)</p>
<p>The group left Frederick at 4 a.m. and I started off near the front.  Most of the fast riders seem to want to do a couple of miles at 15 mph to warm up, then speed up to over 20 mph.  I prefer to do the first couple of miles at 17 mph and then gradually slow down to 13 mph.  (Well, "prefer" is the wrong word.  I'd prefer to ride at 25 all day.  But that ain't gonna happen, ever.  I didn't win that particular genetic lottery.  I think my ancestors were the ones who tricked the mastodons into falling off cliffs, not the ones who ran down the gazelles.)  So I often end up leading the brevet very briefly, then getting rapidly shelled out the back.  At least it gives me a brief chance to see all the fast riders who I'm unlikely to see again all day.</p>
<p>Last year I somehow stayed with the fast pack all the way to the first control at 39 miles in Airmont.  This year, I lasted about 5 miles before I realized that I was going about 23 mph on the flat, which was wasting energy for no good reason.  (Maybe trying to keep up contributed to my bonking last year.)  So I let the pack go and rode alone.  Of course riding alone in the dark is a lot slower than riding with a fast group.  Not only do you lose the draft but you also lose the benefit of other people's lights so you have to descend more slowly.  And you have to navigate for yourself rather than just following a wheel and trusting that 20 people can't all be wrong.  But I think it's still the right choice to let the group go, if they're riding faster than you can reasonably sustain.</p>
<p>I really didn't have much power in my legs on this ride, for whatever reason.  Even just a few miles in, I found myself going 15 mph on the flats and coasting on the slight downhills.  But I climbed well (by my standards, not an actual good climber's standards) all day.  So the power was there when I really needed it, just not all the time.  I pondered why I didn't have it as I slowly rode from Frederick down to Brunswick and then over the bumpy bridge into Lovettesville and around western Loudoun County toward Airmont.  A few riders caught me from behind.  I just let them go and kept riding whatever speed my legs wanted to do.  Oddly that meant getting passed on the flats and then passing people on the uphills.  Of course I also got passed on the downhills, but I always do, because I'm an overly cautious descender.  It doesn't really matter much when you're riding alone because the total time spent going downhill is small, but it matters if you're trying to stick to a group and they accidentally drop you.  So I need to work on my descending.  But the early morning darkness was not the best time for that, so I resolved to not outrace my lights.  (I was using an Inolight 20, plus a cheap LED helmet light for backup / repair / cue sheet reading purposes.  The Inolight is reasonably bright but not super-bright, which makes it nice for my mostly bike trail commute because it doesn't blind oncoming traffic, but not so great for fast descending where you really need to be able to see far ahead.  I also own an Edelux, which is significantly brighter, which I should have mounted before this ride and will definitely mount before the 600.)</p>
<p>I stopped briefly at the Airmont information control, wrote down the information on my brevet card, chatted briefly with a couple of people, and then started the climb up to Snicker's Gap.  The climb was a lot easier than I remember from last year.  Maybe my legs were more tired then from chasing the fast people, or maybe I felt slow because I was watching the fast people pull away from me.  I made it to the top, climbed on the shoulder of Route 7 to the top of the hill (the shoulder is bumpy but perfectly safe for ascending at less than 10 mph), then moved to the white line for the extremely fast descent on Route 7.  This is a scary descent not because it's technical (the road is dead straight and you can see forever), but because there's high-speed traffic on the road and not all of it wants to move to the left lane to pass you.  My maximum speed was just over 40 mph and I got passed by another bike on the way down.  Didn't even have time to see who, it was just "Uh-oh there's a car I didn't hear coming right next to me, no wait it's a bike, wow he goes downhill fast."</p>
<p>Still riding alone, I turned off Route 7 into West Virginia.  I skipped the first store shown on the cue sheet, but my water was running low so I stopped at Charlie Brown's Store (which conveniently sells bongs and handguns so that area cyclists can tell more jokes about West Virginia) to get some Gatorade and use their porta-potty.  A couple other cyclists caught me while I was in the store, but in my weird slow-flat fast-uphill mode I didn't think I could fit well into a group, so I just said hi and continued riding alone.  The route contined toward Shenandoah Junction.  We know it really was a train junction because you have to cross railroad tracks approximately every half-mile in that area, and most of them are diagonal and extra-bumpy, as if the people who built the railroads feared invasion by Dutch bicycle troops and wanted their tracks to also serve as defensive fortifications.  (More foreshadowing.)</p>
<p>As part of a personal tradition of always riding more than the minimum number of miles on a brevet due to occasional inability to read a cue sheet, I turned left instead of right onto Flowing Springs Road and then couldn't find the expected turn onto Daniel Road because it wasn't there, it was the other way.   Of course I had to ride another mile to make sure, before looking harder at the cue sheet and figuring out what I'd done wrong.  Oh well, it was only 2.5 bonus miles, or a mere 1% of the total.  And continually trying to get better at navigation rather than just giving up and using a GPS probably builds character.</p>
<p>After crossing a whole lot of railroad tracks without crashing, I made it to the Shepherdstown Sweet Shop, which has lots of really tasty desserts that you'd feel bad about eating if you weren't riding your bike 250 miles.  And also sandwiches and drinks and bathrooms.  They need to franchise this place and put Starbucks out of business. I had some delicious but messy cherry crumb cake thing, and a donut that had peanut butter in it, and also a greek wrap.  Breakfast of champions.  Hey, I didn't want to bonk.</p>
<p>I left Shepherdstown and went west, approximately following the Potomac River, but not actually close enough to the river for the route to be flat.  Instead it kept on rolling.  Downhill, cross creek, uphill, repeat.  After 25 miles or so the course got on River Road.  River and Creek are usually good words on cue sheets (unlike Mountain and Hill and Ridge and Eagle and Gap and Pass and Highway), but this particular River Road isn't as flat as most, because the railroad got there first and put their train tracks between River Road and the river.  It was approaching noon and I saw some sun peeking between the clouds, so I stopped to put on some sunscreen.  Apparently that was just the cue the clouds were waiting for, because it started raining a few minutes later, and rained for most of the rest of the day and night.  Didn't really need that sunscreen.</p>
<p>Eventually River Road led to the bridge across the Potomac to Hancock, where Maryland is so narrow north-to-south that you can bike across the whole state in just a few minutes.  (Even if you don't actually bicycle much and just read ride reports so you can laugh at insane people, if you live in the area you should head out to Hancock sometime and bike from the river to the Mason-Dixon line, so that later you can say you biked across Maryland and impress geographically uninformed people with your athletic prowess.  You're welcome.)  But before biking all the way across Maryland to Pennsylvania, I had to visit the C&#038;O bike shop control.  It's nice to have a control at a bike shop because if you have a mechanical problem they have some bike parts, and if you have a really serious mechanical problem they rent and sell entire bikes.  And they also have porta-potties, and drinks, and a covered porch that procrastinating cyclists are allowed to loiter on while hoping the rain stops, and a limited supply of bike food. I bought a Clif Bar (I had some but wanted to try a different flavor) and some water and Gatorade, and drank until all the liquid that didn't fit in my bottles was gone.</p>
<p>The course continued down the Western Maryland Rail Trail for 5 miles, to dodge the Hancock traffic, then turned north into Pennsylvania cow country.  Cows and rain and rollers, a winning combination.  I slogged on until the Saunderosa Campground, where I got a delicious vanilla milkshake and refilled my water bottles.  There were 7 other riders there, hiding from the rain, and I decided to leave with them and ride with the group to relieve the monotony.</p>
<p>There was a pretty big climb immediately after the campground, which featured a really stupid driver who tried an ill-advised pass on a blind curve, almost caused a head-on collision, then honked at us like it was our fault.  How hard is it to wait until you can actually see whether you have room before passing?  I know it's boring to be stuck behind a bicycle for 30 seconds, but it's a lot worse to be dead.  Luckily the oncoming car was alert and stopped, so no carnage, just honking.  The rest of the climb was slow and easy.  The descent in the rain was fast and exciting.  My rear brake wasn't very well-adjusted and brakes and tires and road were wet, so I went down even more slowly than usual to make sure I could stop, and got passed by a couple of guys.  We regrouped at the bottom and continued through cow country together.</p>
<p>After about 20 more miles in the rain we reached Letterkenny, which featured a golf course whose pro shop has snack food and bathrooms.  We stopped there and ate hamburgers, which were okay.  While we were there Stan told me that the railroad tracks that were coming up were really nasty.  (More foreshadowing.)  So when we finally left I was third in line, and went over the first diagonal railroad tracks with my bike perfectly vertical but aimed left to cross the track perpendicular.  And again with the second set.  But then the third set of tracks were diagonal the other way (to confuse those invading bicycle troops) and I swung my bike around but I guess I didn't get it quite vertical, because I was on the ground.  Luckily there weren't any cars right behind me to compound the damage.  I was okay, just some road rash on my left arm and leg and a bruise on my hip.  We checked out my bike, which was okay except that the chain had come off, which someone fixed for me while I made sure none of my bones were sticking out.  Then we restarted.  I've been warned about railroad tracks for years and have been crossing them carefully for years, but this was the first time I ever actually fell on one.  Next time I come up to that kind of metal plate track setup in the rain, I'm unclipping both feet and going over at 5 mph.</p>
<p>After that excitement we'd lost a couple of riders off the front of our group, but they waited for us under a bank drive-through shelter a couple of miles up the road.  We continued through lots of mild rollers and then through a bunch of disgusting slippery cow-byproduct-infested mud on Mud Level Road.  Nobody slipped and fell in the mud but it was all over us anyway.  Somewhere in this section we saw a cyclist up ahead.  It was Paul, riding alone, and we merged him into our big group.  We got to the control at Kane's in Newville just before dusk.  Their fryer was broken but they made a good chicken cheesesteak.  (I thought a real beef cheesesteak would be too greasy, especially after the golf course burger.)</p>
<p>While we were in Kane's the rain stopped.  Fantastic!  Unfortunately, a few minutes after we left, it started again.  We went up Big Flat (the easy part but still a big climb).  As it got darker I noticed my headlight was barely working.  I figured the connector to the generator had come loose in my crash, but I didn't want to stop to fix it until someone else stopped.  So I followed Joel's headlight until I saw Bill stop to fix something, then I stopped to fix my headlight (it was just a loose connector, probably knocked off in my crash on the railroad tracks) and rode with Bill up the rest of the hill and down the descent and then through the rollers of Michaux State Forest.  Two lights are definitely better than one, especially when my one was my Inolight rather than my Edelux.  We made it to the next turn and the group all waited to have a navigation discussion, since half our cue sheets were soaked and the rest were under fogged-up plastic.  We came to a consensus and turned toward Gettysburg.</p>
<p>Just before Gettysburg Paul left our group.  Not sure why, but whoever talked to him determined that it was okay for the rest of us to press on to the control.  The remaining 8 of us stopped for a while at the 7-11 control.  They had the air conditioning on so it was freezing inside, and then it was cold again for a while when we got moving again.  But the remaining 40 miles was mostly flat to downhill and so not that hard even in the dark rain.  Except that I couldn't read my cue sheet, so staying with the group was imperative.  Luckily Bill had the route pretty much memorized.  We took almost two hours to make it to Thurmont, stopped again at the non-control 7-11 there, then took a long time to make it to the end in Frederick.  We arrived at 3:15 a.m.  My utter disaster of a 400k last year took 22 hours; this one took 23:15.  There was definitely a time penalty for riding with a big group because we rode at the speed of the slowest rider and took a long time at the controls and occasionally stopped to wait for each other.  But there was a huge navigation and safety benefit to sticking together.  Lots of lights.</p>
<p>When we got to the end my brevet card was soaked.  I had it in a Ziploc baggie but some water got in there somehow.  A volunteer dried it in the microwave, but the signature from one of the controls was illegible.  Luckily I went through that control with a whole bunch of other riders so our RBA was able to verify with them that I did indeed stop there.  Another benefit of riding with a group.  But next time I'm double-bagging my brevet card.  And bringing 3 cue sheets instead of my usual 2.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=54</wfw:commentRss>
		</item>
		<item>
		<title>DC Randonneurs Frederick 300k Ride Report</title>
		<link>http://www.ripton.net/blog/?p=53</link>
		<comments>http://www.ripton.net/blog/?p=53#comments</comments>
		<pubDate>Sat, 15 May 2010 23:51:11 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=53</guid>
		<description><![CDATA[My favorite road bike was sometimes making a funny creaking noise that sounded like handlebars but wasn't (because it continued when riding no-hands).  And it had a slow leak in the rear tire that I didn't feel like fixing.  And my rear brake pads were pretty worn and I didn't have any replacements handy.  [...]]]></description>
			<content:encoded><![CDATA[<p>My favorite road bike was sometimes making a funny creaking noise that sounded like handlebars but wasn't (because it continued when riding no-hands).  And it had a slow leak in the rear tire that I didn't feel like fixing.  And my rear brake pads were pretty worn and I didn't have any replacements handy.  So I decided to ride my touring bike, which I hadn't ridden since last August.  Hey, it's got a triple, so the climbs would be easier.  You probably already know where this is going&#8230;</p>
<p>The night before the ride I installed a new chain, and a cyclocomputer, and lights.  This should have taken 30 minutes but it ended up taking longer.  I packed everything in my car then went to bed, so I could wake up and drive to Frederick for the 5 a.m. start.</p>
<p>I woke up at 3:30 and somehow wasn't at full speed on 5 hours of sleep, and managed to get to the start at about 4:58.  It took me a few minutes to get my bike ready, and then the big pack had already left.  The volunteers at the start checked my lights and gave me a brevet card and a cue sheet, and I was off into the darkness about ten minutes behind almost everyone else.  At the first turn I caught a guy (Chris, I think) on the lowest tadpole trike I'd ever seen.  First time I've seen a trike on a brevet.</p>
<p>Since I still had delusions of catching the pack, I kept going without slowing to chat, checked my cue sheet and computer for the distance to the next turn &#8212; and noticed that my newly installed bike computer was set for kilometers rather than miles.  Now, I've got nothing against kilometers.  As a matter of fact, I'd be thrilled if the US would go 100% metric tomorrow to avoid the inefficiency of needing to constantly convert stuff between the US and the rest of the world, making our imports cheaper and our exports more competitive.  But the cue sheet is in miles, and constantly multiplying and dividing by 1.6 in my head is not much fun.  Worse, I knew that switching the computer to miles involved hitting some micro-button on the back a bunch of times in a sequence that I'd probably not guess without the manual, and would also end up resetting elapsed distance to zero.  So I just left it in metric and navigated without really using the computer all day.</p>
<p>I kept riding into the pre-dawn darkness, and eventually met up with Hank from New York.  He'd forgotten his water bottles and had to go back to the start.  Neither of us were going really fast so we just rode and talked until we started catching the slower riders who were off the back of the main field.  As we started the climb into Catoctin Mountain Park, Hank caught up with his friend Tom and slowed to his pace, and I went ahead.</p>
<p>The first climb of the day through Catoctin was not very steep, but it went on for a long time.  And it started raining.  Our route didn't actually go up Park Central Road (probably because it gets closed whenever the President is at Camp David or the Secret Service just feels like inconveniencing people) so we took the loop around.  With the rain came some wind and dropping temperatures.  I had arm warmers and a cycling cap but no tights or jacket or heavy jersey, because the forecast hadn't called for cold and I was momentarily too stupid to remember that weathermen are often wrong.  So I was a bit chilly, but it wasn't too bad as long as I kept moving.</p>
<p>Eventually the climb ended and we had a secret control.  When I'd plotted the route on Google Maps I'd noticed that the known controls allowed completely bypassing Catoctin Mountain Park and skipping a whole bunch of riding and climbing, so I'd figured there'd be one.  George and Tyler were there and they had food. I didn't take any because I'd stopped to eat a banana and some Vanilla Bean Gu one corner before the control.  I said hello, got my card stamped, and took off.</p>
<p>A bit later I caught and passed Dave from Potomac, riding his first brevet.  And then my helmet light (a cheap Princeton Tec 4-LED AA-battery model that I use as a secondary light for reading cue sheets) fell off going down a hill.  I reversed and picked it up (right in the middle of the lane) and it still worked.  LEDs are a lot more durable than bulbs, but I still think I got lucky.  That's why you always bring at least two headlights and two taillights.  It was light by then so I put the helmet light away and just used the one on my handlebars for the rest of the early morning.  I eventually caught up with Lowell and Cheryl on their tandem, riding with Cliff.  I said hi and then passed them but then a downhill came and my poorly-adjusted cantilevers (oh yeah, now I remember why I never ride this bike on brevets) scared me so I descended even slower than usual and they descended faster and flew away from me.  I caught them again at a store around the 30 mile point and we'd continue to pass each other all day.</p>
<p>Then there was a big climb which turned out to be Big Flat in Michaux State Forest.  I climbed it last year on the 400, but I guess I'd suppressed the memory, because I forgot about the false summit.  So I climbed a lot (and it was much easier with a triple and only 40 miles in my legs than with a compact double and 150 miles), and eventually reached the top and started tearing downhill, only to see the real summit up ahead.  By this point the rain had stopped, but the wind had started to pick up.  The wind wasn't so bad on the climb, and I got to the top feeling pretty good, but on the big descent the combination of badly-adjusted screeching cantilevers and occasional 30 mph crosswind gusts was a wee bit scary.  I was happy to reach the bottom, even though it meant I had to pedal again.</p>
<p>The first control at mile 67 was a Uni-Mart convenience store in Shippensburg.  It had a clean bathroom and food and drinks for sale so I give it an A.  I ate a gigantic Rice Krispies Treat bar and a Macadamia Nut Clif Bar (my new favorite flavor) and probably some other stuff, and drank a big Gatorade (now that they have low-calorie G2 Gatorade, the "sports drink" for drinking while you watch sports on TV, you have to be careful to get the real stuff if you're trying to fuel up and avoid bonking) and filled my bottles with the rest.  I saw a bunch of people who had been ahead of me at the control, but I didn't manage to get through fast enough so I ended up leaving alone.  I got confused by the cue sheet leaving Shippensburg and ended up making a bit loop back to the Uni-Mart and trying again.  And a young man in a Mustang decided to blow through a stop sign right in front of me and test my brakes.  There's a reason not to ride through college towns.</p>
<p>I got back on course, and then suddenly my pedals refused to spin forward. I coasted to a stop off the side of the road and found my chain outside my rear derailleur.  How the heck did that happen?  There's a little tab that's supposed to keep it from slipping out but somehow it had.  I jammed it back in there, but the chain starting skipping once per revolution, like I had a bad link.  So I pulled over again and got out the chain tool and removed the problem link and replaced it with an extra SuperLink from my bag.  Surprisingly, that didn't really fix the problem.  The brand-new chain continued skipping for the rest of the ride.  I decided it was good enough and that I'd rather ride than continue working on the bike, and I found that it didn't happen as much in the big ring, so I rode most of the ride in the big ring.</p>
<p>After zipping through Newville, the next control was at Young's Deli in Bloserville.  No bathroom and slow service, so I give it a D, but they did have sandwiches.  I ate one and took off again.  A bit later the ride went down Creek Road, a beautiful low-traffic road that was actually right next to a creek, and more importantly with the wind at my back for a change.  A 25-mile-per-hour tailwind is a wonderful thing.  Unfortunately the road turned again and it was a crosswind or a headwind for most of the rest of the ride.</p>
<p>I stopped again at a Subway in Mount Holly Springs, because they had a bathroom.  While I was there I got a footlong BMT and two cookies.  This was probably the biggest meal I'd ever eaten on a brevet, and it did a great job keeping the bonk away.  The time I spent at Subway let Hank and Dave catch me, and we rode together for a while.  We eventually reached a decent-sized hill that I wanted to climb faster than they did, and I pulled away.  We met again at the Rocco's Pizza control in East Berlin at mile 129.</p>
<p>Rocco's had okay pizza, but I only ate one slice since I'd just had a big sub.  I hung out at Rocco's for a while, then left with Dave and Hank.  Riding as a small paceline helped with the wind a bit, though it was often coming from the side and it's not always possible to ride echelons if there are cars about.  Then we just kept riding as it slowly got darker and colder.  It started to rain a bit, but not too bad.  The wind never went away.  We stopped twice more, once at a Getty in Bonneuville around mile 144, and once at a 7-11 in Thurmont around mile 168.  I didn't get anything to eat at the last stop, and so I finally started wearing out as we rolled into the last control at the Motel 6 in Frederick.  The ride took us 18 hours.</p>
<p>So I had a decent day legs-wise (not fast but never really in any trouble), a great day nutrition wise (eat before you're hungry, drink before you're thirsty, repeat), and a lousy day equipment wise.  Riding a bike I hadn't written in months on a 300k brevet was dumb.  So was not bringing enough warm clothing.  So was not securing my headlight very well.  So was arriving late and missing the big group, maybe.  It may have been a blessing in disguise, by removing the temptation to waste energy chasing the fast people early.  Anyway, the 400k is coming in a couple of weeks, and I'll be going back to my usual reliable bike (but with new rear brake pads), and I'll be sure to be prepared for colder-than-expected weather.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=53</wfw:commentRss>
		</item>
		<item>
		<title>DC Randonneurs Old Rag 200 km brevet ride report</title>
		<link>http://www.ripton.net/blog/?p=52</link>
		<comments>http://www.ripton.net/blog/?p=52#comments</comments>
		<pubDate>Sun, 11 Apr 2010 23:39:34 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=52</guid>
		<description><![CDATA[I biked to work all winter, except for a couple of weeks when record snowfall made the W&#38;OD Trail nearly impassable.  But I hadn't done a ride longer than 35 miles since November.  And I was still carrying way too much winter weight, which would make climbing hard.  So I was a [...]]]></description>
			<content:encoded><![CDATA[<p>I biked to work all winter, except for a couple of weeks when record snowfall made the W&amp;OD Trail nearly impassable.  But I hadn't done a ride longer than 35 miles since November.  And I was still carrying way too much winter weight, which would make climbing hard.  So I was a bit worried about yesterday's 200 km brevet.</p>
<p>I did this ride a couple of years ago, so I thought I knew what to expect.  Mostly flat and fast early, from Warrenton down to Madison, then a big climb after the second control in Syria, then some rollers, then another big three-part climb, then more rollers, then a really nasty climb over Piney Mountain west of Warrenton right before the finish.</p>
<p>But this time the ride was in April not July, so there was cold to deal with in the morning, but fortunately less heat in the afternoon.  Plus that extra April weight and lack of fitness.</p>
<p>So I decided to take it seriously and try to do everything right.  I got to the start half an hour early.  And I dressed for the 36F start temperature &#8212; thermal tights, wool socks, heavy jersey, balaclava, lobster claws &#8212; but wore shorts and a short-sleeved wool jersey underneath for the expected afternoon warmth.  (The forecast high was 64.)</p>
<p>I started at the front of the group, but resolved not to work very hard to stay there.  (There's no chance of me finishing the brevet first, but if I work at it I can stay near the front for the first half of the ride &#8212; and then die in the second half.)  When the first serious descent happened and a dozen people passed me (I'm still a cautious descender), I let them go rather than chasing them down like I wanted to.  And rode by myself for miles, between the first and second big groups.  When the second group caught me, I let them go too.  "Do not waste energy early," I boringly kept telling myself.</p>
<p>I stopped once to water some trees, and again to take off a layer of clothes, and made it to the first control at 55 miles.  Yoder's Country Market is pretty much the perfect control.  They have a wide variety of good, cheap food.  And picnic tables, some in the sun and some in the shade.  And a clean bathroom.  And free water.  What more could you want?</p>
<p>I ate lunch pretty quickly and left by myself.  "Don't waste time in the controls," the boring guy on my shoulder told me.  By that time the temperature was near 60 and I was riding in short sleeves, lightweight full-finger gloves, and still had the tights on.</p>
<p>I proceded through Madison, still riding alone.  Got to the 71-mile control at Syria Mercantile (Note: the Virginia town of Syria is not pronounced like the country Syria.  The first syllable has a long I sound, and you have to say it with a pronounced Virginia hill country accent.  sigh-REE-uh.)  Not nearly as nice a control, but I bought a Gatorade, and filled up my bottles from a half-full gallon jug that a faster rider had left for slower riders.  (Thanks fast rider!)  I also took off my tights and switched to fingerless gloves and cotton socks and put on some sunscreen.  And crammed all those winter clothes into my Carradice bag.</p>
<p>There's a climb after the Syria control that I remembered as being nasty, but this time it wasn't so bad.  It was steep for a bit, but it wasn't that long.  There were some rollers afterward.  At this point lunch finally kicked in, and my legs came back, so I started climbing faster and passed a rider ahead.  I remember thinking that everything was going so well that I wouldn't have anything to put in my ride report.</p>
<p>Then I turned onto Round Hill Road, and remembered the three nasty hills.  And felt something hit me in the small of the back.  I pulled off the road to check, and noticed my bag was open and the flap had bounced up to let me know.  Whoops.  I closed it and continued, hoping I hadn't lost anything.  (I didn't actually bother taking inventory, because I wasn't going back regardless.  It was 8 miles since the last control, and I didn't feel strong enough to add up to 16 hilly bonus miles to my ride.)</p>
<p>I climbed the three nasty hills without needed to stop to catch my breath (the last time I rode this route I needed to stop, but it was July and hotter).  And continued over a bunch more rollers and then a fast section of US 522 until I reached the 95 mile control, the Laurel Mills Store.  The guy who works at this store is very nice, but I still don't like this control because it lacks a public bathroom.  Also, the Klondike bar I bought there was frozen solid, a serious dental hazard.  So I had to hang around for a while while it thawed, answering questions from a kid riding his bike around the parking lot while wearing a cowboy hat.</p>
<p>While I was waiting, a rider showed up and asked me if I'd dropped anything.  Whoops.  He had my arm warmers and my gloves.  Another rider who arrived a couple minutes later had my balaclava and one of my wool socks.  They said a motorist had seen my reflective vest, but they couldn't find it.  Or, predictably, the other sock.  (Everyone loses one sock, even in their own dryer at home.)  So the good news is that the total punishment for forgetting to close my bag was one lost sock and one lost vest.  And it was a $15 Nashbar vest that I didn't like much anyway because the shoulders tended to ride up and block my peripheral vision.  Thanks again to the riders who recovered my dropped stuff, and anyone else who helped look for it.  Sorry if my absent-mindedness made your ride slower.</p>
<p>Embarrassed at my silly mistake, I left the control slowly.  Whatever energy had gone into my legs after lunch was fading again.  I just trudged through Flint Hill and into the control at mile 114.  I wasn't feeling horrible, but I wasn't going fast.  Probably a touch of bonk.  The Orlean Store is very nice &#8212; clean bathroom, nice selection of food and drink, even a real restaurant adjacent.  I bought some water and some iced tea (I was getting hot in my wool jersey, even though tempertures were still in the 60s) and then left pretty quickly to do the nasty last ten miles.</p>
<p>Right after Orlean the cue sheet had two turns back to back, one after 0.1 miles and the next after 0.2.  I made the first but then zoned out and didn't check the cue sheet until I'd gone by the second, for my only bonus miles of the day.  I kept going about half a mile before I realized my mistake, so it was more like one bonus mile.  No big deal, but another sign that I was a bit cooked.  I had two full bottles for only ten miles of riding, so I resolved to drink more than I wanted, just in case dehydration was affecting my legs or my brain.  (In hindsight, I don't think so.  I think I was properly hydrated but slightly bonked, just not quite enough food.  I had some Gu and some Jelly Belly Sport Beans but didn't eat them for whatever reason.)  Soon enough, the climb up Piney Mountain began.  But it didn't seem as bad as last time I did this ride.  While I didn't have any speed (I was climbing at 5-6 mph), I didn't have to stop either.  When I reached the summit I was very happy.  Until the next hills, which I'd forgotten about.  They're just rollers, but when you think you're coasting into the barn, any hill is a bad hill.</p>
<p>I rolled into the final control in Warrenton in 10 hours 12 minutes.  Last time I did this ride it took 8:59.  So my spring unfitness cost me over an hour.  But I finished and didn't hurt myself and had fun (other than being annoyed at my slowness and at forgetting to close my bag), so it was a good ride.  I'm a bit nervous about the upcoming 300k, though.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=52</wfw:commentRss>
		</item>
		<item>
		<title>Three Pathological cases for the PyPy JIT</title>
		<link>http://www.ripton.net/blog/?p=51</link>
		<comments>http://www.ripton.net/blog/?p=51#comments</comments>
		<pubDate>Thu, 01 Apr 2010 02:35:21 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Math]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=51</guid>
		<description><![CDATA[At PyCon, Maciej from the PyPy team asked for programs that the PyPy JIT did a really bad job on.
I have a directory full of over 200 little Python programs that attempt to solve Project Euler math problems.  Only 186 of them get the right answer, and fewer of them run in a reasonable [...]]]></description>
			<content:encoded><![CDATA[<p>At PyCon, Maciej from the PyPy team asked for programs that the PyPy JIT did a really bad job on.</p>
<p>I have a directory full of over 200 little Python programs that attempt to solve Project Euler math problems.  Only 186 of them get the right answer, and fewer of them run in a reasonable period of time.  But this led me to concoct a quick benchmark comparing the Python implementations installed on my computer: CPython, CPython with Psyco, Unladen Swallow, and PyPy.  (I haven't tested them with Jython or IronPython yet.  Maybe someday.)</p>
<p>Basically, I just run all of euler*.py under four different Python implementations, record how long it took each implementation to run each program, and throw out the results for any programs that didn't work in all four versions of Python, or that didn't finish in 60 seconds or less on all of them.</p>
<p>Here are the results, for recent svn checkouts of PyPy and Unladen, CPython 2.6.4, and CPython 2.6.4 plus Psyco 1.6.  (Don't get too obsessed with the exact results, since it's just a private benchmark and most of the code is unpublished.  This is just background for the real information at the bottom of the post.)</p>
<table>
<th>script</th>
<th>pypy</th>
<th>unladen</th>
<th>psyco</th>
<th>CPython</th>
<tr>
<td>euler1.py</td>
<td align='right'> 0.66</td>
<td align='right'> 0.60</td>
<td align='right'> 0.11</td>
<td align='right'> 0.61</td>
</tr>
<tr>
<td>euler2.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.40</td>
</tr>
<tr>
<td>euler3.py</td>
<td align='right'> 0.21</td>
<td align='right'> 0.51</td>
<td align='right'> 0.31</td>
<td align='right'> 0.41</td>
</tr>
<tr>
<td>euler4.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.51</td>
<td align='right'> 0.20</td>
<td align='right'> 0.31</td>
</tr>
<tr>
<td>euler5.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler6.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler7.py</td>
<td align='right'> 0.11</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.31</td>
</tr>
<tr>
<td>euler8.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler9.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler10.py</td>
<td align='right'> 2.23</td>
<td align='right'> 3.98</td>
<td align='right'> 1.74</td>
<td align='right'> 7.73</td>
</tr>
<tr>
<td>euler11.py</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler13.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler14.py</td>
<td align='right'>44.79</td>
<td align='right'> 2.64</td>
<td align='right'> 1.33</td>
<td align='right'> 2.96</td>
</tr>
<tr>
<td>euler15.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler16.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler18.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler19.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler20.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler21.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler22.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler23.py</td>
<td align='right'> 4.55</td>
<td align='right'>20.96</td>
<td align='right'> 4.08</td>
<td align='right'>10.50</td>
</tr>
<tr>
<td>euler24.py</td>
<td align='right'> 6.77</td>
<td align='right'> 4.18</td>
<td align='right'> 7.88</td>
<td align='right'> 4.65</td>
</tr>
<tr>
<td>euler25.py</td>
<td align='right'> 0.61</td>
<td align='right'> 0.81</td>
<td align='right'> 0.82</td>
<td align='right'> 0.81</td>
</tr>
<tr>
<td>euler26.py</td>
<td align='right'> 8.47</td>
<td align='right'>10.10</td>
<td align='right'> 9.09</td>
<td align='right'>10.41</td>
</tr>
<tr>
<td>euler27.py</td>
<td align='right'> 3.06</td>
<td align='right'> 6.37</td>
<td align='right'> 1.23</td>
<td align='right'> 8.64</td>
</tr>
<tr>
<td>euler28.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler29.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler30.py</td>
<td align='right'> 3.04</td>
<td align='right'> 3.55</td>
<td align='right'> 5.62</td>
<td align='right'> 3.85</td>
</tr>
<tr>
<td>euler32.py</td>
<td align='right'> 2.96</td>
<td align='right'> 3.34</td>
<td align='right'> 4.07</td>
<td align='right'> 3.57</td>
</tr>
<tr>
<td>euler33.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler34.py</td>
<td align='right'> 7.08</td>
<td align='right'>11.96</td>
<td align='right'>11.12</td>
<td align='right'>12.96</td>
</tr>
<tr>
<td>euler35.py</td>
<td align='right'> 5.97</td>
<td align='right'>18.01</td>
<td align='right'> 9.91</td>
<td align='right'>25.38</td>
</tr>
<tr>
<td>euler36.py</td>
<td align='right'> 1.83</td>
<td align='right'> 2.93</td>
<td align='right'> 3.24</td>
<td align='right'> 2.83</td>
</tr>
<tr>
<td>euler37.py</td>
<td align='right'>11.23</td>
<td align='right'>10.83</td>
<td align='right'>17.89</td>
<td align='right'>12.13</td>
</tr>
<tr>
<td>euler38.py</td>
<td align='right'> 1.92</td>
<td align='right'> 1.22</td>
<td align='right'> 1.63</td>
<td align='right'> 1.42</td>
</tr>
<tr>
<td>euler39.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.30</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler40.py</td>
<td align='right'> 0.81</td>
<td align='right'> 0.91</td>
<td align='right'> 0.51</td>
<td align='right'> 0.71</td>
</tr>
<tr>
<td>euler41.py</td>
<td align='right'> 4.18</td>
<td align='right'> 3.54</td>
<td align='right'> 4.86</td>
<td align='right'> 4.05</td>
</tr>
<tr>
<td>euler42.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler43.py</td>
<td align='right'>36.69</td>
<td align='right'>27.91</td>
<td align='right'>37.50</td>
<td align='right'>29.19</td>
</tr>
<tr>
<td>euler44.py</td>
<td align='right'> 1.02</td>
<td align='right'> 7.98</td>
<td align='right'> 0.72</td>
<td align='right'> 4.50</td>
</tr>
<tr>
<td>euler45.py</td>
<td align='right'> 6.95</td>
<td align='right'> 2.54</td>
<td align='right'> 2.36</td>
<td align='right'> 2.45</td>
</tr>
<tr>
<td>euler46.py</td>
<td align='right'> 0.21</td>
<td align='right'> 0.91</td>
<td align='right'> 0.21</td>
<td align='right'> 1.23</td>
</tr>
<tr>
<td>euler47.py</td>
<td align='right'> 0.71</td>
<td align='right'> 1.92</td>
<td align='right'> 0.61</td>
<td align='right'> 2.97</td>
</tr>
<tr>
<td>euler48.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.21</td>
<td align='right'> 0.21</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler49.py</td>
<td align='right'> 0.31</td>
<td align='right'> 1.02</td>
<td align='right'> 0.72</td>
<td align='right'> 0.72</td>
</tr>
<tr>
<td>euler51.py</td>
<td align='right'>22.68</td>
<td align='right'>27.90</td>
<td align='right'>49.11</td>
<td align='right'>31.86</td>
</tr>
<tr>
<td>euler52.py</td>
<td align='right'> 0.71</td>
<td align='right'> 0.81</td>
<td align='right'> 0.91</td>
<td align='right'> 1.11</td>
</tr>
<tr>
<td>euler53.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.20</td>
<td align='right'> 0.20</td>
<td align='right'> 0.31</td>
</tr>
<tr>
<td>euler54.py</td>
<td align='right'> 0.30</td>
<td align='right'> 0.20</td>
<td align='right'> 0.21</td>
<td align='right'> 0.21</td>
</tr>
<tr>
<td>euler56.py</td>
<td align='right'> 0.83</td>
<td align='right'> 0.71</td>
<td align='right'> 0.92</td>
<td align='right'> 0.62</td>
</tr>
<tr>
<td>euler57.py</td>
<td align='right'> 0.41</td>
<td align='right'> 0.51</td>
<td align='right'> 0.52</td>
<td align='right'> 0.72</td>
</tr>
<tr>
<td>euler58.py</td>
<td align='right'> 6.57</td>
<td align='right'>37.76</td>
<td align='right'> 6.77</td>
<td align='right'>58.48</td>
</tr>
<tr>
<td>euler59.py</td>
<td align='right'>12.85</td>
<td align='right'> 6.88</td>
<td align='right'> 9.81</td>
<td align='right'>15.98</td>
</tr>
<tr>
<td>euler61.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
<td align='right'> 0.31</td>
<td align='right'> 0.21</td>
</tr>
<tr>
<td>euler62.py</td>
<td align='right'> 0.31</td>
<td align='right'> 0.20</td>
<td align='right'> 0.41</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler63.py</td>
<td align='right'> 0.21</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler64.py</td>
<td align='right'>10.93</td>
<td align='right'>38.67</td>
<td align='right'>44.00</td>
<td align='right'>59.01</td>
</tr>
<tr>
<td>euler65.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.11</td>
</tr>
<tr>
<td>euler66.py</td>
<td align='right'> 2.43</td>
<td align='right'> 8.49</td>
<td align='right'> 9.82</td>
<td align='right'>12.13</td>
</tr>
<tr>
<td>euler67.py</td>
<td align='right'> 0.11</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
</tr>
<tr>
<td>euler68.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler69.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
</tr>
<tr>
<td>euler70.py</td>
<td align='right'> 0.41</td>
<td align='right'> 0.73</td>
<td align='right'> 1.03</td>
<td align='right'> 0.61</td>
</tr>
<tr>
<td>euler71.py</td>
<td align='right'> 0.32</td>
<td align='right'> 1.53</td>
<td align='right'> 0.31</td>
<td align='right'> 1.31</td>
</tr>
<tr>
<td>euler72.py</td>
<td align='right'> 7.85</td>
<td align='right'>32.59</td>
<td align='right'> 9.77</td>
<td align='right'>56.56</td>
</tr>
<tr>
<td>euler73.py</td>
<td align='right'> 9.19</td>
<td align='right'>27.32</td>
<td align='right'> 2.87</td>
<td align='right'>25.50</td>
</tr>
<tr>
<td>euler75.py</td>
<td align='right'> 5.15</td>
<td align='right'> 2.22</td>
<td align='right'> 0.61</td>
<td align='right'> 2.32</td>
</tr>
<tr>
<td>euler77.py</td>
<td align='right'> 0.31</td>
<td align='right'> 0.32</td>
<td align='right'> 0.23</td>
<td align='right'> 0.51</td>
</tr>
<tr>
<td>euler79.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler80.py</td>
<td align='right'> 0.71</td>
<td align='right'> 0.71</td>
<td align='right'> 0.71</td>
<td align='right'> 0.61</td>
</tr>
<tr>
<td>euler81.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler82.py</td>
<td align='right'> 0.71</td>
<td align='right'> 0.31</td>
<td align='right'> 0.30</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler83.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.61</td>
<td align='right'> 0.41</td>
<td align='right'> 0.51</td>
</tr>
<tr>
<td>euler84.py</td>
<td align='right'> 2.93</td>
<td align='right'>14.24</td>
<td align='right'> 4.76</td>
<td align='right'>17.89</td>
</tr>
<tr>
<td>euler85.py</td>
<td align='right'> 6.67</td>
<td align='right'> 7.20</td>
<td align='right'>11.16</td>
<td align='right'>11.84</td>
</tr>
<tr>
<td>euler87.py</td>
<td align='right'> 1.63</td>
<td align='right'> 1.32</td>
<td align='right'> 0.41</td>
<td align='right'> 0.82</td>
</tr>
<tr>
<td>euler89.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler93.py</td>
<td align='right'> 3.13</td>
<td align='right'> 5.26</td>
<td align='right'> 5.31</td>
<td align='right'>11.75</td>
</tr>
<tr>
<td>euler94.py</td>
<td align='right'>34.40</td>
<td align='right'>26.40</td>
<td align='right'>26.30</td>
<td align='right'>27.80</td>
</tr>
<tr>
<td>euler97.py</td>
<td align='right'> 3.44</td>
<td align='right'> 4.56</td>
<td align='right'> 2.35</td>
<td align='right'> 3.34</td>
</tr>
<tr>
<td>euler98.py</td>
<td align='right'> 0.30</td>
<td align='right'> 0.61</td>
<td align='right'> 0.51</td>
<td align='right'> 0.51</td>
</tr>
<tr>
<td>euler99.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler100.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler101.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler102.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler103.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler105.py</td>
<td align='right'> 0.61</td>
<td align='right'> 0.30</td>
<td align='right'> 0.81</td>
<td align='right'> 0.30</td>
</tr>
<tr>
<td>euler106.py</td>
<td align='right'> 0.61</td>
<td align='right'> 0.51</td>
<td align='right'> 0.81</td>
<td align='right'> 0.31</td>
</tr>
<tr>
<td>euler107.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.41</td>
<td align='right'> 0.20</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler108.py</td>
<td align='right'> 3.77</td>
<td align='right'>13.74</td>
<td align='right'> 7.14</td>
<td align='right'> 9.99</td>
</tr>
<tr>
<td>euler109.py</td>
<td align='right'> 0.31</td>
<td align='right'> 1.22</td>
<td align='right'> 0.31</td>
<td align='right'> 1.64</td>
</tr>
<tr>
<td>euler111.py</td>
<td align='right'> 3.27</td>
<td align='right'>15.82</td>
<td align='right'> 4.19</td>
<td align='right'>15.28</td>
</tr>
<tr>
<td>euler112.py</td>
<td align='right'> 5.96</td>
<td align='right'>12.45</td>
<td align='right'>11.42</td>
<td align='right'>13.50</td>
</tr>
<tr>
<td>euler114.py</td>
<td align='right'> 0.12</td>
<td align='right'> 0.21</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
</tr>
<tr>
<td>euler115.py</td>
<td align='right'> 0.22</td>
<td align='right'> 0.41</td>
<td align='right'> 0.30</td>
<td align='right'> 0.62</td>
</tr>
<tr>
<td>euler116.py</td>
<td align='right'> 0.11</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
</tr>
<tr>
<td>euler117.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
</tr>
<tr>
<td>euler119.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler120.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler121.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
<td align='right'> 0.10</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler123.py</td>
<td align='right'> 5.87</td>
<td align='right'> 5.26</td>
<td align='right'> 8.78</td>
<td align='right'> 7.05</td>
</tr>
<tr>
<td>euler124.py</td>
<td align='right'> 0.82</td>
<td align='right'> 1.83</td>
<td align='right'> 0.71</td>
<td align='right'> 2.43</td>
</tr>
<tr>
<td>euler125.py</td>
<td align='right'> 0.93</td>
<td align='right'> 1.42</td>
<td align='right'> 1.33</td>
<td align='right'> 1.32</td>
</tr>
<tr>
<td>euler135.py</td>
<td align='right'>28.39</td>
<td align='right'> 5.22</td>
<td align='right'> 2.65</td>
<td align='right'> 4.19</td>
</tr>
<tr>
<td>euler142.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.81</td>
<td align='right'> 0.11</td>
<td align='right'> 0.41</td>
</tr>
<tr>
<td>euler157.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler162.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler171.py</td>
<td align='right'> 0.12</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler173.py</td>
<td align='right'> 0.92</td>
<td align='right'> 1.42</td>
<td align='right'> 1.02</td>
<td align='right'> 1.01</td>
</tr>
<tr>
<td>euler174.py</td>
<td align='right'>35.72</td>
<td align='right'> 4.75</td>
<td align='right'> 2.96</td>
<td align='right'> 3.27</td>
</tr>
<tr>
<td>euler181.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler190.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler193.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler202.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler205.py</td>
<td align='right'> 1.83</td>
<td align='right'> 0.72</td>
<td align='right'> 2.35</td>
<td align='right'> 0.71</td>
</tr>
<tr>
<td>euler207.py</td>
<td align='right'> 0.11</td>
<td align='right'> 0.53</td>
<td align='right'> 0.32</td>
<td align='right'> 0.42</td>
</tr>
<tr>
<td>euler222.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler233.py</td>
<td align='right'> 0.10</td>
<td align='right'> 0.10</td>
<td align='right'> 0.11</td>
<td align='right'> 0.10</td>
</tr>
<tr>
<td>euler234.py</td>
<td align='right'> 5.77</td>
<td align='right'> 6.62</td>
<td align='right'> 7.38</td>
<td align='right'> 7.48</td>
</tr>
<tr>
<td>euler235.py</td>
<td align='right'> 0.20</td>
<td align='right'> 0.20</td>
<td align='right'> 0.42</td>
<td align='right'> 0.20</td>
</tr>
<tr>
<td>euler240.py</td>
<td align='right'>16.17</td>
<td align='right'>14.96</td>
<td align='right'>17.38</td>
<td align='right'>19.59</td>
</tr>
<tr>
<td>total</td>
<td align='right'>409.3</td>
<td align='right'>492.26</td>
<td align='right'>393.54</td>
<td align='right'>593.8</td>
</tr>
<tr>
<td>wins</td>
<td align='right'>77</td>
<td align='right'>48</td>
<td align='right'>67</td>
<td align='right'>45</td>
</tr>
</table>
<p>So all the JITs are faster than CPython for this set of programs, but none is twice as fast.  PyPy has the most wins, but Psyco has the lowest total time.</p>
<p>While PyPy does very well overall, it's an order of magnitude slower than all the others on 3 of the programs: 14, 135, and 174.  If PyPy fixed whatever made those ones slow, it would definitely be the overall leader.</p>
<p>Here's my euler14.py</p>
<pre>
#!/usr/bin/env python

"""Project Euler, problem 14

The following iterative sequence is defined for the set of positive integers:

n -> n / 2 (n is even)
n -> 3n + 1 (n is odd)

Which starting number, under one million, produces the longest chain?
"""

def next_num(num):
    if num &#038; 1:
        return 3 * num + 1
    else:
        return num // 2

MAX_NUM = 1000000

lengths = {1: 0}

def series_length(num):
    global lengths
    if num in lengths:
        return lengths[num]
    else:
        num2 = next_num(num)
        result = 1 + series_length(num2)
        lengths[num] = result
        return result

def main():
    num_with_max_length = 1
    max_length = 0
    for ii in range(1, MAX_NUM):
        length = series_length(ii)
        if length > max_length:
            max_length = length
            num_with_max_length = ii
    print num_with_max_length, max_length

if __name__ == "__main__":
    main()
</pre>
<p>Why is 14 so slow?  My guess would be that it's because it heavily mutates a global dictionary.</p>
<p>Here's euler135.py:</p>
<pre>
#!/usr/bin/env python

"""Project Euler, problem 135

Given the positive integers, x, y, and z, are consecutive terms of an
arithmetic progression, the least value of the positive integer, n, for which
the equation, x**2 - y**2 - z**2 = n, has exactly two solutions is n = 27:

34**2 - 27**2 - 20**2 = 12**2 - 9**2 - 6**2 = 27

It turns out that n = 1155 is the least value which has exactly ten solutions.

How many values of n less than one million have exactly ten distinct solutions?
"""

"""
x**2 - y**2 - z**2 = n
y = z + d
x = z + 2 * d
d > 0
z > 0
(z + 2 d) ** 2 - (z + d) ** 2 - z ** 2 = n
(z**2 + 4dz + 4d**2) - (z**2 + 2dz + d**2) - z**2 = n
z**2 + 4dz + 4d**2 -z**2 - 2dz - d**2 - z**2 = n
-z**2 + 2dz + 3d**2 - n = 0
a = -1
b = 2d
c = 3d**2 - n
z = (-b +/- sqrt(b**2-4ac)) / 2a
z = (-2d +/- sqrt(4d**2+4(3d**2-n))) / -2
z = (-2d +/- sqrt(4d**2+12d**2-4n))) / -2
z = (-2d +/- sqrt(16d**2-4n))) / -2
z = (-2d +/- 2 sqrt(4d**2 - n)) / -2
z = (-d +/-  sqrt(4d**2 - n)) / -1
z = d +/- sqrt(4d**2 - n)
4d**2 - n >= 0
n <= 4d**2
4d**2 - n is a perfect square
"""

def main():
    limit = 1000000
    counts = limit * [0]
    for d in range(1, limit / 4 + 1):
        d24 = d ** 2 * 4
        if d24 < limit:
            start = 1
            counts[d24] += 1
        else:
            start = int((d24 - limit) ** 0.5)
        if start < 1:
            start = 1
        for root in xrange(start, 2 * d):
            n = d24 - root ** 2
            if n <= 0:
                break
            if n < limit:
                z = root + d
                y = z + d
                x = y + d
                #print "n", n, "d", d, "root", root, "x", x, "y", y, "z", z
                #assert x**2 - y**2 - z**2 == n
                counts[n] += 1
                if d > root:
                    z = d - root
                    y = z + d
                    x = y + d
                    #print "n", n, "d", d, "root", root, "x", x, "y", y, "z", z
                    #assert x**2 - y**2 - z**2 == n
                    counts[n] += 1
    total = 0
    assert counts[0] == 0
    for val in counts:
        if val == 10:
            total += 1
    print total

if __name__ == "__main__":
    main()
</pre>
<p>Why is PyPy so slow on this one?  Well, maybe it's because all the work happens in one function, if PyPy doesn't JIT a function while it's still running.  Or maybe it's the list with a million elements in it.</p>
<p>Finally, euler174.py:</p>
<pre>
#!/usr/bin/env python

"""Project Euler, problem 174

We shall define a square lamina to be a square outline with a square "hole" so
that the shape possesses vertical and horizontal symmetry.

Given eight tiles it is possible to form a lamina in only one way: 3x3 square
with a 1x1 hole in the middle. However, using thirty-two tiles it is possible
to form two distinct laminae.

If t represents the number of tiles used, we shall say that t = 8 is type L(1)
and t = 32 is type L(2).

Let N(n) be the number of t <= 1000000 such that t is type L(n); for example,
N(15) = 832.

What is sum(N(n)) for 1 <= n <= 10?
"""

from math import ceil
from collections import defaultdict

def gen_laminae(limit):
    """Yield laminae with up to limit squares, as tuples
    (outer, inner, squares)"""
    for outer in range(3, limit // 4 + 2):
        if outer &#038; 1:
            min_min_inner = 1
        else:
            min_min_inner = 2
        min_inner_squared = outer ** 2 - limit
        if min_inner_squared < 0:
            min_inner = min_min_inner
        else:
            min_inner = max(min_min_inner, int(ceil(min_inner_squared ** 0.5)))
            if outer &#038; 1 != min_inner &#038; 1:
                min_inner += 1
        outer_squared = outer ** 2
        for inner in range(min_inner, outer - 1, 2):
            squares = outer_squared - inner ** 2
            yield (outer, inner, squares)

def main():
    squares_to_count = defaultdict(int)
    for (outer, inner, squares) in gen_laminae(1000000):
        squares_to_count[squares] += 1
    histogram = defaultdict(int)
    for val in squares_to_count.values():
        if val <= 10:
            histogram[val] += 1
    print sum(histogram.values())

if __name__ == "__main__":
    main()
</pre>
<p>Perhaps this one is slow because it heavily uses generators and a defaultdict?</p>
<p>Anyway, I'm not claiming any of these are great programs.  I know others have much better solutions to these problems.  And this code is certainly not optimized for PyPy.  They're just examples of small programs that were originally written for CPython, and do work correctly on PyPy, but happen to be much slower on PyPy than on CPython.</p>
<p>Again, note these are the exceptions not the rule.  PyPy runs most pure-Python code great.  Just not these three programs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=51</wfw:commentRss>
		</item>
		<item>
		<title>W&#038;OD Trail Conditions redux</title>
		<link>http://www.ripton.net/blog/?p=50</link>
		<comments>http://www.ripton.net/blog/?p=50#comments</comments>
		<pubDate>Fri, 26 Feb 2010 12:45:38 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=50</guid>
		<description><![CDATA[They plowed the W&#038;OD Trail!  Woo-hoo!  It's now rideable with a road bike, without studded tires, at least until the next time it snows.  Great job by the park maintenance crews, and thanks to whoever made the decision to finally do this.
And all the fallen trees I saw on Wednesday were gone [...]]]></description>
			<content:encoded><![CDATA[<p>They plowed the W&#038;OD Trail!  Woo-hoo!  It's now rideable with a road bike, without studded tires, at least until the next time it snows.  Great job by the park maintenance crews, and thanks to whoever made the decision to finally do this.</p>
<p>And all the fallen trees I saw on Wednesday were gone by Thursday.  (Well, not quite gone &#8212; you can see what's left of them on the sides of the trail &#8212; but they're not blocking the trail.)</p>
<p>Be careful out there, though &#8212; there will be black ice in the mornings as the melted snow from the sides of the trail refreezes, and there are still some large low-hanging branches.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=50</wfw:commentRss>
		</item>
		<item>
		<title>W&#038;OD Trail Conditions</title>
		<link>http://www.ripton.net/blog/?p=49</link>
		<comments>http://www.ripton.net/blog/?p=49#comments</comments>
		<pubDate>Wed, 24 Feb 2010 15:36:35 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Bicycles]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=49</guid>
		<description><![CDATA[If you somehow haven't heard, the Washington DC area got about 30 inches of snow in early February.  Too much to bike through.  They plowed the big roads, and then the small roads, and then most of the very small roads.  But not the bike paths.
My commute is from Ashburn to Herndon, Virginia.  Exurb to [...]]]></description>
			<content:encoded><![CDATA[<p>If you somehow haven't heard, the Washington DC area got about 30 inches of snow in early February.  Too much to bike through.  They plowed the big roads, and then the small roads, and then most of the very small roads.  But not the bike paths.</p>
<p>My commute is from Ashburn to Herndon, Virginia.  Exurb to outer suburb.  It' s about a mile of nice calm local roads and nine miles of W&amp;OD Trail, each way.  Usually takes me about 35 minutes when there's no snow.  Less with a tailwind or if I'm really trying hard, more with a headwind or if I'm sick or on the mountain bike.</p>
<p>Today, I tried it for the first time since the big snow.  I didn't know what the trail would be like.  I have alternate safe road routes for about 90% of my commute, so if it was really bad I could take roads for most of the way and just walk the bike down the W&amp;OD for the mile between Loudoun County Parkway and Route 28, where there are no bike-safe roads.  (There are two stream crossings there, and no bike-friendly roads bridge them.  Only the W&amp;OD and big high-speed highways like 7, 267, 606, and Waxpool.  267 is a limited access toll road and actually illegal to bike on; the others are unsafe to bike on in my opinion, at least during rush hour with their shoulders unrideable due to piled snow.  So if anyone from VDOT or NVRPA reads this, if you can only afford to plow one mile of the W&amp;OD, it should be that mile.)</p>
<p>Anyway, I took local roads to Wild Meadow, which has a small paved side trail leading to the W&amp;OD.  That side trail was covered with several inches of uneven refreeze, so I walked the bike over it.  But the W&amp;OD in Ashburn was actually plowed!  Awesome.  It was only about 5&#8242; wide, but that was more than enough.</p>
<p>Around the Ashburn Village Road underpass, the trail went from perfectly plowed to doubletrack.  There were two slushy pickup-truck tire tracks, and then a bunch of footprints.  And a mix of snow, slush, ice, crust, black ice, and occasional bare pavement.  This is rideable with skill and studded tires.  I don't have much icebiking skill (it's like mountain biking, with fewer trees to hit but much worse traction), so I had to put a foot down in places, but it wasn't bad.</p>
<p>After crossing Smith's Switch Road, the tree-lined section of trail was plowed, with evidence of much recent tree work.  Looks like some trees fell and blocked the trail there, but the work crews already got out there and cleared them away, and also got rid of some snow while they were at it.  So I stayed on the trail rather than detouring through the adjacent commercial area's parking lots and roads.</p>
<p>The stretch between Loudoun County Parkway and Route 28 was double-track with lots of melted snow, slush, etc. again.  Rideable with studded tires, but not easy.  I was getting hot at this point (it was about 40 degrees, and the mix of low-speed cycling and scootering and pushing the bike that I was doing is hot work and does not provide the cooling headwind of normal cycling) and removed my balaclava.</p>
<p>Once I crossed 28 I could have taken my road detour (Ruritan, Church, W Holly, E Holly, S Lincoln, Crestview, Herndon, Ferndale, Vine, Spring), but I wanted to see how the trail was.  Bad idea.  Just west of Sterling Road, the trail was blocked by several stopped work crew vehicles.  I pushed the bike around and saw that the crew was removing 3 or 4 large fallen trees.  I should have turned around at this point, but pressed on, walking the bike.  Once I got past where they were working, the double-track went away, showing that no vehicles had gone through.  So the snow in this part of the trail was mostly 4-6&#8243; deep refreeze, with footprints and a few refrozen mountain bike tracks but no vehicle tracks.  So I had to mostly walk rather than ride.</p>
<p>I should have turned onto Sterling Road, but I didn't.  Just on the east side of Sterling Road was another large fallen tree that the work crews hadn't reached yet.  I pushed my bike around it.  The next chance to get off the trail (without turning around, which would have been admitting defeat) was at the Oak Grove Baptist Church.  I didn't know where the road there went, but I took it anyway, hoping it hooked up to Crestview.  Nope, it connected to 606, which was crawling with bumper-to-bumper traffic.  I could have ridden in that mess (it's no fun, but the cars are moving slowly enough that it's not that dangerous), but instead I turned around and rode back to the trail.  Then I pushed the bike up to the trail until I reached the largest fallen tree yet, which was big enough that it completely blocked the trail.  I had to climb the snowy embankment on one side to get around it, which would have been slightly annoying even without a bike to push.</p>
<p>That was the last fallen tree until I reached Crestview.  By that point I was hot, tired, and late for work, so I took roads the rest of the way in.  The roads were fine.</p>
<p>Temperatures have been in the 40s lately, so it's all melting.  The parts that are kind of slushy and icy should be clear by the end of the week, if it doesn't snow again.  And the work crews are working on the fallen trees, though I'm not sure how long it'll take them to remove them all.  I recommend taking roads instead of the W&amp;OD through Sterling, at least for a few more days.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=49</wfw:commentRss>
		</item>
		<item>
		<title>PyCon 2010</title>
		<link>http://www.ripton.net/blog/?p=48</link>
		<comments>http://www.ripton.net/blog/?p=48#comments</comments>
		<pubDate>Sun, 21 Feb 2010 17:10:13 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=48</guid>
		<description><![CDATA[PyCon was in Atlanta this year, which got me away from the record snow in the DC area.  Yay for winter conferences being in warm places.  (Nothing against Chicago, but Chicago conferences should be in the summer.)
Attendance was about 1100, a little more than last year, but nothing like the crazy growth PyCon saw when [...]]]></description>
			<content:encoded><![CDATA[<p>PyCon was in Atlanta this year, which got me away from the record snow in the DC area.  Yay for winter conferences being in warm places.  (Nothing against Chicago, but Chicago conferences should be in the summer.)</p>
<p>Attendance was about 1100, a little more than last year, but nothing like the crazy growth PyCon saw when the economy was strong. I think that Python is still growing but travel and recruiting budgets are down.</p>
<p>The best talk I attended was Raymond Hettinger's.  It was about using the right container classes to solve computationally expensive problems.  He pointed out that every ordered dict implementation except the one he just added to Python 3.1 had O(n) deletes due to using a list for storing the order, while his had O(1) deletes because he used a linked list with a dict index.  I hung my head in shame because I've written odict twice (once at a former employer, again from scratch for Slugathon) and done it "wrong" both times.</p>
<p>The most useful thing I attended was the Twisted Open Space.   Because my employer really wants IPv6 in Twisted, and I've submitted a patch but not had it accepted because of reverse compatibility concerns.  Actually talking to most of the core Twisted team at once in person really helped clarify what we need to do to break the logjam and get the patch moving forward again.  That ten minutes probably justified the cost of sending me to PyCon this year.  (And I wish I could go to the sprints and maybe actually get this change into Twisted this week, but I can't.  Next year I really want to go to at least a couple of sprint days.)</p>
<p>Rackspace Cloud was there as a sponsor with a booth, which reminded me that I should have blogged about my experience using Rackspace Cloud.  Basically, they stood up a virtual small Ubuntu (they have other choices too) server for me in about 5 minutes, for about $12 per month (plus bandwidth, more money for more memory), and it just stinking worked.  I've since turned it off because Slugathon isn't done yet so I don't really need a dedicated game server yet, but I'll definitely be back when it is.  The only negative is that there's no way to setup a cap at which the server turns itself off, so if you get Slashdotted or DOS attacked you may get a high bandwidth bill.</p>
<p>Negatives:</p>
<p>Airline travel sucks.  You already know this.</p>
<p>Guido's keynote was just taking questions via Twitter, and the signal-to-noise ratio was awful.  (Yes, I'm an old Angry Unix Guy.  Get off my lawn and take your Twitter and your Facebook and your iPhone with you.)  If Guido doesn't want to do a real keynote, that's fine; why not let someone else have the slot?</p>
<p>I'm no longer in favor of invited talks, because one of them was just content-free pattern metababble that never would have been accepted if the speaker had had to do a proposal.  (But, in fairness, all the other invited talks I attended were excellent.)</p>
<p>There were several talks that I really enjoyed and thought were great fun, but where I didn't really learn anything.  So they validated my existing opinions but didn't stretch my brain at all.  (Larry Hastings actually pointed out before his talk about micro-optimizations that it was just nerd porn and that it would be entertaining but nobody would learn much.  I applaud him for his honesty.)  I guess that's natural when you've been doing something for a long time and have attended the same conference a bunch of times.  I need to attend fewer talks and spend more time just talking to people.</p>
<p>The board game social wasn't as awesome as last year because there wasn't a huge pile of games to pick from.  (I think last year a game store donated some games, and you can't expect that to happen every year.)  So I will bring at least one game next year.</p>
<p>My 7-year-old laptop lost its WiFi connection whenever things got crowded.  The networking people do their best, but 1000 laptops crammed into a small area means the newer stronger ruder WiFi cards will crowd out the older weaker more-polite ones, no matter how many access points there are.  I plugged into a switch when I could, and lived without WiFi when I couldn't.  My laptop is heavy and has poor battery life anyway, so I think it's time to retire it in favor of a netbook.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=48</wfw:commentRss>
		</item>
		<item>
		<title>Moved Slugathon to github</title>
		<link>http://www.ripton.net/blog/?p=47</link>
		<comments>http://www.ripton.net/blog/?p=47#comments</comments>
		<pubDate>Sun, 15 Nov 2009 20:51:49 +0000</pubDate>
		<dc:creator>dripton</dc:creator>
		
		<category><![CDATA[Games]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.ripton.net/blog/?p=47</guid>
		<description><![CDATA[I've been working on Slugathon on-and-off (but mostly off) since 2003.  The bare minimum feature set that I consider necessary to do a serious alpha release is almost done.  (Release early, release often; but if you release before you actually do anything useful you might just leave a bad first impression and scare [...]]]></description>
			<content:encoded><![CDATA[<p>I've been working on Slugathon on-and-off (but mostly off) since 2003.  The bare minimum feature set that I consider necessary to do a serious alpha release is almost done.  (Release early, release often; but if you release before you actually do anything useful you might just leave a bad first impression and scare off your potential users.)  So I've been thinking about installers, and portability to MacOS and Windows, and whether my current hosting solution (svn and Trac provided for free to open source Python projects by <a href="http://webfaction.com">WebFaction</a>; thanks WebFaction) would cut it when I had users and possibly more contributors.</p>
<p>I like Trac, a lot.  I now strongly prefer Git to Subversion.  You can use Git and Trac together with the <a href="http://trac-hacks.org/wiki/GitPlugin">GitTracPlugin</a>, but it's hard to find a host that has it installed.  (<a href="http://sf.net">SourceForge</a>, for example, now offers both Git and Trac, but not together.)  So I decided to go with <a href="http://github.com">github</a>.  They're the most popular Git host, their paid hosting business seems to be solid enough that they're unlikely to go away anytime soon, they offer free hosting for open source projects, and they have a wiki and an issue tracker.</p>
<p>So this morning I experimentally moved everything from Subversion+Trac to github.  I've administered both Svn/Trac and Git/Trac installations at work, so I knew how to do this on a local machine where I had control, but doing things locally is different from doing things on a remote hosting service.</p>
<p>Here's what I did on github:</p>
<p>1. Signed up for an account.  (I've poked around github plenty of times, and cloned other people's repositories there to my local box, but I never needed to register until I actually wanted to move my own repository there.  Which is exactly the way it should work.)</p>
<p>2. Uploaded an ssh key.  I already know ssh so it was just a matter of posting ~/.ssh/id_rsa.pub into a web form.</p>
<p>3. Re-cloned my Subversion repository to my local box, using git-svn, using the &#8211;no-metadata option to remove all the ugly  "git-svn-id" blobs in the log.  I'd done this before when we switched from Subversion to Git at work, but I didn't remember the exact syntax.  Luckily it was right there on Github's help page so I didn't even need to check a Git man page.</p>
<p>4. Uploaded my new local Git repository to Github.</p>
<p>5. Realized that I'd forgotten to use the &#8211;authors-file option to convert the author metadata from Subversion format (bare username) to Git format (firstname lastname email).  Oops, this was also on github's help page but I'd been in too much of a hurry.  I poked around github until I found out how to delete a repository, deleted the one I'd just made, redid the git-svn clone with the missing option, and re-uploaded my repository.</p>
<p>6. Basically cut-and-pasted my wiki pages (there were only 8 of them) from Trac to Github's wiki.  I did a little tweaking to convert formatting from Trac format to the Textile format that Github uses, but didn't obsess about getting every little format perfect.  One thing that github's wiki doesn't support well is images; they let you link to external images, but not post attachments directly into the wiki.  So for now the thumbnail screenshots are there, but they don't link to the larger versions.</p>
<p>7. Manually ported all my Trac tickets to github issues.  I had 62 tickets, 30 closed and 32 open.  Both Trac and the github issue tracker share the same #number format for referring to issues, and I mention ticket numbers inside commit messages, so I thought it was necessary to add all the already-closed issues for historical reasons.  I also changed any references to Subversion commit numbers to Git commit ids inside the issues.  This was an annoying data entry task, but with only 62 tickets it was faster to just do it by hand than to write some awesome Trac to github conversion script.  (Which would require either cooperation from github, or advanced web scraping, since github is a rather fancy web site with JavaScript everywhere.)</p>
<p>8. Changed Slugathon's SourceForge page to point at github rather than WebFaction.  (I'm keeping a SourceForge presence for the project because they offer useful things that Github does not, like project mailing lists.  Also, if SourceForge ever integrates Git and Trac and I become dissatisfied with Github's new and fairly minimal issue tracker, I might move everything to SourceForge.)</p>
<p>9. Changed the main wiki page at WebFaction to point to github, too.  (I will eventually ask WebFaction to delete the project, but first I want to make sure that the move was a good idea.  And give Google enough time to cache the version of the page that shows the redirect to github, so people don't think the project just disappeared.)</p>
<p>10. Created a static web page using the instructions at <a href="http://pages.github.com">pages.github.com</a>.  This feels somewhat redundant with the github wiki, but it gave me a place to park my images.</p>
<p>My conclusion so far: I still like Git a lot more than Subversion.  I like github's wiki and issue tracker less than Trac, but they seem to be good enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ripton.net/blog/?feed=rss2&amp;p=47</wfw:commentRss>
		</item>
	</channel>
</rss>
