Thursday, February 26, 2009

Another day at the office

I was at work.

In the dream, it seemed like I knew I was still working AMPS, but I don't remember thinking it explicitly. How does that work? Maybe I inferred it because the layout of the building was sort of the same except the walls and floors looked sparkling new. In real life, the building was on the demolition list, but they didn't have the funds to tear it down. "Let's move AMPS there!" said some kind soul. Believe it or not, it was a step up from being next door to the laundromat and auto shop.

So I'm at work standing in the hallway by Robert's office that leads outside to the loading area. I see my wife turn the corner off the main hallway. (The connecting hall was much longer in the dream than in the real building.) Soon after, this little skunk comes sauntering behind her. I don't use that as a cliché: it was grinning cartoonishly and had a happy-go-lucky bounce to its step.

I alerted my wife: "Sam!" This startled the skunk. I remember hoping it wouldn't spray, but it lowered its head, stuck its butt in the air, and shot a stream of blackish liquid in a nice upward arc just as an unknown black guy turned the corner. Poor guy: wrong place, wrong time.

Next thing I know, the little critter is chasing me, but I had a plan: I knew I was near a kitchen or break area with two doors close together in a corner — openings in both adjoining walls — and I was going to weave around through the doors to confuse the skunk. This would have been about where Bo's office or the bathroom was, but the real building has no such room.

So I do the weave thing and end up retracing my path down the hall that opened to my office, toward where I was when the dream started. Now a married couple Don and Karen were in the hall holding open large black garbage bags intending to catch the skunk. I ran past them (not sure how: the real hall is narrow), and the skunk ran into one of the bags. They tied up the bag, and Don said something about what to do with it — I can't remember what.

The guy who walked into the stink remarked that he'd been following the skunk, so it must have lost his scent. This made me think of a principle illustrated in an episode of Mr. Wizard's World where he blindfolded a kid, placed a bottle of vinegar under her nose, and told her to say when she thought he'd taken the bottle away. Even though the bottle was still under her nose, she thought he'd removed it. The technical name for this phenomenon is olfactory fatigue.

Monday, February 23, 2009

Scapegoats and the mortgage crisis

When my wife and I were shopping for houses a few years ago, an originator preapproved us for a loan amount so ridiculously high that I knew a mistake must have happened somewhere.

"But you have no debt," the agent insisted.

At this point, I could have patted myself on the back for having arrived, for being a success, for Being Somebody, for having Achieved The American Dream.

I'm sure the agent would have been quite pleased to bank the commission check on such a monster. My family, on the other hand, would have been so house-poor that developing a taste for licking paint off the walls would have become a necessity.

The agent was doing her job. She has zero responsibility for me or my family: that's my job. Had I plunged so deeply into debt, I would have been the fool. I'd have been even more foolish to do so willingly but then turn around and charge "Predatory Lending!"

The same thing happens on car lots. For most people, buying new cars is stupid, and leasing cars even worse. Wise people don't go to car lots seeking financial advice from car salesmen. For good reason: it's not their job! A car salesmen is there to sell you the car you want, regardless of what a lead weight around your neck it'll end up being and the enormous opportunity cost you'll pay.

That cute girl at the office whose marriage is on the rocks and likes to make flirty comments, you could easily throw away your own marriage and your own family over her. Keeping it in your pants is your job, not hers.

Opportunities to screw up royally are everywhere. Children and the incompetent must depend on others to prevent them from making stupid mistakes. It's part of being adults for the rest of us.

Wednesday, February 18, 2009

Scraping data from a program's output

Consider a (truncated) output from vmstat on AIX:
  2031616 memory pages
  1953185 lruable pages
   935166 free pages
        1 memory pools
   170943 pinned pages
     80.0 maxpin percentage
  ...
Say you want to grab the values for memory pages and free pages. Below, I explain a couple of ways to do it.
#! /usr/bin/perl

use warnings;
use strict;

no warnings "exec";

open my $fh, "vmstat -v |"
  or die "$0: can't execute vmstat: $!\n";

my %vmstat;

while () {
  chomp;
  my($n,$desc) = split " ", $_, 2;

  $vmstat{$desc} = $n;
}

print "Memory pages: $vmstat{'memory pages'}\n",
      "Free pages:   $vmstat{'free pages'}\n";
When the filename argument to open ends with a pipe, Perl runs the named command and makes its output available on the returned filehandle. I turn off the autogenerated error (no warnings "exec") because I like my format better.

Looking at vmstat's output, each line has a value and a description, so the plan is to read each line and stash the parameters where we can find them later. A hash is a perfect data structure for this task.

Most of the time, the pattern to the split operator is a regular expression, but with no arguments (or a pattern of a lone space) it acts like awk, throwing away leading whitespace. Because the descriptions contain spaces, we don't want to split on them and tell Perl to give us back exactly two fields. Because we've limited the number of splits, we have to remove the trailing newline with chomp.

The output is straightforward: print the desired values.

You can of course be more clever:

#! /usr/bin/perl

%vmstat = reverse `vmstat -v` =~ /(\S+) (.+)/g;

print "Memory pages: $vmstat{'memory pages'}\n",
      "Free pages:   $vmstat{'free pages'}\n";
Instead of a piped open, this time we use backticks (``) to capture vmstat's output and from the output extract the values and descriptions.

The regular expression \S+ means a sequence of one or more non-whitespace characters, and this matches the numbers in the output. You might be tempted to use \d+ (one or more digits), but this will give you surprising results on the floating-point numbers.

By default, dot does not match newline, so the (.+) subpattern matches through the rest of the current line — the description in this case.

The /g regular-expression switch means we get all possible non-overlapping matches.

The list returned from the match will look like (2031616, "memory pages", 1953185, "lruable pages", ...), but that's the opposite order from hash initialization, i.e., key then value. The reverse operator fixes this problem.

Friday, February 13, 2009

25 random songs

Bo hit me with the 25 random songs meme. Who wants to push buttons when you can write a program?
#! /usr/bin/perl

use warnings;
use strict;

use File::Find;

use constant CHOOSE_N => 25;

@ARGV = "." unless @ARGV;

my @mp3;
my $matches = sub {
  push @mp3 => $File::Find::name
    if /\.mp3$/i;
};

find $matches => @ARGV;

# Fisher-Yates-Knuth
for (my $n = $#mp3; $n >= 1; $n--) {
  my $k = int rand($n+1);
  @mp3[$k,$n] = @mp3[$n,$k];
}

for (1 .. CHOOSE_N) {
  last unless @mp3;
  my $song = shift @mp3;

  # e.g., .../Music/Bob Marley/Kaya/08 - Crisis.mp3
  if ($song =~ m!^.*/([^/]+)/[^/]+/\d+\s+-\s+(.+)\.!) {
    my($artist,$title) = ($1,$2);
    print qq{$_. "$title," $artist\n};
  }
}

The output:
  1. "The End," The Doors
  2. "Misty Morning," Bob Marley
  3. "My Mood Swings," Elvis Costello
  4. "Concerto Emperor: II. Adagio un poco moto," Ludwig van Beethoven
  5. "What's the Matter Here?," 10,000 Maniacs
  6. "Trench Town Rock," Bob Marley
  7. "Final Hour," Lauryn Hill
  8. "These Are Days," 10,000 Maniacs
  9. "Want-Ad Blues," John Lee Hooker
  10. "Loser," Beck
  11. "Sonata Pathétique: II. Adagio cantabile" Ludwig van Beethoven
  12. "Peer Gynt Suite No. 2: Ingrid's Lament," Edvard Grieg
  13. "4 Better or 4 Worse (interlude)," The Pharcyde
  14. "Bonita Applebum," A Tribe Called Quest
  15. "Hard Hearted Woman," John Lee Hooker
  16. "Jeremy," Pearl Jam
  17. "Toccata and Fugue in D minor," Johann Sebastian Bach
  18. "Ya Mama," The Pharcyde
  19. "Pennyroyal Tea," Nirvana
  20. "Concerto in C minor for Violin and Oboe," Johann Sebastian Bach
  21. "Sex Type Thing," Stone Temple Pilots
  22. "Drive," R.E.M.
  23. "People Are Strange," The Doors
  24. "Vivrant Thing - Violator (feat. Q-Tip)," A Tribe Called Quest
  25. "The New Pollution," Beck

Oh Lucy, I'm hooome!

I got home from work and was telling a grandmotherly figure about my day. I said something about an issue with a wiki, and she said it was important to get the thing fixed.

Thinking back, I don't recognize the layout of the house, and I don't recognize the Latino woman who spoke with an accent. I knew her in the dream.

There was some issue about a check she had given at church that day. I assumed she had been to Mass because it was a workday, and she was probably Mexican. (I am not Roman Catholic.) She was on the phone trying to call a woman at her church about it when I got home. She was frazzled because of this and because of a baby somewhere in the house who was calling out unintelligibly. A few times, she raised her voice to be heard and to say she'd be there soon.

As I left the front of the house, I passed by a kitchen on the right where a Latino guy about my age was doing something. Again, I knew him in the dream, but I'm not sure what our relationship was. I thought about saying "Buenos dias" but didn't because I wasn't sure whether the greeting was linguistically appropriate.

Making two left turns, I got to what I assume was my bedroom. I think I emptied my pockets there but don't remember specific items. I could still hear the baby calling, but being closer didn't make it sound any less odd.

I go into the room in the back of the house on the right where the baby was, and he was barely floating face-up in an inflatable pool on the bed. "Oh my God! C----!" I shouted. I did recognize the baby: he was an infantized version, but a big baby, of my friends' son. He was bobbing and made his weird noise when his mouth surfaced. I ran over to him. His face was smurf-blue but not all over, as though his part of his face had been dipped in paint.

I sat him up, and he threw up a couple of times in the water. First a little bit and then a thin-milkshake gusher.

That's when I woke up. As I sat reflecting, I could still hear the baby's noise: something was partially obstructing one of my nostrils, making a faint whistle-wheeze.

Wednesday, February 11, 2009

Playing chess with Maddy

My four-year-old daughter wanted to play against the computer in Chess Titans. Observations:
  • She plays an unorthodox opener: p-h4 and then continuing right-to-left, she advanced pawns one or two spaces (apparently at random).
  • No concept of position.
  • Her understanding of material advantage is better suited for checkers: a few times, she asked, "Do I have more of their people?"
  • Her strategy is better suited for a first-person shooter. A couple of times, I tried to explain that she was making bad trades, but the appeal of capturing was irresistible.
  • Knights on d2 and e2 were highly comforting.
Still, it's a start!

Thursday, February 05, 2009

Kids say the darndest things

This morning on the way to school, my 8-year-old son and I were talking about his spelling words. One was investor, and I asked whether he knew what it meant.

"Is it someone who invents something?"

"No, that's an inventor. Hmm, let's see. Do you know what profit is?"

"Like the guy in Halo?"

Monday, January 19, 2009

With certain unalienable Rights

I have an etymology calendar on my desk, and today's word is freedom. The author makes a serious mistake in writing, "'Liberty' … also means 'free' but in the sense of rights granted rather than any innate quality."

Liberty carries its natural-rights sense as used by enlightenment thinkers such as Locke and Bastiat, viz., government is the servant of free people and not their master.

For a contemporary example, consider Ron Paul who wrote (with emphasis added), "Democracy represented unlimited rule by an omnipotent majority, while a constitutionally limited republic was seen as the best system to preserve liberty. Inalienable individual liberties enshrined in the Bill of Rights would be threatened by the 'excesses of democracy.'"

In 1943, the U.S. supreme court declared, "One's right to life, liberty, and property, to free speech, a free press, freedom of worship and assembly, and other fundamental rights may not be submitted to vote; they depend on the outcome of no elections."

Thomas Jefferson took an even more radical position: "Rightful liberty is unobstructed action according to our will within limits drawn around us by the equal rights of others. I do not add 'within the limits of the law,' because law is often but the tyrant's will, and always so when it violates the rights of the individual."

The tenth amendment to the U.S. constitution (so-called these days) makes plain that the federal government is not the source of the people's rights, and this in turn is consistent with the Declaration's connection of government's just powers to "the consent of the governed."

Thursday, January 15, 2009

They see me rollin': a probability problem

Say you're playing 7-card stud and are dealt rolled-up deuces. If you see the case deuce as someone else's door, what is the probability that you'll bring it in?

In stud high games, the player with the lowest upcard is the bring-in. Suits break ties, with different places using different orders, so let's use bridge order, i.e., clubs, diamonds, hearts, and spades. Deuce of clubs always pays the bring-in.

The search space is small enough to use brute force. Front matter first:

> import Control.Monad
> import qualified System.IO.UTF8 as UTF8
> import Text.Printf
Modeling suits is straightforward:
> data Suit = C | D | H | S deriving (Show, Ord, Eq, Enum)
Haskell's deriving clause saves tedious definitions. For example, making Suit an instance of the Ord typeclass means that clubs are less than diamonds and so on.

We walk through all possibilities and report the probability:

> main = do
>   mapM_ display doors
>   putStrLn $ printf "Hero bringin probability: %.3f%%"
>                     (100.0 * k / n :: Float)

Simulate the deal. Automatically deriving an instance of the Enum typeclass allows us to use shorthand for all suits. From the problem statement, we know our hero will see two deuces, and the others are in the hole. Enumerating all possibilities is trivial with a list comprehension.

>   where doors = deal [C .. S]
>         deal xs = [ (h,v) | h <- xs, v <- xs, h /= v ]

Here we apply the definition of probability: the ratio of the number of times an event occurs with the total number of events:

>         hero  = [1.0 | (h,v) <- doors, h < v ]
>         (k,n) = (sum hero, fromIntegral $ length doors)

Given a pair of hero and villain door cards, pretty-print it to the standard output:

> display (h,v) = UTF8.putStrLn bringin
>   where hv = "Hero: " ++ (suit h) ++ ", Villain: " ++ (suit v)
>         bringin | h < v     = hv ++ " *"
>                 | otherwise = hv
>         suit C = "♣"
>         suit D = "♦"
>         suit H = "♥"
>         suit S = "♠"

Output:

Hero: ♣, Villain: ♦ *
Hero: ♣, Villain: ♥ *
Hero: ♣, Villain: ♠ *
Hero: ♦, Villain: ♣
Hero: ♦, Villain: ♥ *
Hero: ♦, Villain: ♠ *
Hero: ♥, Villain: ♣
Hero: ♥, Villain: ♦
Hero: ♥, Villain: ♠ *
Hero: ♠, Villain: ♣
Hero: ♠, Villain: ♦
Hero: ♠, Villain: ♥
Hero bringin probability: 50.000%

Wednesday, January 14, 2009

Sally's generosity project

When I first heard about Sally's unusual assignment for her functional area, I was standing in the Opry Mills Mall. (They have this great place there called Dave & Buster's — why in the world don't we have one of those in the Huntsvegas geek mecca?)

My cell phone rang, and I saw Jenny was calling. This was just before Christmas, and everyone at work knew I'd gone to Nashville to spend time with friends and family — and also to nearly freeze myself and my progeny to death in our 9° viewing of ice sculptures inspired by How The Grinch Stole Christmas.

I prepared for bad, bad news, but instead she asked the seemingly random question of whether I was still a coordinator for Dave Ramsey's Financial Peace University. "Uh, yeah," I stumbled, "what's up?" She clued me in and said she wanted to give an FPU scholarship. A young couple at our church are engaged to be married soon: the bride-elect also happens to be an Alabama alumna, so I figured that would mean extra warm fuzzies for the benefactress.

The next Monday (that would be December 22 for those scoring at home), Sally gave me a blue envelope with instructions to do a good deed. The only catch was that I had to write about it on my blog. When I got home, I hoped my wife would suggest a great gift, but we had a zillion other gifts flying through our heads trying to get ready for a Christmas trip to her grandmother's. So the task went into the background.

Christmas Eve at her grandmother's is completely nuts. My wife enjoys telling the story of my first ever Christmas Eve with her family. I leaned over to her, eyes no doubt wide with fright, and whispered, "Who are all these people?"

"This is my immediate family!" she proudly declared. Neices and uncles and nephews and aunts and cousins once, twice, and thrice removed. (Being around this sprawling brood is great practice for the aspiring genealogist.) You see, growing up, we didn't have any family in town, so I was used to laid-back, quiet Christmases with my parents and two brothers. Nothing like the loud bazaar over in Florence full of shouts, screeching monkeys, and goods of all sorts.

So maybe I was conserving my mental energy and couldn't spare the cycles Sally's worthy cause deserved.

When we go to Florence, my mother-in-law is great about offering to keep the kids so Sam and I can sneak out for a quiet date. One of our favorite places do go is Dale's, same brand as Dale's sauce you can buy in stores. Wonderful, delicious, scrumptuous steak, and they do everything for you but wipe your mouth when you're done. Order ribs and they even bring you warm wet towels with lemon slices. Well worth the trip, and I detest sitting in a car!

The other is Ricatoni's, an Italian restaurant on Court Street. On the drive over, we'd talked about maybe going there for lunch or dinner but didn't make firm plans. After sufficient recovery from the Christmas Eve piranha tank, cabin fever started to set in, so off we traipsed for my bride to feed her toasted-ravioli jones.

"Let's give a big tip to our waitress," Sam suggested on the way over, and the conspirators proceeded to carry out their plan. The food was outstanding as always. I had the catch, so I forgot for a while that I was six hours inland.

On the way out, I handed our waitress, probably a student at UNA, the bill folder, wished her a merry Christmas, and walked out feeling satisfied body and soul.

Monday, December 29, 2008

Whose rev is it anyway?

Recently a teammate reported an inconsistency between our code and documentation: the cloud altitude in our rain model is supposed to be in units of meters with a default of 3km, but the default in the code was 10.

We checked both snapshots we thought they had, but both were in order. The last time the default changed in the trunk was over a year ago, and that was a change in units (i.e., 3.0 to 3000.0). 'Maybe they changed the code,' I thought but then remembered that the finger-pointing game is an evil at whose very root we must strike!

Principle is great — in principle — but now I had to hunt through more than a hundred tags to clear dB's name. That's a lot of clicky-clicky in the HTTP view. Instead, I could pull copies of rain_model.c from all hundred-plus tags and grep those.

Ugh. There ought to be a quicker way.

Then I remembered importing our Subversion repository into a Git repository using git-svn. With git-grep, searching through all those revisions is straightforward:

$ git grep 'cloud_altitude *= *[^3 ]' \
  `git branch -a | grep tags` -- \
  libs/env/rain_model.c
Joy!

The [^3 ] bit in the search pattern means find a character that's neither a 3 nor a space, the latter being necessary to prevent spuriously matching a space to the left of the value being assigned — effectively asking for all assignments in all tags to cloud_altitude. Not what we want.

Unlike Subversion, Git's operations are almost all local. That means fast! The above search ran in less than a quarter of a second.

Turns out the weird default was our doing after all, from a nearly two-year-old engineering release. Here's to keeping egg off our faces!

Wednesday, December 17, 2008

SEC coaches spoof

Tuesday, December 16, 2008

Elvis + bacon =

Friday, December 05, 2008

Grrr!

My son's basketball team has a game tomorrow at Mount Carmel — tipoff at 3pm, same time as the national championship game. Our people asked the other team to reschedule, but they refused — probably a bunch of bitter Aubies.

Monday, November 17, 2008

Affordable Places to Weather the Downturn

Judged by affordability, property taxes, and job growth, Alabama's Madison County — home to deciBel Research! — tops Forbes magazine's list of places to wait out the coming storm.

Thursday, November 06, 2008

Mr. Obama, tear down this "PATRIOT" act!

Back up the campaign-trail talk about civil liberties with real action: demand that a repeal of this abomination be on your desk no later than the end of your first week in office. Given your party's control of the congress, you are the lone obstacle to blotting out this shameful spot.

If this is not an urgent priority for your administration, then congratulations for conning millions of Americans.

Monday, November 03, 2008

Friday, October 31, 2008

Accountability, one element at a time

At the end of September and beginning of October, the U.S. House of Representatives voted on a proposed bailo"rescue" plan for poorly managed Wall Street firms. HR 3997 was the first vote, and it failed so back to the drawing board! In the words of Rep. Ron Paul of Texas, "It’s amazing, you take a very, very bad bill, appropriating $700 billion, you can’t get enough votes to pass it so you take it back out, you make it much worse and take it up to over $800 billion." The "much worse" version was the one that passed, so the obvious question is which of our public servants made this possible? This post is a literate Haskell program: copy-and-paste it into a file with the extension "lhs" (say, turncoats.lhs) to get a working program! First, a bit of front matter to import libraries that we'll be using.
> {-# LANGUAGE Arrows #-}

> module Main where
> import Control.Monad
> import Data.List (groupBy, intercalate, sort)
> import qualified Data.Map as M
> import System.Environment
> import Text.XML.HXT.Arrow
The House makes available on the web results of recorded votes:
> hr3997 = "http://clerk.house.gov/evs/2008/roll674.xml"
> hr1424 = "http://clerk.house.gov/evs/2008/roll681.xml"
Despite the way they look in your browser, the resources linked above are XML document instances — verify for yourself with View Source — that we can use for a little accountability. The agenda for our program is straightforward: pull the results of the votes, extract the votes from each, and output the flip-floppers. As a bit of lagniappe, we group the principled stalwarts into classes according to how they changed their votes.
> main :: IO ()
> main = do
>   a <- runX $ readDoc hr3997 >>> votes
>   b <- runX $ readDoc hr1424 >>> votes
>   let turncoats = flipFlops a b
>   forM_ (groupBy same (sort turncoats)) $
>     \ xs -> do
>       let (v,v',_) = head xs
>           n = show $ length xs
>       putStrLn $ v ++ " -> " ++ v' ++ ": (" ++ n ++ ")  "
>       putStrLn $ intercalate ", " (map name xs)
>       putStrLn ""
>   where
>     a `same` b = before a == before b && after a == after b
>     before (v,_,_) = v
>     after  (_,v,_) = v
>     name   (_,_,n) = n
>     readDoc = readDocument [(a_tagsoup, "1")]
We'll represent each vote by pairing a representative's name with his yea-or-nay:
> type Name = String
> type Vote = (Name, String)
For a baseline, we use HR 3997 to build a hash table whose keys are representative names and whose values are the corresponding votes. Then for each vote from HR 1424, we compare the latter vote against the former, making note of those members who changed their votes. As the type of flipFlops indicates, the result is a list of tuples of the form (former-vote, latter-vote, rep-name).
> flipFlops :: [Vote] -> [Vote] -> [(String, String, Name)]
> flipFlops before after =
>   let prev = M.fromList before
>   in after >>= ff prev
>   where
In cases where a member did not vote on the earlier issue, lookup produces an error value, which is Nothing inside the Maybe monad. In Haskell, we don't get NullPointerExceptions. The astute reader will note that flipFlops is not fully general: it doesn't report cases where representatives voted on the former question but not the latter.
>     ff prev (name, latter) =
>       case M.lookup name prev of
>         Just former -> if former == latter
>                          then []
>                          else [(former,   latter, name)]
>         _           ->        [("<none>", latter, name)]
These are the bits that worry about slogging through the XML, but XPath makes it straightforward: the expression below says we want all recorded-vote elements, and those are children of the vote-data element, which are children of the rollcall-vote element at the document root.
> votes :: ArrowXml a => a XmlTree Vote
> votes = getXPathTrees "/rollcall-vote/vote-data/recorded-vote" >>>
>   proc rv -> do
>     name <- getName -< rv
>     vote <- getVote -< rv
>     returnA -< (name, normalize vote)
Consider the structure of a recorded-vote element:
<recorded-vote>
    <legislator>Cramer</legislator>
    <vote>Aye</vote>
</recorded-vote>
So for each recorded-vote, we extract the inner-text of the legislator and vote child elements.
>   where
>     getName = getChildren >>>
>               isElem >>> hasName "legislator" >>>
>               xshow getChildren
>     getVote = getChildren >>>
>               isElem >>> hasName "vote" >>>
>               xshow getChildren
Due to supremely lovely irony, yea is not yea nor nay nay in the recorded votes, so we have to normalize.
>     normalize "Yea" = "Y"
>     normalize "Yes" = "Y"
>     normalize "Aye" = "Y"
>     normalize "Nay" = "N"
>     normalize "No"  = "N"
>     normalize v     = v

Finally the output:

N → Y: (58)
Abercrombie, Alexander, Baca, Barrett (SC), Berkley, Biggert, Boustany, Braley (IA), Buchanan, Carson, Cleaver, Coble, Conaway, Cuellar, Cummings, Dent, Edwards (MD), Fallin, Frelinghuysen, Gerlach, Giffords, Green, Al, Hirono, Hoekstra, Jackson (IL), Jackson-Lee (TX), Kilpatrick, Knollenberg, Kuhl (NY), Lee, Lewis (GA), Mitchell, Myrick, Ortiz, Pascrell, Pastor, Ramstad, Ros-Lehtinen, Rush, Schiff, Schmidt, Scott (GA), Shadegg, Shuster, Solis, Sullivan, Sutton, Terry, Thompson (CA), Thornberry, Tiberi, Tierney, Wamp, Watson, Welch (VT), Woolsey, Wu, Yarmuth

Not Voting → Y: (1)
Weller

Y → N: (1)
McDermott

Tuesday, October 07, 2008

Friday, July 04, 2008

What could have been

As Doug Newman put it, "I write this on July 4, when we celebrate the ouster of a 'tyrant' who taxed his subjects at the rate of about three percent."

Today, Gary North wrote, "When Jefferson wrote [the declaration of independence], the British were extracting approximately 1% of national income from the American colonies. For the southern colonies, it may have been 2.5%. If we could somehow get back to the tyranny of Great Britain in 1776, I would be willing to celebrate the Fourth of July with greater enthusiasm. But that would take a revolution."