Monday, December 28, 2009

Antihistamines while Breastfeeding

After scouring the web and coming to the same conclusion, I found this quick chart on Lactation Guidance for Antihistamines: Claritin and Zyrtec should be fairly safe to take.

Some charts, like kellymom, are more generous, but since diphenhydramine can cause drowsiness, it's not the best for baby. I'm going with the more conservative version ...


The best utility software is so transparent in use that you don't even notice you're using it. I'm a fan of OpenMeta tags, so I started using Tagger:

Tagger is a small application for OS X that can be used for quickly adding arbitrary textual [OpenMeta] tags to files.

I only noticed it this morning when I clicked on the "Update available!" button. One of the updates is to use Sparkle for future updates, so I won't even have these minor reminders that I'm using it anymore! So now's the time for a shout-out while I remember. This is such an easy way to tag files ... Between Tagger and OMSavePanel (no, I haven't installed Snow Leopard yet, so I'm not using Save Panel Extender), most of my newly created files are now tagged.

Monday, December 21, 2009

A Calorie Is NOT Just A Calorie

For some lucky people I know (I married one), body weight comes down to a simple calories in-calories out measurement. Myself, I see a big difference in my weight between eating spaghetti (on refined carbs like pasta, my weight goes up no matter what) and eating beans and rice (I can eat lots, but as long as I exercise a little, my weight goes down). So I agree with this post, A Calorie Is NOT Just A Calorie:

You’ve certainly heard “a calorie is just a calorie.” Meaning, if you stick to say, a 1500 calorie per day diet, it doesn’t matter if those calories come from potatoes, salad, or cheeseburgers. Wrong-o!

My addition: if refined carbs make your weight skyrocket, look for diabetic-friendly recipes.

Eat healthy!

Friday, December 4, 2009

LooperNG: no go

I love the feature list for LooperNG:

  • SNMP Trap forwarding, exploding and rewriting (enhancing).
  • Event generation for demos, debugging, troubleshooting etc.
  • Event Enrichment and Escalation.
  • Intelligent routing, re-routing, and processing of events and alerts.
  • Monitoring logfiles, syslog events, intrusion events, etc.
  • Forwarding alert history to databases, logfiles, etc.
  • Centralize alerts in a LooperDB database.

The bitter reality is that the simple configuration we tried at work didn't properly handle its own logfile, and we ended up getting alerts that we were running out filespace in /var (thank goodness logs were partitioned away from the kernel!). The only way to recover space in /var was to quit Looper NG. So as much as I loved the feature list, this is not the software for me to use at work on a production server(s). I'm not even sure how to phrase this as a bug report since I know Dustin Marquess is professional enough not to use software that slams /var. But I know when to move on, especially when I have trap forwarder and I only wanted to explore more powerful alternatives. Test over, not using this software.

Thursday, December 3, 2009

The Engineer

I just took an online personality test, and it says I am INTP or "The Engineer" which I find amusing since my most recent degree is in Engineering, and I self-identify as an engineer. So a large dose of I knew that. The first description worked for me.

INTPs are relatively easy-going and amenable to most anything until their principles are violated, about which they may become outspoken and inflexible. They prefer to return, however, to a reserved albeit benign ambiance, not wishing to make spectacles of themselves.

However, most of the other descriptions made me want to argue with them, so don't trust cheesy short online tests over common sense.

Monday, November 30, 2009

T42 backlight

My T42 has gone from half-display (the left 1/3 of my screen would be black) to display wiggles (hard to read, hard to know exactly where to click; the jiggles were just the external monitor, though) to shorter times after cold boot with b(l)acklight. At first, it seemed like I only had the display problem if I didn't use this laptop continuously, so I thought I thought I had the display stays black after resume problem; you know, back in the days where I had some runtime before the backlight turned off. Right now, I get about one minute of backlight before it turns off and the screen is essentially black unless you squint in a bright room. Sounds like I'm not alone, so I have switched from massive abuse of my xorg.conf to asking the spare parts guy. I hope this new tactic works!

Friday, November 20, 2009

Patience ...

Not that I'm exactly the patient type (having been a happy user of uControl for a long time until OS X offered this keymap), but sometimes good features will come if you wait. Initially I wanted to have CAPS LOCK and CONTROL in the same place on all of my keyboards, and my laptops needed to switch them. (I have muscle memory for many Unix control-key options, and hitting CAPS LOCKS instead can lead to foul language.) Then I put my work MacBook Pro, originally with OS X 10.4, on a KVM with an IBM keyboard, and I needed to switch COMMAND and OPTION. However, this led to another annoyance: if I swapped COMMAND and OPTION for the external keyboard, they were swapped when I took the laptop sans external keyboard to a meeting.

I've been running 10.5 for ages, but I finally paid attention while I was tinkering with the keymap: it now supports per-recognized-keyboard remaps! I know the novelty will wear off soon and I'll forget how much I love this feature unless someone asks me directly, but it's a very welcome feature addition to the welcome feature of keymapping. Sometimes it is the little things that makes long meetings with minimal content not so annoying.

Friday, November 13, 2009

Highlights High Five Magazine

The Highlights High Five magazine is a funny thing ... we gave it Karston as a Christmas present when he was three and a half. At first, he just liked getting something colorful in the mail, but he didn't care about the content. About three months later, it clicked. All of sudden, when his magazine arrived, he was very excited to get to read it and play with it. (Each issue includes an activity to cut out, and Karston is an expert with his safety scissors!) For about six months, it was the best! Then the phone calls to renew started (ugh) at the same time that Karston started plowing through an issue in about five minutes. He can do the puzzles, like find the hidden picture, quickly. He cuts out the activity, but that's also the most fun he has with it. It was worth it for the three months on either side of his fourth birthday, but since the renewal solicitations take more time than he spends with the magazine, we're not going to renew. It was fun while it lasted!

Thursday, November 12, 2009

Taste Test: crispy chocolate bars

Well, I just did the taste test (a convenient by-product of Halloween bringing more candy bars into my house than is normal, and with a greater variety) between Hershey's crisp wafer bars and Kit Kat. Before I tasted them side-by-side, I was sure that I would like the Kit Kat better. It's the classic of the chocolate-coated crisp bar genre, right? Well, crunch-for-crunch, the 100-calorie crisp wafers tasted much better to me.

Friday, November 6, 2009

From the depths of FreeRADIUS

Two pieces of advice on FreeRADIUS.

  1. Keep up with new versions. There are improvements in each version, so don't just copy over the same config files: make those changes in the new files so you keep up with the times.
  2. If you're starting with a fresh install, don't jump in and make changes right away. Test the freshly installed server first to be sure it works. Make a change, then restart the server to be sure it still works. Another change, another restart, another test. Debug mode -XXX is your friend.

And I finally eliminated a FreeRADIUS warning I saw while in debug mode. This warning is very common now because FreeRADIUS has been upgraded internally but not all of the sample files have been tidied up to reflect the improvement (see my recommendations above!). In debug mode, you might see Info: [ldap] WARNING: Deprecated conditional expansion ":-". See "man unlang" for details and man unlang wasn't particularly enlightening on first pass since it wasn't obvious until I read this post by Mr. FreeRADIUS himself where he explains why this change is A Good Thing. The key is to use more percents and more braces. The line that causes the error for ldap is in the modules/ldap file:

filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"

It needs to updated like so:

filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"

This worked to eliminate the warning before I ditched LDAP because it wasn't matching what I needed.

Thursday, October 29, 2009

GFCF Chicken Florentine

1 lb organic baby spinach, rinsed, in a big bowl, with

a minuscule sprinkle of nutmeg on top

microwave for 2 minutes to reduce spinach bulk

1/2 tsp coarse sea salt

dried leaves from a 2-inch stem of rosemary

1/4 tsp coarsely-ground black pepper

pulverize herbs with mortar and pestle

sprinkle herbs over spinach

stir spinach, and watch it shrink

1 small onion, diced

1 cup chicken stock

1/3 cup garbanzo bean flour

mix in a small bowl

microwave for 2 minutes until flour thickens

mix with spinach

spread this spinach mixture in a 9x9 baking pan

1 lb chicken / 2 breasts

top spinach mixture with chicken

bake at 350°F until chicken reaches 165°F, about 20 minutes unless chicken is thick

The last time I made this, my father-in-law (I didn't even know if he liked spinach!) said he loved it, but it needed more spinach. He's from meat-and-potatoes Wisconsin, but he's always had his meat and potatoes with a salad too. So this time I doubled again* the amount of spinach, and I hope this ratio works for us. This recipe as written serves my family: Daddy and Mommy eat all of our spinach, and there's enough chicken to share with our two hungry sons who like chicken but are small enough that they don't need their own serving from this recipe. Plus the boys just think food tastes better when it comes off our plates. No, neither of them eat spinach yet. I loved spinach, even as a small girl, and even more the other dark leafy greens, so I'm not worried yet.

*Almost all meat-and-veggie recipes taste better to me if I double the amount of veggies or halve the amount of meat. I'm pretty sure this recipe has already had at least one doubling, which is why it goes in a baking pan with high sides!

Baked garbanzo flour (mixed with olive oil or chicken stock) is a surprisingly good cheese sauce substitute! It even has protein, and a lot less fat than cheese.

I almost called this recipe "Vegan Chicken Florentine" because it is dairy-free and egg-free, but then I remembered the chicken ... hehe ... oops! But it is GFCF (not that the original had gluten either, but this version is gluten-free and casein-free) so it works around Cale's allergies.

This is an easy make-ahead recipe: I do all of the steps except baking the chicken (sometimes I butterfly it and try to have the chicken breasts "hug" the spinach, but as I said, we like more spinach than you can even pretend to stuff inside the chicken, so the chicken is a topping on a bed of delicious spinach). I take it over to the in-laws, leave the boys to play (Karston said today that he doesn't get to visit Opa and Grammy often enough), go to work, and return to a yummy meal that I know is allergy-safe for me and Cale to eat. Making three dinners tonight (chicken soup for Daddy who has the cold that the boys have, chicken stir-fry for me, and chicken florentine for tomorrow) was a challenge, but at least mine was just combining and heating leftovers.

Come to think of it, I guess that chicken soup was da bomb! Daddy went back for seconds, if not thirds, and this cold has removed his appetite (not that he ever had much). Chicken soup with tiny pastina stars made by a food lover is pretty tasty ... homemade stock + chicken breast + grated carrot + sliced celery + a handful of frozen peas + a few diced onions from the florentine + a sprinkle of adobo seasoning + pastina added at the end so it doesn't get over-cooked, boiled until done. Simple, and good enough for someone who's sick and not hungry to go back for more.


Well, I just tried a Krups coffee grinder to turn flax seeds into flax seed meal, and it works! Fast too! One tablespoon of flax seeds turned into two tablespoons of meal, so that's an easy conversion to remember. I wish I had thought to use when I mixed the spices (coarse sea salt, dried rosemary from my bush, and coarsely ground black pepper) for my chicken florentine by hand with mortar and pestle. If the Krups can pulverize rosemary too, that would be awesome! I bet it can. I like the flavor of rosemary (in moderation), but I don't like finding little sticks of rosemary in my food.

At first I tried to use it like my food processor, where five two-second bursts yield better results than one ten-second burst, but since I want the flax seed finely pulverized, the continuous run (instead of short bursts) is more effective. It's not hard at all to clean with a paper towel either.

Wednesday, October 28, 2009

Hugging the Toilet

This morning I was struck by how some of the ... ah ... college experience does prepare you for life. There's the experience of hugging toilet, as I was doing this morning. Only this time, as a parent, I was hugging my small child with tummy hurting sitting on the toilet to go poop. When he doesn't feel well, he can get a hug anywhere. And all-nighters? That's obvious to anyone who's had a sick kid. And here I thought I had outgrown my days of hugging the toilet!

Monday, October 26, 2009

Ban Short Vertical Pockets!

The (comfy slacker) knit pants I'm wearing today have vertical-entry on-seam pockets. I've got nothing against on-seam pockets, except these are also short, shallow pockets that aren't deep enough. And when I say my pockets aren't deep enough, I mean that my cell phone and my keys have fallen out! Worse yet, I even lost my building-entry badge that I clipped to the pocket because the pockets are so shallow that the bottom of the pocket pushed on the clip until it popped off!

These pants may be comfortable, but I don't think I'll keep them too long, at least not as wear-to-work on meeting-free days.

If these pockets had a horizontal entry, items wouldn't fall out so easily. If these pockets were deeper, again it wouldn't be a problem because the opening would again be above the stuff stored in the pocket. But short vertical pockets are truly dangerous because it's so tempting to use your pockets as, well, pockets to store essential items, and this short-vertical configuration kicks out everything.

Bad, bad pockets.

Saturday, October 24, 2009

kid fonts

At Karston's preschool, the teachers carefully dash out the name for each child to trace on the daily artwork. Tedious! Karston is learning to write his name, and I'd love to build on that at home, but I know I'm not going to draft all this tracing for him when I'm sure there's a font for it ... I found free trace fonts @ with the Print Clearly and Trace fonts. Much better!

Friday, October 23, 2009

Chocolate Chip Oatmeal Cookies

I looked at The Post-Punk Kitchen for a butter or margarine to oil conversion (1/2 cup/1 stick of those to 1/3 cup oil). Also, when I use Ener-G Egg Replacer, I use the whisk attachment on my mixer to whip it into a meringue-like froth before using it, and I've never noticed the chalk-y taste. Another tip is that chocolate chips don't "stick" to oil batters, so use fewer than in the chips-laden original. I also replace brown sugar with slightly less white sugar and a dollop of molasses. So here's what I did:

1 1/2 Tbs Ener-G egg replacer

2 Tbs water

1/2 tsp vanilla extract

whisk into a froth (several minutes)

1/3 cup canola oil

3/4 cup brown sugar


7/8 cup flour

1/2 tsp baking soda

1/2 tsp salt


preheat oven to 325 °F

1 cup oatmeal

mix (batter will now be getting stiff)

1/2 cup (3 oz) chocolate chips



lightly grease cookie sheet

put cookie batter on cookie sheet

bake 8-12 minutes at 325 °F

I either left the cookies in too long (the kids were wild), or I need to drop the temperature to 300 °F for the oil substitution. Or perhaps I should use a combination of apple sauce (to hold moisture) and oil (to transport yummy flavor)? OK, this is still a work in progress, but completely edible as is too. The cookies also wanted to stick to the pan, so I either should have removed them sooner or I should have greased the cookie sheet. But still mighty tasty! These are my favorite cookies ...

Friday, October 16, 2009

MythDora ... Not Yet

Running anaconda, the MythDora system installer - please wait...

/usr/bin/python: error while loading shared libraries: cannot open shared object file: No such file or directory

install exited abnormally [1/1]

disabling swap...

unmounting filesystems...

        /mnt/runtime done

        disabling /dev/loop0 LOOP_CLR_FD failed: 6

        /proc done

        /dev/pts done

        /sys done

        /mnt/stage2 done

sending termination signals...done

sending kill signals...done

you may safely reboot your system

My current theory as to why I can't install MythDora from DVD or CD or LiveCD is that I have bad burns from OS X. Maybe it doesn't set all the right "bootable DVD" signals so that something (including libpython) isn't extracted or mounted at boot. I believe the error message because I can't find libpython when I mount the image in OS X.

The other possible theory is that the hardware I'm using is just that screwy. Linux is strongest on slightly older hardware (so that someone has written the drivers for it), so I asked for a cast-off. This cast-off, it was finally admitted to me, is unwanted because it was not stable as a Windows XP box. I've got another cast-off (same reason, but different-enough hardware to try again) to try.


Thursday, October 15, 2009

Today's Javascript Lessons

Today I learned two tricks for the replace() function in Javascript.

  1. Use $? for the found pattern, and
  2. use (parentheses) within your regular expression if you want to refer to what it matched by $number in the replacement.

I needed the sub-string '.A.' to be zero-padded into '.0A.' instead. However, I wasn't positive enough that the only character that needed zero-padding would be an A, so I wanted to match the general case of any single character between dots.

So that means I could match any single character between dots and give a long-winded message: output = input.replace(/\.(.)\./g, "replace> $& <replace "); or more to the point: output = input.replace(/\.(\w)\./g, ".0$1.");

I can use either '.' (traditional Unix regexp for a single character) or '\w' (PCRE for any non-whitespace character) to match A with my expected input.

Monday, October 12, 2009

Finder Toolbar Links

The Drag a link to Tagger into the Finder toolbar screenshot was driving me nuts because it's not that simple. I dragged, and the link just bounced back to the application. So I tried some keyboard combinations (since the screenshot indicates that it's possible), and sure enough, COMMAND-OPTION is the magic pre-drop key combination! Of course, now I'm used to it in my Finder sidebar, so I don't need it in my toolbar, but it's nice to know I can do that when I want.

Friday, October 9, 2009


So I had some Bob's Red Mill garbanzo flour that includes a recipe for hummus on the back. Starting with finely ground garbanzo flour seems a lot easier than grinding my own chickpeas to the properly smooth texture! I was also tempted by this hummus cracker recipe so something had to happen eventually.

The first time, I scaled down the hummus recipe to make only the 1/2 cup needed for the crackers, and I left out the tahini because I didn't have (or want!) any. What I learned from this batch of hummus answers one of those little mysteries: why is some hummus so amazingly good, and why does the rest taste horrible like dirt? The answer is that cooked garbanzos are tasty, and raw garbanzos are ick ptooey. Cook the mixture again after adding the garbanzo flour, and it improves greatly!

On to the crackers, first time! I used olive oil instead of canola oil. Even adding extra flour, the crackers still were too wet to roll out, but after baking, the clumps tasted pretty good! Worth making again.

The second time I made 1/2 cup hummus from the Bob's recipe much as before, except I put all the liquids (lemon juice and texas pete) in the 1/2 cup measuring cup, and topped it off to 1/2 cup total. I also skipped the olive oil in the hummus this time around (it still tasted mostly ok, suggesting I can skip the tahini and cut back on the olive oil, and still get enjoyable lower-fat hummus), and just added the olive oil for the crackers part of the recipe. This time I had crackers that I could roll out to a uniform thinness before baking on a silicon baking sheet.

The report is still yummy crackers, and more cracker-like with the much drier hummus. I'm inspired to try this with refried beans! I had never considered making my own crackers until Cale had allergies to most commercial crackers, but it's not hard to make these crackers and they taste great! The one drawback (ahem) is that I get some remarkable gas from just two small crackers, so I probably need to cook the garbanzo beans even longer to tone down that effect. Or perhaps this is inherent in the garbanzo flour, although I suspect not since I don't remember gas from the vegan calzones made with it.

1 Tbs lemon juice

1 tsp hot sauce

1/2 cup water less 4 tsp

add lemon juice and Texas Pete to a half-cup measuring cup,

then fill to 1/2-cup with water

2 shakes onion powder

2 shakes adobo seasoning

4 shakes garlic powder

1/4 tsp ground cumin

mix in a bowl, then microwave 1 minute

preheat oven to 325 °F

2 1/2 Tbs garbanzo flour

stir in, then microwave 2 minutes

1/2 cup whole wheat flour

2 Tbs garbanzo flour

mix in

1 1/2 Tbs olive oil

add just enough oil to get mixture to stick together like a dry dough

roll out to 1/8-inch thickness onto a silicon baking sheet

(if too moist to roll, just spread thin, but without holes, with your fingers;

may need to increase cooking time for extra thickness)

gently cut (or dent) crackers with pizza roller

place silicon baking sheet on a cookie sheet for stability

bake in oven until edges look toasted, about 20-25 minutes at 325 °F

when cool enough to handle, snap crackers apart

cool completely, and store in an air-tight container

Thursday, October 8, 2009

Life Without Cable TV ...

I mentioned it again Tuesday, Lifehacker Wednesday ... I can confidently say that replacing a television subscription service with what you can legally view online is no longer in the "early adopter" range. There's still plenty of room to build your own (say if you want HD more than AppleTV), so it's not "commodity" yet either, but the bleeding edge bled elsewhere.

Monday, October 5, 2009

Less TV

So we've been thinking that, for as little as we watch TV, the cable bill is rather high. However, we want HD (but now there's significantly more free HD available), and we need a DVR. I might miss some of the cable channels if I'm sick and at home, but that doesn't happen often enough to plan for it. I think we could watch over-the-air with a side of Netflix and be perfectly happy. However, I'll have to roll a DVR replacement because the children expect their shows now, with fast forward and rewind. (Bill Cosby said parents don't want justice, they want quiet, and we've learned how right he is! If we want to eat breakfast without children climbing all over us, that episode of Super Why or Imagination Movers or Mickey Mouse Clubhouse sounds pretty tempting. If they don't talk to the TV, we turn it off as soon as we inhale our food. Usually, however, they interact with the show and we're not disappointed with the educational opportunity while we eat in peace and quiet.) Super Why is on PBS so we can watch it over-the-air, and Disney has episodes online and seasons on Netflix. It will take some juggling, but I think we can go without cable. I'm planning a gentle, gradual, slow transition, though.

So that means the first piece of hardware is something to send HD signals to a home-grown DVR. I thought this would be very confusing, a wide field of choices, blah blah blah. Well, it isn't. After reading bronzefinger, there's only one choice: the Hauppauge HD PVR. The usual dithering of checking online reviews and trying to imagine which feature set I want is unnecessary without choices. Newegg had the best price, and a rebate that ended that weekend (2 weekends ago), so I just ordered it. We're still getting the hang of using this box, but so far this glacial move away from the glassy medusa has been surprisingly, disturbingly (as in, why didn't we do this sooner?) easy.

Sunday, October 4, 2009

Caramel Apple Cookies

I saw the Caramel Apple cookies at Craft:, and I had to have some! I started with the allergy-friendly Chocolate Oat Cookie Bars recipe at Recipezaar, replaced the milk with orange juice, and replaced the 1 cup of chocolate chips with a generous cup of apples and a scant cup of caramel bits. These bar cookies are really yummy, and they taste appropriately like Fall.

Saturday, October 3, 2009

Breakfast Experiment: Fluffy Pancakes

We wanted pancakes this morning, and I'm still searching for the right vegan recipe to avoid Cale's allergies. I started with the Simple but Perfect Pancake at Recipezaar. To eliminate the eggs, I followed the Post-Punk Kitchen's advice and used 1/2 cup of banana that had been through the food processor (I was trying to make banana ice cream, but discovered that if the banana has been frozen so long that it has lots of ice crystals, the water prevents the desirable ice creamy texture: so I had leftover, defrosted, maple-extract-spiced banana purée to use up). Instead of milk, I used fruit juice (mango, passionfruit, peach, and pear; cleaning out the frig again). I followed the technique, even to beating the "eggs and milk" with a mixer. The banana and fruit juice, despite not having the protein (and allergen!) content of eggs in milk, did froth up a lot! I used the whisk attachment for my mixer, and that may have helped aerate it. Whatever the reason, frothy fruit or Bakewell Cream, the pancakes turned out great! They were thick, fluffy, light, and only very vaguely possibly fruity. No gooey center (and no crispy edges), either. Yum! I didn't add fruit chunks this time since I figured I had already pushed my luck enough by replacing all of the protein and most of the liquid with Cale-safe alternatives.

1/2 cup banana, smooth purée

1 1/4 cup fruit juice

2 tsp vanilla

beat until frothy

3 Tbs canola oil

stir into juice

1 cup all-purpose flour

1/2 cup white wheat flour

1/2 tsp salt

2 tsp baking powder

2 Tbs sugar

sift dry stuff together, then fold in to wet stuff (do not overbeat)

Picking an All-in-One Media Center

I happened across the Telematics Freedom Foundation PDF on FLOSS Media Centers, and the chart in the middle was great! For as little as we watch TV, the cable TV bill is gigantic! So we're considering ditching it (keeping the cable modem of course, but that portion of the bill doesn't feel as outrageous unless you compare it to most of the rest of the developed world where the US loses on bandwidth to households and price per bandwidth), but we like the DVR feature. So we need to replace it with something like TiVo. From the chart, I eliminated Neuros (don't want another set-top box, although it does look cool) and MediaPortal (I don't run servers on Windows). The next filter was that I want to watch and record TV, so that knocked out all but MythTV and Freevo. (Shame; XBMC and its derivatives Plex and Boxee look nice.) Those two have about the same feature sets, but I noticed that Feevo didn't have keyword search in media library; if I go to the trouble of adding keywords (and I do), I want to be able to search those. So it's MythTV.

The easy path is probably one of the bundled versions. Of those, Google search results seem to agree that if you can stand the longer up-front install time, MythDora is the easiest. I shouldn't have to install it too often, and I don't mind walking away from an installer either, so I think I should burn a copy of MythDora to try it out. Bonus is using RHEL at work might transfer to some comfort with RH's Fedora Core too (I hope). I'm keeping LinuxMCE in mind too, in case we want to add that home automation. Since LinuxMCE uses MythTV as well, I don't think it would be a painful transition for us after I install the same libraries and skins, but I suspect that starting there would be unnecessarily complicated.

Finding the right online reference comparing our choices has made all the difference so far. Yay for online!

Thursday, October 1, 2009

CSS for numbered sublists

I ran across a nice piece of CSS to add numbered subitems in an ordered list.

ol { counter-reset: item }

li { display: block }

li:before { content: counters(item, ".") " "; counter-increment: item }

That's pretty simple! You can play around with HTML lists here.

There's also the jQuery route (with example), but it isn't as simple or lightweight, and it isn't recursive.

Sad Information Move

Well, I really want my notes to be accessible, and that means available to Spotlight more and more now, so with some sadness and some help from touch -r, I just migrated the first document from Alepin to Journler.

Alepin's export preserves the hierarchy (the way I wish the document package's internal structure did, #3 on my wishlist), but it doesn't preserve timestamps. So the package structure is flat but with the timestamps I want, and the export structure is hierarchical with a 'now' timestamp. I believe I can fix this!

cd ~/Desktop/Notes\ Exported

find . -name "*.rtf" | grep -v TXT.rtf | tee adjustTimes.txt

find . -name "*.rtfd" | tee -a adjustTimes.txt


while read FILENAME; do echo "${FILENAME}"; ls -l "${FILENAME}"; BASENAME=${FILENAME##*/}; ls -ld "${ORIG}"/"${BASENAME}"*; echo; done < adjustTimes.txt

while read FILENAME; do echo "${FILENAME}"; ls -l "${FILENAME}"; BASENAME=${FILENAME##*/}; ls -ld "${ORIG}"/"${BASENAME}"*; touch -r "${ORIG}"/"${BASENAME}"* "${FILENAME}"; ls -l "${FILENAME}"; echo; done < adjustTimes.txt

rm adjustTimes.txt

Let's decompose that last long while loop. (And take out the touch command the first time you try this yourself!!! Make sure the right files show up, to make sure you won't mind the results!)

while read FILENAME; do (stuff); done < adjustTimes.txt

This is a while loop that puts the entire line, one line at a time from that text file, into the variable FILENAME. This is the iterative engine!

First, display the filename (make sure spaces come through properly escaped) with echo "${FILENAME}". Then show the directory listing with timestamp via ls -l "${FILENAME}": too new.

Since Alepin's package structure is flat, strip off everything in front the last slash; ## is greedy match removal, */ is anything before and including a slash. This should be the rtfd filename inside the Alepin document. However, rich-text-only exports from Alepin are sensibly just RTF. So to look at that timestamp, I need to convert *.rtf to *.rtfd ... or just tack on * to match zero or more characters for ls -ld ~/Documents/stuff/Notes.alpn/"${BASENAME}"*.

If all that checks out when you test it, it's time to move the Alepin timestamps to the Alepin export with touch -r ~/Documents/stuff/Notes.alpn/"${BASENAME}"* "${FILENAME}"! Admire the results with a final directory listing with updated timestamps: ls -l "${FILENAME}" (and a final echo for visual space).Ta-da!

rsync script

I wrote a quick bash script about a month ago to do my daily rsync, but I had a problem that took the quick and easy fun out of the script for several days. What worked on the command line to handle spaces didn't work in the script! The answer was buried in the rsync FAQ:

The [rsync] command line is interpreted by the remote shell and thus the spaces need to arrive on the remote system escaped so that the shell doesn't split such filenames into multiple arguments.

That's the core of the problem, but backslashes didn't seem to help. I went for the ? solution, to match one character that happens to be a space, instead.

Today I discovered that I probably could have stayed with what worked on the command line (but not in the script) if I had used eval on the scripted rsync command.

Tuesday, September 29, 2009

The Perfect Alepin

I think everyone has their own version of the perfect application to store all of those information tidbits. The time before last when I went looking for mine, I picked Alepin. Since it has been sold and hasn't been updated, I had to pick another (Journler), but I still miss the good parts of Alepin. It's easy to dream while your product is in update limbo, so here's my sorted list of enhancements to make Alepin perfect.

  1. Spotlight support. This is a deal-breaker for me. Without Spotlight, I have to launch an application to find my memory. With Spotlight, I just search from the menubar and find any tidbit in any application (with a Spotlight importer).
    • QuickLook makes filtering Spotlight results just that much easier.
  2. I want per-page tags, preferably OpenMeta tags. I suppose the new developers would have to worry about which file systems don't support extended attributes (like Dropbox, SMB mounts ...) so I guess Alepin needs a hidden file for that, making it less clean. Or a warning "Tagging only supported on ..." but that doesn't catch a Finder copy that causes data loss. So they need duplicate tagging, OpenMeta where supported and a per-document-bundle hidden plist. And a method to sync those as needed.
  3. I always wished for the internal structure to match hierarchy, meaning "Show Package Contents" in the Finder would have the same nested folders as Alepin's display, because then I could duplicate page names (Hotels in both the Asheville and Wilmington folders in Travel.alpn), and because then the "recoverability" if an Alepin doc gets corrupt is essentially perfect. All cases were my own fault and easily recovered, but I have had my Alepin documents get corrupted.
    • This could go interesting places, in that Alepin becomes a browser to a folder of RTFD, especially if metadata like tags goes on the file and the safety file can be re-created from the component documents.
    • Add in textutil's ability to convert to rtfd ... this could go many places. I haven't thought this all the way through, especially since it's not how I would use Alepin. I'm happy with its Import and Export (to nested folders that aren't in its internal hierarchy!).
  4. Fix bug where editing a internal component rtfd (using "Show Package Contents" or found because of my tweakings for Spotlight) with TextEdit would cause the whole document.alpn to be corrupt on next launch. Since it showed up in a search, a proper Spotlight importer would help here too; but Alepin would need to be able to open an Alepin document in context to fix it well.
  5. Fix bug where password-protecting an Alepin document on one Mac, copying (well, bbouncer-approved rsync-ing) that document to another Mac and trying to open it would show the corrupt message. Yeah, apparently I can corrupt documents like nobody's business.

I love(d) Alepin, but I need to be able to find and use what I've stored, in a format with easy recoverability from corruption, with solid import and export choices, preferably document-based. I tried (and bought) Circus Ponies, but since then I bought and am using Journler instead because it just feels easier.

Sunday, September 27, 2009

I Miss My Boys

I have an "All Hands" meeting tomorrow, so I just drove home from the coast. I left my boys with Daddy so they could enjoy more time at the coast, another boat ride, maybe play on a sandy beach. I cannot possibly explain how hard it was to leave them behind. The hormonal sense of bereavement was excruciating. I think what I learned is that I can't possibly get divorced. I have no reason to (thank goodness! we all love Daddy!), but even if I did, I couldn't bear to leave my children on a regular basis. It was brutal. For some reason I can go to work in the morning, but this "optional" trip when I came home a day earlier is rough. I wonder if it's because Cale nursed right before I left so all of my "mom hormones" are up.

Wednesday, September 23, 2009

LeapFrog is afraid of beer

Really! The educational company LeapFrog is afraid of beer! I was trying to figure out why neither of us could enter Cale's name in Karston's new Leapster2 (he played with Nadia's in July and picked it up easily). Finally I found the answer from the company, and the example was very helpful ... can't have ALEX because it contains ALE, so that explains why we can't have CALE too. Their workaround works, too. And it got me out of the endless loop of the doggone thing asking me to enter a profile name but not accepting it! We were sure it was a bug, but it really is a "child protection feature" *argh*! In their defense, they are using "a popular third-party filter" and they did document the problem. Another non-bug: you can only delete a name when all three name slots are filled.

Karston's been playing with it for less than a day so far, but he loves it. (And he loved Nadia's all that weekend.) I think it's a flexible (since spanning ages 4-8 covers a lot of changes), expandable (SD slot) learning toy.

Tuesday, September 22, 2009

Root Beer Pancakes

I made a half-batch of Root Beer Pancakes this weekend, with 1/4 cup of mashed banana as the egg substitute. The report is that the griddle needs to be hotter for these pancakes, to get the yummy crispy edges and to avoid a gooey center. Since my root beer was going flat, I added 1/4 teaspoon of baking powder. Cale had to have one as soon as he saw pancakes, and he had to do a lot of blowing. He definitely understands that hot foods need blowing!

1 cup root beer

1/4 cup puréed banana

mix together

2/3 cup all-purpose flour

1/3 cup white wheat flour

1/4 tsp baking powder if the root beer is flat

sift into wet stuff, then stir together without overbeating

This makes a thin batter that needs to be on a hotter griddle than most pancakes. Then it makes somewhat thin pancakes with tasty crispy edges and soft middle. The root beer flavor came through (as did the baking powder, barely), so I need to adjust it for perfection ... like maybe using regular beer that isn't flat so I can skip the baking powder.

Monday, September 21, 2009

Stevia In The Raw: I should've known better

I decided to try stevia as a sugar substitue, just to see. I bought a small box of Stevia In The Raw to see how it tasted. The problem with most artificial sweeteners, all except Splenda so far as I know, taste like rotten lemons to me. Not just not sweet, but sour gone bad! Yuck! Well, Stevia in the Raw, and presumably all stevia, hits another one of my taste bud quirks: I strongly dislike the taste of anise, the flavoring of black licorise. We had anise plants when I was growing up (it looks like dill, and like dill, grows like a weed), and even the plant and seeds smelled fake to me. Anise just strikes my tongue as wrong, fake, weird, icky sweet. So if I had read the box that says they've removed the licorise aftertaste, I would have known that it's not possible to remove enough of that aftertaste for me.

Luckily, since I dislike throwing away food, the taste is masked in my granola. I use two packets of Stevia in the Raw instead of six Tablespoons of brown sugar. With the other yummy flavors and three cups of oats, I don't taste licorice. So I can use it up, and not do that again.

Friday, September 18, 2009

What I Learned Today

It's a little thing that comes from trying to wing it and not having a reference book, but I learned that Javascript's setTimeout is a delay before the command the relevant command, not after. For some reason I wanted it to be the sort of timeout that means to bail out of starting that process if you don't complete it within the time interval. It's not. It means run that command after a delay of this many milliseconds which is a different creature entirely.

setTimeout(thatCommand, this)


Once again, the local "co-op" grocery store (yes, the one that's usually about $1 per item more expensive than Whole Foods for the things I get) is cheaper than the presumably cheap grocery store. Years ago, Mary and I compared Quaker Oats from Food Lion to bulk oats from Weaver Street, and WS was about half the cost per pound. This time I compared the per-pound prices of dry roasted peanuts and walnuts: $2.98 and $5.24 at Wal-Mart, $2.49 and $4.99 at Weaver Street. So don't assume too much ...

Wednesday, September 16, 2009

Not an Intruder

So yesterday evening, hubby tells me that a house down the street was broken into last week during the day. I was just playing with Cale in the living room when I heard some thumps from the other end of the house. Whoops! Time to investigate! Since I was on the side of the house with all the doors, I wasn't too alarmed since it would be hard to get in my house right now without me noticing. But, ah, it was still time to investigate heavy mystery thumps. It turns out that Cale had turned on Roomba who is quite creative at getting stuck in unusual places. Roomba can escape the normal obstacles, but in this case had rather noisily climbed inside the sturdy metal circular base of the nursing rocking chair ... a regular Roomba prison!

Opt-out of Time-Warner/RoadRunner's DNS Hijacking

I am opposed to ISP DNS Hijacking for many reasons (DNS needs to be trustworthy, DNS needs to follow the RFC standard and return "Not Found" as specified especially since my browser would then tack on ".com" for me, I already pay TWRR more money for less bandwidth than most other developed nations so I resent this standards-breaking monetization), but luckily today I found the opt-out page. Thankfully it's easier and less intrusive than Comcast's opt-out.

A bright spot on a rainy day!

I was about to use the hosts file, like this tip. The bazooka approach would be to download this impressive ad-blocking hosts file and add to it.

Tuesday, September 15, 2009

Debugging Expect programs

So far, the best way to debug Expect programs seems to be to append " -d" the #! line. The output is confusingly verbose, but if I work through it one glob at a time, I can usually figure out what's going on.

Right now, it's that it's matching too early. So I think sleep 5 may be the needed breather.

PBworks migration

It was a good ride while it lasted (I was an early adopter), but it was time to move off the PBworks (formerly pbwiki) boat. My site was hard to read on my iPod touch, and the new 2.0 migration took away my ability to edit from my touch. I do most of my "personal" web browsing from my touch while Cale is nursing, but I don't do it often enough to want to pay for that feature. (I'm not fond of the 2.0 look either. I prefer simple. I think I'll be happy, possibly happier, with jottit, simpler than a wiki, and wikidot, so customizable and lovely page tags with a flying tag cloud, instead.) I decided that a lot of what I had in pbwiki didn't need to be online, so I decided to move it to Journler. I wish it were Alepin, but I want tags and Spotlight.

First I downloaded all of my files from my site (fill in your workspace name). I noticed that the zip file preserved the file modification times! Bonus!

I didn't like how Journler imported HTML (as an attachment to an otherwise-empty entry), though, so I decided to convert to RTF instead. I was sure it had to be easy on OS X, so after discarding non-simple Google results, I found textutil! Score!

I opened Terminal, and changed to the directory of my HTML files.

textutil -convert rtf *.html

mkdir rtfdir

mv *.rtf rtfdir

That was a nice start, but I lost the timestamps! I was sure I could keep those, and I know touch modifies timestamps ...

cd rtfdir

for filebase in $(ls *.rtf | sed 's/\.rtf$//g'); do touch -r ../$filebase.html $filebase.rtf ; done

Now to import into Journler ... no problem: my data are in the entry (not attached to it), and the timestamps are preserved as creation date! Not a bad piece of command-line tomfoolery to get exactly what I wanted without touching each file by hand. I like textutil!

Don't get me wrong: I think PBworks is a great service, and I don't think anything bad about it. But I know what features I want, and it was time for me to move on for my needs.

Tuesday, September 8, 2009

Anthony Bourdain Told Me So

I went to a nice Italian restaurant for lunch today. I told myself I had to order something other than my usual (rut) this time, and I reminded myself that I've always enjoyed the weekly specials. So when I saw the tuna panino on the weekly specials menu, I ordered it. To be honest, what drew me in was the toppings: arugula and roasted red peppers, one with a kick and the other with the mellow. I love those!

Anthony Bourdain says never to order fish on Monday. Since yesterday was the Labor Day holiday, today is a virtual Monday. And I ordered fish. And I've been going to the bathroom roughly once every other hour ever since lunch. I can hear the I told you so, and if I had remembered the virtual Monday-ness, I wouldn't've done it.

Come to think of it, it's been years since I've been happy with my food order when I've told myself to order something different before I saw the menu. Maybe the lesson is not to fight the rut: if the menu tempts me away from The Usual, I should branch out, but otherwise ... might be safer to play it safe. And I always order taco salad at Mexican restaurants because I want the largest pile of lettuce. (I love salad, mostly for the greens.) Last time I made myself branch out at a Mexican restaurant, I really missed the tall stack of fresh vegetables to lighten the meal.

Friday, September 4, 2009

Little Mysteries

Some days have little mysteries.

I was happy to learn the bash trick ${0##*/} to skip using basename (don't need to add dependencies), and once I learned more about bash substring removal, it made perfect sense. $0 (or ${0}) is the script name, as called, often with leading directory information. You need curly braces for substring removal, so start with ${0}. Use # for stingy prefix matching (the smallest match from the start of the variable), and ## for greedy prefix matching (the largest match). So ##*/ is the largest match of any character than ends with a slash. Since / is the directory separator, that greedy match removes all leading directories from the script name ... same as basename, but should be faster.

OK, so I feel like I've learned something! A small trick, but it weans me from excessive sed and awk too.

Yesterday's neat trick was shoving all of my command-line arguments into an array. Why an array? I kept losing the quotes around a string with spaces (user comment) with unexpected script results. This is why I test my scripts! So I don't have to worry about shift eating the script input, I'm in the habit of storing that input in a variable for safe-keeping; I'm now tinkering with an array for that purpose. (Yes, the implicit shift of getopts can be overridden with OPTIND=1, but $ARGS is immune to other tactics like set too.)

# save the args


# or put the args into an array, space-preserving

typeset -a ARGARRAY=("$@")

The ARGARRAY is great: although I lose the quotes from the command line, the user comment is a single element in the array so it's safe as long as I quote that variable when I use it. But back on the bash string replacement track: using the command-line input argument array, I quickly noticed that the flags starting with a dash (hyphen) disturb some string matching routines. So since I know about greedy string matching now, I thought this should work:

typeset -a UNDASHEDARGARRAY("${@##-}")

It doesn't work. It still doesn't work when I escape the hyphen UDAA=("${@##\-}"); either way, the result is just the same as the stingy removal of UDAA=("${@#\-}"): just the first dash goes away. Phooey.

The only approach I've found that works is to use the substring removal twice in a row.

typeset -a UDAA=("${@##\-}")

UDAA=("${UDAA[@]##\-}") (also works with single octothorpes instead of pairs)

What also works is the overkill of removing all hyphens, leading or trailing or internal, with either

typeset -a ONE=("${@//-}") TWO=("${@//-/}")

However, internal hyphens don't mess up string matching, and might be significant. One or two leading dashes indicate a flag, an option to the command; any other dashes might be useful.

So my little bash mystery today is why these two arrays are the same with --long-flags:

typeset -a FIRST=("${@#-}") SECOND=("${@##-}")

I don't like these mysteries, but I know when it's time to get back to work. I have a work-around, so I'll use it.

UPDATE 14:09: looked at the strip_leading_zero2 () example function in the Advanced Bash-Scripting Guide to strip possible leading zero(s), and came up with a dash-prefix-stripper that works in one operation:

shopt -s extglob

typeset -a UNDASHEDARGARRAY=("${@##+(-)}")

I'll ponder that one, and check extglob before set then unset it after.

Thursday, September 3, 2009

September = Fall

I didn't know the weather was watching the calendar, but just as soon as the calendar flipped over to September, the weather turned into Fall. Usually summer has a long tail, Indian Summer, maybe a fall snap and then summer comes back for a few weeks ... but this looks like Fall is sticking around.

I love fall weather (early fall weather while it's still reasonably warm), but it's always so poignant since I know that cold winter weather is just around the corner. However, winter isn't as much of a drag in our house with a pretty view (I didn't know home location could make that much difference!) and with two kids enjoying it so much!

Monday, August 31, 2009

Packing for Key West

When we went to Key West the last week of June, I packed following the One-Page Checklist.

When we got back, I jotted down the items I wish I had brought along.

  • tea bags (mainly because my mother came along)
  • bug spray -- it's on the checklist, but I didn't pack it since we hadn't needed it for Key West summers before
  • aloe gel for sunburn
  • a bike lock for the double stroller
  • a small package of salad dressing -- it's hard to find allergy-friendly salad dressing, and a small amount from home would have been tastier
  • a very small packet of oil -- I've got these at home, and it would have helped the pan!
  • headphones for iPod to listen on the plane

The irony of that last item is that I packed headphones for the next trip two weeks later, and didn't have any chance to use them: either the kids required too much attention, or I was so exhausted I just wanted to doze.

Most of these items are specific to the travel companions (tea for mother, bike lock for stroller for kids) or to the location (bug spray and aloe for tropical climate, cooking supplies for small kitchen), so I'd have to say the One Bag checklist was great overall!

Tuesday, August 25, 2009

Fish Oil vs Flax Seed Oil

I've seen a number of variations on Fish Oil versus Flax Seed Oil, and I think the most best answer is to use whichever one (or neither, or algae) suits you best. However, looking at this metabolic pathway chart, I agree that

fish oil is a superior source of omega-3's since it is already in an active form upon ingestion.

In fact, that metabolic chart explains both of these "contradictory" results: ALA is the left side with all of the inflammatory agents (hmm, needs COX2 inhibitors), while flax is upper right (fish lower right) with the anti-inflammatory agents.

Sunday, August 23, 2009

Me Time

About two weeks ago, during a rare bout of heartburn (I had it once as a kid for overeating, as an adverse reaction to naproxen, and during most of both pregnancies), I wondered why I had such fond, rosy memories of my pregnancies. I mean, morning sickness kicked in before the fourth week, before the positive pregnancy test even, subsided around the 20th week, and kicked back in once I was really large. Add in the unaccustomed bulk and the every-movement-is-arerobic-exercise from week 24 on, and it's no picnic. I figured it out, though. I relished the free license to be selfish about taking care of myself. Of course I have to eat this, it's the healthiest choice on the menu that doesn't make my stomach churn at the thought. Time to get ready for bed now so that I have time to do my static flexibility stretches to keep me from aching. No, it's not breakfast time yet, I have to do my strength training first!

Post-partum, the rules change to keep the baby happy.

But since I noticed what I liked, I'm making more time for exercise. (I've always preferred healthier food, although I was falling off the wagon for sweet snacks more often before I noticed this.) I like it. I think I'll go stretch now and enjoy my own oasis of luxurious, self-indulgent exercise. I've done this routine before bed so many times, I can't stop yawning for the last third of my static stretches. Great way to take care of myself. I'm headed for the floor!

Saturday, August 22, 2009


And now for an update on allergy-friendly foods. New name ‘tempt’ on the hemp milk, but it still tastes good. However, the nutritional specs seem to have dropped: less protein, more sugar. The Purely Decadent line of coconut milk ice cream tastes great, too! Whole Foods has vegan rella (the cheddar tastes icky but I only ever liked the mildest of mild cheddar ... and the mozzarella flavor is tasty melted), ume plum vinegar (in place of soy sauce), and so many more allergy-friendly choices at 50¢ to $1 cheaper than I had been paying before.

New Toilets

The American Standard Cadet toilet comes in far too many varieties, and I don’t just mean colors. So what we got just works but it seems like it might want to run, and I might need to depress handle a second longer. Now that all of the original toilets in the house have been replaced, I saw Sam's Club has a HET with dual flush for $100! I longed for dual flush, settled for 2:3 HET instead. These seemed expensive even before I saw the no-name model at Sam’s that got a rave review on Amazon, but I would've tried at least one given a chance.

Better Vitamins?

I have a reasonable diet (I love salad!), but as I mentioned yesterday, I love my prenatal multivitamins too. Since I probably get most of my trace minerals in my diet, I prefer that my multivitamin is low in vitamins with accessible toxicity (Vitamin A, I'm looking at you) and low in the heavy metal sort of trace minerals (selenium linked to infertility). I don't like B vitamins from GNC because most of those have thousands of percents over the USRDA, and that sounds like overkill in the unhealthy direction to me. Once again, my "current" brand of prenatals went unavailable, so I've been trying other brands that meet my desire not to do over-do certain items while still bumping up the B's.

The first one I tried was a pretty traditional women's multivitamin. It lacked the slightly higher levels of B vitamins, but there weren't any prenatals at the store. Back to sprue (especially about 30 minutes to an hour after I drink a cola), back to the search. The next one I tried is OneADay Energy, although I wouldn't've bought it if I had noticed then that it has caffeine. (Most of the others that were high on some B vitamins were low on B6 and B12. Which would be one way to test which one helps me!) Although I drank tea for years, coffee gives me sweats and shakes, so "contains the caffeine of about 1 cup of coffee" isn't reassuring. It's even higher on those B vitamins than prenatal multivitamins, so I might alternate days with the standard women's. New discovery! With those B vitamins generally at 200% (but not an unacceptable 6000%), my weight seems to be stabilizing! I was having annoying cyclic weight gain, a little loss, then back to the gain grind. How much I ate didn't seem to affect the cyclic pattern much (so why starve).

Extra B vitamins beyond prenatal multivitamin levels, and (#1) I'm back to being in control of my weight and I like to be in charge of my own destiny, and (#2) for the first time in absolutely years, I'm not facing afternoon doldrums with a severe urge to snack on something sweet! Wow! I can probably learn to live with caffeine for that, but I notice that the OneADay Teen mixtures look similar but without the caffeine. In fact, the only amount I disagree with on those is the Chromium since it can affect appetite too. I think I like the Teen Boy formula best because it's lower in iron and some weeks I average 3x USRDA for iron ... I don't need to take an iron supplement unless I like brittle hair and nails. I even think the RDI for iron is high since, at least for blood hemoglobin, the elemental iron is usually recycled into new hemoglobin: it's a fairly closed cycle for iron in hemoglobin, not much loss. I think iron loss is 20 mg for childbirth, and most other times much lower than that ... so I don't think I need it. I do remember what anemia feels like (that lethargy, particularly in my elbows: my elbows felt weak) and I would know to take moderate levels of iron.

I really like that the US RDI tables are available online because these tables include the suggested upper limit too. There you can see that while the RDI for sodium is 1500 mg (a big drop from the old USRDA values), the suggested upper limit is 2300 mg! I think the old USRDA for sodium was 3500 mg. Yeah. So the suggested limit works out to about 3/4 teaspoon of salt ... per day. Since fruits and veggies contain some natural sodium, it's possible to get enough sodium with very little, if any, added salt.

So I used to think that prenatal multivitamins were the gold standard to balance my body, but I learn new things all the time. This time it seems to be that even a little bit more of those B vitamins is a better thing.


I have had hip bursitis since January 2001, and it hasn’t gone away. The general recommendations are to think about what caused it, and don’t do that any more. Hip bursitis can often be caused by a tight piriformis muscle. Tight muscles respond well to exercise (that doesn’t exacerbate it - listen to your body). I take 500 mg of glucosamine daily for osteoarthritis in my knees; if I stop taking it, my knees start to ache about a week later.

Remote i/o with Expect

Hmm, remote input-output with Expect sounds exactly like where I'll be next week with expect scripts. However, the whole expect buffer concept doesn't sit well with me. I can tell it's powerful, once you grok it, but I'm not there and I doubt I need to get there: I'm good with sed and awk. I understand that the expect buffer holds both sides of the "conversation" without regard for local and remote, and that $expect_out(buffer) contains everything since the last match, but even so, I'm not able to get expect to filter just the way I want to view. On the other hand, I just splatted the whole output to sed and I'm done.

Seductive power tools, these sed and awk. And despite what my co-workers think, I'm not even all that good with them ... but I know how to look up 80% of what I need from sed1line and awk1line.txt, and I glean the rest from Google or from scripts I've already written. (Every once in a while, I'm really clever. The other days, I just refer back to what I did then.) Most of it is actually knowing regular expressions from studying man regexp in my youth. Now I'd probably just use txt2regex instead.

Friday, August 21, 2009

Three Things Women Should Know

I try to tell my girlfriends these.

  • Prenatal vitamins can cure a weekly+ bout of sprue without the suffering of a diagnosis of IBS. I thought I was headed for IBS myself, but prenatal vitamins fixed that when a regular multivitamin didn't. This has worked for me and for two friends who are also professional women with stressful jobs. I note that prenatal vitamins are slightly higher in B vitamins, and I know research studies have shown that stress interferes with the absorption of some B vitamins. So my theory is that stress is blocking some vitamin B absorption (not sure which one or ones) causing the bouts of sprue, but prenatal multivitamins shore up your levels of B. (Yes, IBS is real, but for some women there could be a simple, effective solution. Note that a sample size of three women plus a heuristic argument does not make for good science. No harm in trying either!)
  • Your menstrual cycle could be two days shorter without tampons. I heard this at a women's health seminar. I went to be moral support for a friend so she would go, and it wasn't the touchy-feely blather I was afraid of. The speaker cited research studies, although I haven't been able to find them. So I'll just say my sample size is one plus hearsay of research, but I don't miss those two days one bit.
  • Talc, although it comes in powder form, is still a rock. Talc in the panties has been causally linked to increased infections. If you really want to powder, use a cornstarch one unless you have a yeast infection. Cornstarch is from corn, a food item. Yeast can eat it and thrive. So no powder is best, but the occasional puff of cornstarch baby powder is fine.

These are non-obvious tips that can make life better. Share!

Friday, August 14, 2009

The 8 Most Common Expect Errors

A good place to start my workday of Expect scripting: The 8 most common errors:

  1. Have you mis-spelt a variable name?
  2. Have you mis-spelt a command name?
  3. Have you used a $ when setting a variable, or left one off when using the contents of a variable?
  4. Do your brackets balance?
  5. Have you left spaces in the right places?
  6. Have you added a new line in the middle of a command and forgotten the \ on the end of all lines except the last?
  7. Do you need \ protection on anything?
  8. Have you got () {} or [] mixed up?

I'll keep those in mind.

Thursday, August 13, 2009

The Syncplicity Saga

When my USB thumb drive died, and then its brand new replacement followed it, I looked for an online alternative. I picked Syncplicity because I liked the screen shots: I knew exactly what I would see as a user. I used it to access live copies of my most-used files on both my work and home MacBook Pros. Well, Syncplicity decided to drop Mac support cold at the end of last month. I finally got around to uninstalling it, which was a pain because the directions disappeared out from under me.

If you need 'em, those directions are:

1. Shut Syncplicity down

2. Delete /Applications/

3. Delete /Library/Contextual Menu Items/SyncpCMPlugin.plugin

4. Delete ~/Library/Application Support/Syncplicity

5. Restart your Mac

My first thought while reading those directions was:

1. osascript -e "tell application \"Syncplicity\" to quit"

2. rm -rf /Applications/

3. sudo rm -rf /Library/Contextual\ Menu\ Items/SyncpCMPlugin.plugin

4. rm -rf ~/Library/Application\ Support/Syncplicity

5. osascript -e "tell application \"Finder\" to restart"

so I decided to script it. Since the first and last steps were AppleScript commands, I dabbled around and came up with an AppleScript application to uninstall Syncplicity for the Mac (download).

For alternatives, I picked Dropbox (SugarSync is similar), but if you lean towards backups too then Mozy, iDrive, and are also strong contenders.

The last step, after making sure all my files are current and local, is to cancel my account at Syncplicity. Time to move on!

Tuesday, August 11, 2009

Useful tip

From the inimitable Daring Fireball, how to see if an application is running with AppleScript:

tell application "System Events"

count (every process whose name is "BBEdit")

end tell

I modified that into tell application "System Events" to set syncpRunning to count (every process whose name is "Syncplicity") for my purposes.

Arguing with AppleScript

AppleScript sounds great: it's a high-level language, and the code, done right, can be quite human-readable. That's also the problem ... there are so many cases where "to" and "of" both work, and then you run into a case where it matters. Frustrating! That makes me long for a less-flexible language; if there's only one way to issue the command, look it up, use it, and you're done. Or try to figure out where and why AppleScript is so slippery ...

Anyway, yesterday's quest was to identify special folders, like the Applications folder, without assuming /Applications.

Most of the names of special folders are listed in the AppleScript Language Guide: Commands Reference. Yay! However, some special folders aren't there. You can find that longer list in AppleScript 1-2-3. For instance, I used this line of AppleScript

set removePlugin to (the path to "cmnu" as string) & "SyncpCMPlugin.plugin" as alias

where the path to "cmnu" gives me the path to the user's Contextual Menu Items folder. That's not as readable as I'd like my AppleScript, but there's no human-readable version of the 4-letter code.

Today's challenge is to discover if the Trash is empty or not with AppleScript; I'm not going to cheat and use shell.

I've tried

set trashItems to the count of every item in the trash

set number_of_items to (count (every item of the trash))

set tryThis to count of items in trash

and they don't work.

Oh yeah, here's what I mean about AppleScript being a slippery dog, and natural language failing.

These lines work:

tell application "Finder" to set trashList to (items of trash)

tell application "Finder" to open (the path to the trash folder as alias)

These lines do not work:

tell application "Finder" to set trashList to (items of trash folder) with Can't get every item of trash folder.

tell application "Finder" to open the trash

Since Unix is so good at text manipulation, I find that aspect of AppleScript frustrating, and the Working with Text AppleScript reference useful.

OK, so I have solved today's AppleScript frustration to see if the Trash is empty or full.

set trashList to {""}

set trashFiles to {""}

tell application "Finder" to set trashList to (the items of the trash)

tell application "Finder" to set trashFiles to the name of the items in the trash

set old_delimiters to AppleScript's text item delimiters

set AppleScript's text item delimiters to {", "}

set display_trashFiles to trashFiles as string

set trashCount to the count of trashFiles

if (trashFiles is {}) then

display dialog "There are no items in the Trash." buttons {"OK"} default button 1 with title "Trash Empty" with icon note


display dialog "There are items in the Trash." buttons {"OK"} default button "OK" with title "Trash Not Empty" with icon caution

end if

if trashCount > 1 then

display dialog "There are " & trashCount & " items in the Trash." & return & "list: " & (trashFiles as string) buttons {"OK"} default button "OK" with title "Trash Full" with icon stop

else if trashCount = 1 then

display dialog "There is " & trashCount & " item in the Trash." & return & "list: " & display_trashFiles buttons {"OK"} default button "OK" with title "Trash Full" with icon caution


display dialog "Empty, " & trashCount & " items in the Trash." & return & "list: " & display_trashFiles

end if

set AppleScript's text item delimiters to old_delimiters

tell application "Finder"

display dialog "What would you like to do?" buttons {"Empty Trash", "View Trash", "OK"} default button "Empty Trash" with icon note

if button returned of result is "Empty Trash" then

empty trash

else if button returned of result is "View Trash" then

open the (path to the trash folder as alias)

end if

end tell

That was harder than I expected, but now it's done.

Sunday, August 9, 2009


Just found where that annoying preference was hiding with AppCleaner, since of course Spotlight doesn't want to search there ... even if you don't want to delete an application, what AppCleaner finds when you're frustrated can still be valuable!

Dropbox passes!

Unlike Syncplicity (dropping Mac support, failing most of Backup Bouncer), Dropbox passes Backup Bouncer!

sudo /usr/local/bin/rsync -aAHNX --delete --fileflags /Volumes/Src/ ~/Dropbox/bb/

sudo ./bbouncer verify -d /Volumes/Src/ /Users/hope/Dropbox/bb/

Verifying: basic-permissions ... ok (Critical)

Verifying: timestamps ... ok (Critical)

Verifying: symlinks ... ok (Critical)

Verifying: symlink-ownership ... ok

Verifying: hardlinks ... ok (Important)

Verifying: resource-forks ...

Sub-test: on files ... ok (Critical)

Sub-test: on hardlinked files ... ok (Important)

Verifying: finder-flags ... ok (Critical)

Verifying: finder-locks ... ok

Verifying: creation-date ... ok

Verifying: bsd-flags ... ok

Verifying: extended-attrs ...

Sub-test: on files ... ok (Important)

Sub-test: on directories ... ok (Important)

Sub-test: on symlinks ... ok

Verifying: access-control-lists ...

Sub-test: on files ... ok (Important)

Sub-test: on dirs ... ok (Important)

Verifying: fifo ... ok

Verifying: devices ... ok

Verifying: combo-tests ...

Sub-test: xattrs + rsrc forks ... ok

Sub-test: lots of metadata ... ok

That's a clean slate for rsync 3.0.6 (patched) and for Dropbox (provisionally)! Nice to know Dropbox should keep my OpenMeta tags intact. At work tomorrow, we'll see if Dropbox still passes, on the other end of the Dropbox wormhole; that will be the real test of Dropbox.

UPDATE: Not surprisingly, Dropbox doesn't look as pretty on the other side of the wormhole. It mostly fails everything, so only use it for self-contained files (no extended attributes, no specialized metadata, no resource forks; just timestamps and bsd-flags).

sudo ./bbouncer create-vol Src

./bbouncer create /Volumes/Src

sudo ./bbouncer verify -d /Volumes/Src ~/Dropbox/bb

Verifying: basic-permissions ... FAIL (Critical)

Verifying: timestamps ... ok (Critical)

Verifying: symlinks ... FAIL (Critical)

Verifying: symlink-ownership ... FAIL

Verifying: hardlinks ... FAIL (Important)

Verifying: resource-forks ...

Sub-test: on files ... FAIL (Critical)

Sub-test: on hardlinked files ... FAIL (Important)

Verifying: finder-flags ... FAIL (Critical)

Verifying: finder-locks ... FAIL

Verifying: creation-date ... FAIL

Verifying: bsd-flags ... ok

Verifying: extended-attrs ...

Sub-test: on files ... FAIL (Important)

Sub-test: on directories ... FAIL (Important)

Sub-test: on symlinks ... FAIL

Verifying: access-control-lists ...

Sub-test: on files ... FAIL (Important)

Sub-test: on dirs ... FAIL (Important)

Verifying: fifo ... FAIL

Verifying: devices ... FAIL

Verifying: combo-tests ...

Sub-test: xattrs + rsrc forks ... FAIL

Sub-test: lots of metadata ... FAIL

sudo ./bbouncer verify -d /Volumes/Src ~/Dropbox/bb | grep ok

Verifying: timestamps ... ok (Critical)

Verifying: bsd-flags ... ok

./bbouncer clean /Volumes/Src

./bbouncer clean ~/Dropbox/bb

So ... be careful. On the origin end, your file is fine; on the other end of the wormhole, it might be mangled.

Synology and extended attributes

Past time to run Backup Bouncer on my Synology store-everything plan!

./bbouncer create-vol Src

./bbouncer create /Volumes/Src

sudo /usr/local/bin/rsync -aAHNX --delete --stats /Volumes/Src/ /Volumes/NetworkShare/Dst-rsync1

Number of files: 69

Number of files transferred: 26

sent 4621 bytes received 655 bytes 2110.40 bytes/sec

total size is 365 speedup is 0.07

rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1039) [sender=3.0.6]

sudo ./bbouncer verify -d /Volumes/Src /Volumes/NetworkShare/Dst-rsync1

Verifying: basic-permissions ... FAIL (Critical)

Verifying: timestamps ... stat: ./some-file: stat: No such file or directory

FAIL (Critical)

Verifying: symlinks ... ok (Critical)

Verifying: symlink-ownership ... FAIL

Verifying: hardlinks ... stat: link1: stat: No such file or directory

stat: link2: stat: No such file or directory

stat: link3: stat: No such file or directory

FAIL (Important)

Verifying: resource-forks ...

grep: ./some-file/rsrc: Not a directory

Sub-test: on files ... FAIL (Critical)

Sub-test: on hardlinked files ... FAIL (Important)

Verifying: finder-flags ... ok (Critical)

Verifying: finder-locks ... FAIL

Verifying: creation-date ... ok

Verifying: bsd-flags ... ok

Verifying: extended-attrs ...

Sub-test: on files ... FAIL (Important)

Sub-test: on directories ... FAIL (Important)

Sub-test: on symlinks ... FAIL

Verifying: access-control-lists ...

Sub-test: on files ... FAIL (Important)

Sub-test: on dirs ... FAIL (Important)

Verifying: fifo ... FAIL

Verifying: devices ... FAIL

Verifying: combo-tests ...

Sub-test: xattrs + rsrc forks ... FAIL

Sub-test: lots of metadata ... FAIL

sudo /usr/local/bin/rsync -aAHNX --delete --fileflags --force-change --stats /Volumes/Src/ /Volumes/NetworkShare/Dst-rsync2

Number of files: 69

Number of files transferred: 26

sent 4664 bytes received 655 bytes 2127.60 bytes/sec

total size is 365 speedup is 0.07

rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1039) [sender=3.0.6]

sudo ./bbouncer verify -d /Volumes/Src /Volumes/NetworkShare/Dst-rsync2

Verifying: basic-permissions ... FAIL (Critical)

Verifying: timestamps ... stat: ./some-file: stat: No such file or directory

FAIL (Critical)

Verifying: symlinks ... ok (Critical)

Verifying: symlink-ownership ... FAIL

Verifying: hardlinks ... stat: link1: stat: No such file or directory

stat: link2: stat: No such file or directory

stat: link3: stat: No such file or directory

FAIL (Important)

Verifying: resource-forks ...

grep: ./some-file/rsrc: Not a directory

Sub-test: on files ... FAIL (Critical)

Sub-test: on hardlinked files ... FAIL (Important)

Verifying: finder-flags ... ok (Critical)

Verifying: finder-locks ... ok

Verifying: creation-date ... ok

Verifying: bsd-flags ... ok

Verifying: extended-attrs ...

Sub-test: on files ... FAIL (Important)

Sub-test: on directories ... FAIL (Important)

Sub-test: on symlinks ... FAIL

Verifying: access-control-lists ...

Sub-test: on files ... FAIL (Important)

Sub-test: on dirs ... FAIL (Important)

Verifying: fifo ... FAIL

Verifying: devices ... FAIL

Verifying: combo-tests ...

Sub-test: xattrs + rsrc forks ... FAIL

Sub-test: lots of metadata ... FAIL

One thing to note is that I need --fileflags with rsync to pass the finder-locks test; other than that the two rsync results look the same. Without the errors, those results are:

Verifying: basic-permissions ... FAIL (Critical)

Verifying: timestamps ... FAIL (Critical)

Verifying: symlinks ... ok (Critical)

Verifying: symlink-ownership ... FAIL

Verifying: hardlinks ... FAIL (Important)

Verifying: resource-forks ...

Sub-test: on files ... FAIL (Critical)

Sub-test: on hardlinked files ... FAIL (Important)

Verifying: finder-flags ... ok (Critical)

Verifying: finder-locks ... ok

Verifying: creation-date ... ok

Verifying: bsd-flags ... ok

Verifying: extended-attrs ...

Sub-test: on files ... FAIL (Important)

Sub-test: on directories ... FAIL (Important)

Sub-test: on symlinks ... FAIL

Verifying: access-control-lists ...

Sub-test: on files ... FAIL (Important)

Sub-test: on dirs ... FAIL (Important)

Verifying: fifo ... FAIL

Verifying: devices ... FAIL

Verifying: combo-tests ...

Sub-test: xattrs + rsrc forks ... FAIL

Sub-test: lots of metadata ... FAIL

Or, paring it down to failed tests,

Verifying: basic-permissions ... FAIL (Critical)

Verifying: timestamps ... FAIL (Critical)

Verifying: symlink-ownership ... FAIL

Verifying: hardlinks ... FAIL (Important)

Verifying: resource-forks ...

Sub-test: on files ... FAIL (Critical)

Sub-test: on hardlinked files ... FAIL (Important)

Verifying: extended-attrs ...

Sub-test: on files ... FAIL (Important)

Sub-test: on directories ... FAIL (Important)

Sub-test: on symlinks ... FAIL

Verifying: access-control-lists ...

Sub-test: on files ... FAIL (Important)

Sub-test: on dirs ... FAIL (Important)

Verifying: fifo ... FAIL

Verifying: devices ... FAIL

Verifying: combo-tests ...

Sub-test: xattrs + rsrc forks ... FAIL

Sub-test: lots of metadata ... FAIL

The NetworkShare volume is a Synology RS-407 running an embedded Linux mounted via AFP (AppleShare). The permission problems (and ownership and hardlinks and resource forks and ACLs) might be how it's mounted, but I'm concerned about those extended attributes. Might be time to ask Google and friends ...

Tuesday, August 4, 2009

Endnote v. Zotero

From Thomson Reuters Lawsuit Dismissed blog post at The Quintessence of Ham:

I'm delighted to announce that this morning the Fairfax Circuit Court dismissed the lawsuit filed against Zotero by Thomson Reuters. The lawsuit had claimed that the Center for History and New Media "reverse-engineered" Thomson Reuters’s EndNote software to provide data interoperability between Zotero and EndNote.

I used EndNote at work around 1990 to manage our scientific references. I personally used EndNote in the early 1990s when I scored a free copy for being helpful in the right place at the right time. I loved it for bibliography management and formatting! I thought it could have stored more/better/any notes on each reference to help the writing process, but still very useful. At the same time, I was concerned about the company's ethics. I couldn't put my finger on it, but I wasn't sure I liked the company (I read the EULA). The fact that they filed this lawsuit helps me articulate my hesitation. Why should I be locked in to their format? Thank goodness for the web! You can use Zotero or RefWorks (not free, but I have a site license at work) or CiteULike or Connotea or Memento.

From those choices, I would recommend Zotero because it's very good as a bibliography manager (I don't need to create bibliographies now, so I don't have an opinion on that). It even includes the note taking features I wanted in EndNote years ago! It just makes sense to me to store the notes with the reference; that's what will help you (remember to) make the correct citation.

It's also a great note-taking tool for anything on the web, web notebook, web snapshot archiver, whatever you want to call this category. So you could probably use Zotero instead of another Firefox add-on like ScrapBook+ or even a service like Iterasi.

The beta version has sync. I'm not sure how I would use Zotero's Timeline support (maybe if you track news reports on certain topics?), but Timeline is very cool! Many plugins. It's impressive, and even more impressive that it doesn't feel bloated. [This sounds like a gush. Guess what? I don't use it often, but I'm glad it's there, and when I sync my Profile, I get my Zotero data too.] I guess the real drawback to Zotero is that it requires Firefox and I like Safari and Cruz too.

But my point is, I'm glad the big guy (EndNote, established software with corporate funding) didn't get to take out the little guy (Zotero, university project) this time.