Practically perfect chocolate chip cookies, my foot!

Our oven is slowly dying. When we bought the house, the inside glass panel on the oven door had one crack that extended from the top to the bottom of the pane. After I started baking bread, I wanted to get some steam action from the oven. One day, I accidentally dripped a single drop of water onto the open door. Sizzle, sizzle, POP! another crack was added to the pane which now has a triangular shard ready to pop right out if you pressed on it.

This is all in addition to the bad prognosis that the doctor oven gave us last time he visited. The igniter died and we had it replaced. We asked him how much a new window for the door would cost and he said it would not be worth it—just replace the oven. Oh, I almost forgot, when the house was still under the ‘homeowner warranty’, the oven went on the fritz and we had to have the front control panel replaced. The oven light still bugs out on us now and then, but hey, it’s getting old.

Now we are faced with a real dilemma. Do we buy a new oven now or should we wait until we can afford a remodel. I normally wouldn’t bother replacing the oven since it isn’t completely dead yet. But we haven’t been able to bake a decent chocolate chip cookie since we moved here. We really want to say it is the oven’s fault. Then we would have an excuse to get a new oven. But the current remodel plan calls for a double wall oven and a separate gas range, so a new oven just before remodeling the kitchen would be a waste of money.

In the mean time, we have been trying very hard to isolate the problem. We have done everything we can think of to get the cookies to turn out. The problem is that they end up flat and pockmarked on the top. We have tried using butter instead of margarine. We have tried soft butter, butter straight from the fridge, different recipes, varying the cooking temperature and time, a little bit more flour, and even refrigerating the dough. Our great lengths have gone as far as asking our neighbors to use their oven. Of course, theirs was a gas oven too, so gas ovens are somewhat suspect in my head. But the cookies never seem to turn out.

One day I recall reading about some chocolate chip cookie recipe that was supposedly created and tested by Consumer Reports. I figured if it is good enough to pass their quality testing, it should work for me. I searched for this fabled recipe and found The Practically Perfect Chocolate Chip Cookie. I printed it out and figured we could give it a shot. Nothing ventured, nothing gained. As we are following the recipe, we notice that it looks somewhat familiar. Wait a minute… This is the EXACT SAME RECIPE as the Original Nestlé Toll House Chocolate Chip Cookies. The only difference was that the recipe I found was tailored for use with a stand mixer. Harrrumph! The cookies still turned out flat and pockmarked.

We are inches from making up a batch of cookie dough and taking it over to our local Standard TV and Appliance showroom and telling them that the oven that cooks the best cookie will come home with us.

In the mean time, I will just have to settle for another kind of cookie. Oddly enough, only chocolate chip cookies and lemon sugar cookies seem to be affected by our oven this way. I swear it is the oven….

IPv6 regex

I spent too much time today playing with IPv6 stuff that I didn’t have any time to work on my latest time sink, Pyrobox. I will have to write about that some other time.

For now, I wanted to get this out there. I was curious about how easy it was to confirm that a string is a valid IPv6 address. It turns out that it is not so simple, thanks to the “space saving” techniques of zero folding that is used. Here are some examples of IPv6 addresses that are valid:

::                           unspecified address
::1                          localhost
fe80::219:7eff:fe46:6c42     link local address
::00:192.168.10.184          embedded IPv4 address

Yes, those are just some of the variety that was introduced that makes the protocol easier to use from a high level, but harder to implement and use from a low level. I mean, I tell my router to advertise IPv6 addresses and within seconds all the machines on the LAN have configured themselves with globally routable IPv6 addresses. Impressive. Yet so very *not* human friendly. There is no way around it, when you are dealing with 128 bits, it is a lot of data to put in a human readable format. That’s what the 8 sets of quad-byte segments are all about, human readability, but it is still so long, nobody will be able to spout off their IP address like they can with IPv4. Thankfully nameservers should help out with that. But sometimes we will have to deal with IPv6 addresses and I want to know how easy it is to recognize a true address from a fake.

I wrote a little ditty in python to help me conceptualize it. I found several sites that had similar regexes to this Ruby parser. I was somewhat dismayed to find out that while they successfully classify a bunch of the namespace correctly, they also have an infinite set of bad addresses they classify as good. Oops. Time to look at your regex handbook again, folks. To remedy their situation is not so easy though. Here is the python program I wrote that generates a regex:

 import re

def valid_ipv6(addr, debug=False):
	# we will build an array of matches and then join them
	a = []
	# the simplest match in the ipv6 address
	sm = r'[0-9a-f]{1,4}'
	for i in range(1,7):
		a.append(r'A(%s:){1,%d}(:%s){1,%d}Z' % (sm, i, sm, 7-i))
	a.append(r'A((%s:){1,7}|:):Z' % sm)
	a.append(r'A:(:%s){1,7}Z' % sm)
	a.append(r'A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3})Z')
	# support for embedded ipv4 addresses in the lower 32 bits
	ipv4 = r'(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}'
	a.append(r'A((%s:){5}%s:%s)Z' % (sm, sm, ipv4))
	a.append(r'A(%s:){5}:%s:%sZ' % (sm, sm, ipv4))
	for i in range(1,5):
		a.append(r'A(%s:){1,%d}(:%s){1,%d}:%sZ' % (sm, i, sm, 5-i, ipv4))
	a.append(r'A((%s:){1,5}|:):%sZ' % (sm, ipv4))
	a.append(r'A:(:%s){1,5}:%sZ' % (sm, ipv4))
	bigre = "("+")|(".join(a)+")"
	if debug:
		for i in range(len(a)):
			r = re.compile(a[i], re.I)
			if r.search(addr):
				print a[i]
		print "n%s" % bigre
	bigre = re.compile(bigre, re.I)
	return bigre.search(addr) and True

if __name__ == '__main__':
	import sys
	if len(sys.argv) < 2:
		print "usage: %s "%sys.argv[0]
		sys.exit(1)
	
	if valid_ipv6(sys.argv[1], True):
		print "valid"
		sys.exit(0)
	else:
		print "invalid"
		sys.exit(1)

When it runs, it can print out the final regex (which embodies the entire IPv6 address language as far as I can tell). Here is that regex:

(A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}Z)|
(A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}Z)|
(A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}Z)|
(A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}Z)|
(A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}Z)|
(A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}Z)|
(A(([0-9a-f]{1,4}:){1,7}|:):Z)|
(A:(:[0-9a-f]{1,4}){1,7}Z)|
(A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3})Z)|
(A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3})Z)|
(A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)|
(A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)|
(A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)|
(A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)|
(A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)|
(A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)|
(A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}Z)

Yes, I realize that is one big regex (note that the lines should all really be concatenated, but I broke it apart at the | points to make it easier to read). But I think it is more complete and correct than other regexes that google helped me to find. If anyone knows a better way to do this using some regex fu, please let me know.

I have found my struan

About one week after I checked out Peter Reinhart’s Whole Grain Breads book from the library, I decided to start my own wild yeast whole grain sourdough starter. I figured this was some easy business since people have been using wild yeast starters since the beginning of time. Oh, not so, my friends. My first try failed. I am going to point my finger at the vinegar bottle as the culprit. You see, I was trying to follow the ‘Pineapple Juice Method’ but I didn’t have any unsweetened pineapple juice (or sweetened for that matter). The reason for adding the juice in the first place is to raise the acidity level of the mixture so the leuconostoc bacteria won’t take over before the lactobacillus and wild yeast get a good start. I figured one acid was as good as the next and substituted a diluted acetic acid solution for the citric acid solution. After 10 days, all I had was a funny smelling slimy goop. I decided to start over. This time I used diluted lemon juice instead. After about 6 days I had definitely captured some wild yeast.

I nurtured it with care and when it came time to refresh the starter, I figured I could make a loaf of something. I chose a Rye Meteil, which I botched, but it was a good starting place. I think most of all, it helped cement into my head that I need to follow the recipe a little bit better. When it failed, I was a bit discouraged. The bread smelled great, looked fine, but tasted about like cardboard. Even with my ‘sourdough’ starter. I was planning to make it again to see if I could do it any better, but in the mean time, I took a chance and wrote an email to Peter Reinhart asking him if he had any ideas on what could have gone wrong. He responded very quickly with a very positive email saying that one thing I should check is whether or not I left out the salt from the final dough. That is very possible. As for the lack of sourdough flavor, I did not realize that this takes even more time for the starter to develop. Now at about one month old, my starter is just starting to get a rich sour smell and a mild sour flavor. So it may just take some more time. A big thumbs up for Peter. Great book and a great heart to help out a struggling wannabe baker.

The breads I have made out of the Whole Grain Bread book are only getting better. The sweet, almost nutty flavor of the breads is irresistible to me. All I can say is at least they are whole grain, so all the better to gorge myself on. The 100% whole wheat sandwich bread is a favorite, as well as 100% whole wheat bagels, which I tried recently. But so far, I think the most flavorful bread I have made from the book is the Multigrain Struan. Struan is a word derived from Gaelic meaning “the convergence of streams”. The bread’s multigrain recipe was originally made with whatever grains the harvest brought in. By weight, it is about 25% mixed grains. I used brown rice, cracked wheat, polenta and quinoa (my harvest was a half-hour playing in the bulk-foods section of WinCo). In the soaker I also used buttermilk, which really made the soaker have a quite questionable smell, but it turned out to taste terrific in the end. I also used wild yeast sourdough starter instead of the biga. I think I have found my struan. With the wealth of possibilities to change this recipe, it could very well be one tasty loaf after another. I am considering quitting my job and making homemade bread full time for the rest of my life. Much less stressful and much better tasting.

Best darn 100% whole wheat bread ever

I think the title says it all. After having read The Bread Baker’s Apprentice: Mastering the Art of Extraordinary Bread, by Peter Reinhart, I really started making some tasty breads. I have tried the Pain a l’Anciene, the amazing Pizza Napoletana, Foccacia, Pugliese, Anadama bread, and Multi-grain Bread Extraordinaire. They were all very wonderful (and I plan on continuing to make them) but I was left feeling somewhat unfulfilled. For several reasons: I want to eat healthy, and too much white bread is not good for the body; I have more whole grains on hand than white flour and it would be nice to know how to make tastier breads with just the whole grains; people before G.A. Bockler survived without white flour, why can’t I?

I found my answer when bumbling around on Amazon, looking for things to round out my wishlist. I was rating items so Amazon could give me better suggestions of things I might like (which it does a fairly poor job at), when I came across Peter Reinharts’s Whole Grain Breads: New Techniques, Extraordinary Flavor. Wow! Does he ever deliver. I love the science of bread that he puts into his books. Not being a chemist, I think the actual chemistry behind all the reactions in the dough is a little beyond me, bit the deconstruction of the bread, the nitty-gritty how it works is what really intrigues me. I am an engineer. I love to take things apart and see what makes them tick. When things are broken, I want to fix them. I have a deep need to see how the puzzle fits together.

Yesterday I made four loaves of 50-50 wheat/white bread from the recipe that my mother-in-law uses. It is a very tasty recipe that I have been using for the past 5 years. My technique has gotten better and I think the four loaves from yesterday were the most uniform and best tasting loaves I have made from that recipe. But it still bugs me that there is a requirement for 1 1/2 cups of white flour per loaf. I have tried substituting whole wheat flour for the white flour to varying degrees of success, but it never turns out as good as the original recipe. It is always more dense and the flavor isn’t quite right either. I even took the advice of one recipe book that said to use less wheat flour when substituting and also increase the leavening to compensate. But it still wasn’t quite right.

Yesterday was also the day that my time on the library waiting list for “Peter Reinhart’s Whole Grain Breads: New Techniques, Extraordinary Flavor” was up and I got to take it home. Almost before the four loaves of bread were fully cooled (and one half eaten), I had read half the book and started on the first recipe, 100% whole wheat sandwich bread. Almost all the recipes in the book use two pre-doughs, a soaker and a biga. According to the science content in the book, the soaker provides flavor and a good environment for yeast production while the biga provides more flavor and the needed acidity to control the enzymes in the soaker before they do too much of a good thing. Put the two parts together, add a little more yeast for leavening and you have one tasty, tender bread. So today, after the soaker and biga had had plenty of time to do their parts, I finished the single test loaf. I just cannot get over how good that bread was. And that was my first shot at the recipe. Hold on while I drool as I imagine how good it will be after five years of practice….

I will certainly be back with more stories from my time in the kitchen.

MythTV + MediaMVP = Time Shifted Television

I have long been slightly jealous of Darren’s MythTV setup. I kept telling myself that I have enough other projects (a.k.a. kids) to keep myself busy for the next 18 years. Plus, the VCR and TV have always been fine for our needs and up until about a month ago were working fine. The TV has never really been what I would call a great piece of electronic equipment. A great piece of something. But it was free and I can’t argue with that. It still works if not for its slightly discolored screen. The VCR is in the same boat. But it finally did give up the ghost. First it stopped rewinding tapes and then it stopped recording. So I tossed it. But that left us without a way to record Sesame Street. Dun dun dun…

Ever since the invention of the VCR, Americans have loved the ability to watch Time Shifted Television (TST). Two shows you want to watch are always on at the same time. Record one and watch the other; then watch the second show at your leisure. Simple solution. Enter the digital age. Hello TiVo. Thank you, Richard Stallman, for telling it how it is. Goodbye TiVo, hello MythTV. MythTV was created by a guy that didn’t want to have to pay the costly startup fees and crazy monthly fees associated with a commercial Digital Video Recorder (DVR) so he wrote his own software that runs on a personal computer that has a TV tuner card in it. To make things better, he agrees with Richard Stallman and released it under the GPL, which means that everyone and his dog can get it for free, use it, hack it, redistribute it, etc. So that is what I am using. Yeah!

We came very close to choosing TiVo as our DVR. I had plans to buy a basic 80 hour box and add a larger hard drive if we needed it. I also planned on buying the lifetime subscription if we liked the service. I hate monthly fees. They are the bane of my existence. “For less than a dollar a day you can have…” a thirty dollar bill at the end of each month. EVERY MONTH. But I digress. The lifetime subscription was the equivalent of 2 years of service. I figured if we liked TiVo and stuck with it for 2 years, it would be worth our while. But they (the big wigs at TiVo) came up with this grand plan to make more money and wring every last dime out of their users. The spin they put on it was something like “No up-front fees” and something about only slightly higher monthly fees in small print. The idea is that users no longer have to buy a TiVo box — they lease one as part of the 1, 2, or 3 year contract for service. When the contract is over, you can upgrade your box when you renew it. Sounds like a great plan! If you want to pay $20 a month for the rest of your life.

Enter MythTV. (I think I already said that). I figured with TiVo, the startup costs would have been about $400 including the lifetime subscription. So I set out to find parts to fix up one of my old computers to make it a worthy Myth backend (server). I looked at all the shiny boxes that you can put in your entertainment center; the ones that don’t even look like computers and are so silent they make your fridge seem noisy. They cost about 3 times what I was willing to pay. After talking some with Darren, I decided the best way to go was to have a backend with the tuner cards and a big disk drive and a itty-bitty, thin-client frontend that hooks up to the TV. So we bought a Hauppage PVR 500 dual tuner card and a Hauppage MediaMVP for the frontend. Speaking of opensource software, a group of people hacked the MediaMVP software so it can run a program that speaks the MythTV protocol (basically it is a MythTV frontend). The project is MVP Media Center (MVPMC). It is a Linux kernel running a small program. Very cool.

So now we can tell MythTV what we want to watch and decide for ourselves when we want to watch it. Now if only I could keep it running all the time (it seems to segfault now and then…) then all would be well in the Domestic Tranquility Department. 🙂

MauOS makes its public debut

After a request from a friend to see the source for my personal OS toy, I have released the first public version of MauOS. I started MauOS as a way to learn more about the i386 architecture. It turned into quite a fun little project. Even though it doesn’t do much more than switch between two tasks and respond to timer interrupts, it was a lot of fun to delve into the sick minds of the creators of the i386.

As it happens, when I was being interviewed by IBM, they learned of MauOS and the word got out that I am an overachiever. Just because I like to play with the bits of my emulated machine does not make me an overachiever.

MauOS runs well in bochs and sometimes on real hardware if you are that crazy. Have fun and fix it for me. Maybe someday it will take over the world. Downloads are available at the download page.

Linux Laptop Howto

I finally got my IBM T40 to a point that it is very usable and mostly stable. (When I say mostly stable, that means it about half as much as w1nD0w$ does, i.e. once a week or less) OS development/debugging is generally pretty abusive to computers, so I need stability. Anyway, I wrote up a page or two of how I configured my machine and thought I would make it public. Debian GNU/Linux on a IBM T40