Archive for the ‘Research’ Category

Red-black Trees in Erlang

Tuesday, December 1st, 2009

Working through Chris Okasaki’s “Purely Functional Data Structures“, I found that I couldn’t find an Erlang version of the red-black tree implementation Chris shows on page 28.

The code, also available as a pastie and download (with more comments of mine) .erl and .hrl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
%% redblack.hrl
-record(node, {color, data, left, right}).
 
%% redblack.erl
%% Adapted from Okasaki "Purely Functional Data Structures" p. 28
member(_X, undefined) ->
    false;
member(X, #node{left=A, data=Y}) when X < Y ->
    member(X, A);
member(X, #node{data=Y, right=B}) when X > Y ->
    member(X, B);
member(_X, _S) ->
    true.
 
insert(X, undefined) ->
    #node{color=black, data=X};
insert(X, S) ->
    % to do recursive anonymous functions, pass the created fun in as 2nd parameter
    Ins = fun(undefined, _F) ->
                  #node{color=red, data=Data}; % insert the new data as a red node
             (#node{color=Color, left=A, data=Y, right=B}, F) when X < Y->
                  balance(Color, F(A, F), Y, B);
             (#node{color=Color, left=A, data=Y, right=B}, F) when X > Y->
                  balance(Color, A, Y, F(B, F));
             (Node, _F) ->
                  Node
          end,
    #node{left=A, data=Y, right=B} = Ins(S, Ins),
    #node{color=black, left=A, data=Y, right=B}.
 
%% detect Black->Red->Red Patterns and balance the situation
balance(black, #node{color=red, left=#node{color=red, left=A, data=X, right=B}, data=Y, right=C}, Z, D) ->
    #node{color=red, left=#node{color=black, left=A, data=X, right=B}, data=Y, right=#node{color=black, left=C, data=Z, right=D}};
balance(black, #node{color=red, left=A, data=X, right=#node{color=red, left=B, data=Y, right=C}}, Z, D) ->
    #node{color=red, left=#node{color=black, left=A, data=X, right=B }, data=Y, right=#node{color=black, left=C, data=Z, right=D}};
balance(black, A, X, #node{color=red, left=#node{color=red, left=B, data=Y, right=C}, data=Z, right=D}) ->
    #node{color=red, left=#node{color=black, left=A, data=X, right=B }, data=Y, right=#node{color=black, left=C, data=Z, right=D}};
balance(black, A, X, #node{color=red, left=B, data=Y, right=#node{color=red, left=C, data=Z, right=D}}) ->
    #node{color=red, left=#node{color=black, left=A, data=X, right=B }, data=Y, right=#node{color=black, left=C, data=Z, right=D}};
balance(Color, Left, Data, Right) ->
    #node{color=Color, left=Left, data=Data, right=Right}.

So, I’m going to go through this, mainly to prove to myself that I kinda get it, and because Ben will complain I didn’t dumb it down enough for him.

Line 2 defines the node structure in an Erlang header file. Comparable to a struct in C.

Member

Lines 6-13 define the member function. Each member() -> … is a function clause, essentially a case statement on steroids. The first clause says if the tree is undefined, then whatever X is, it is not a member of undefined, so return false.
The second clause unpacks the current node ( #node{left=A, data=Y} ) and assigns the values of left and data to A and Y, respectively (I have tried to maintain Chris’s variable names as much as possible, though I think Erlang’s record syntax complements the Standard ML syntax found in the book). The clause then compares Y, the node’s data, to the query X, and if X < Y, checks the left branch (the variable A) of the node.
The third clause is nearly identical, except it handles when X > Y, and checks the right branch (B) for X’s existence.
The fourth and final clause handles a match (because when X is not greater than or less than Y, it must be equal), returning true. Simple enough to follow and grok.

Insertion

When I read several different articles online concerning red-black trees, the insertion routine sounded quite complex to me. I was quite pleased when I read the algorithm in the book, as it crystallized my thoughts and allowed me to grok the action.

The first clause of the insert function handles the empty (or undefined) tree, creating and returning a black node (since the root of the tree must be black).
The second clause takes the new data X and a tree S and creates a new function, stored in the var Ins. Now, calling an anonymous function recursively is tricky, and I will explain why this part varies slightly from the text. Since there’s no way to refer to the function (as it isn’t named), we have to pass the anonymous function as a second parameter to the anonymous function, which is what happens on line 28. So when you see F(A, F), mentally think Ins(A).
The first parameter to Ins() is our current node in the tree. If it is undefined, we insert our new data as a red node. Why? That is discussed at length elsewhere, but it boils down to being easier to fix a red violation than a black violation (look up the constraints a red-black tree has on it, and the violations will make more sense).
The second clause unpacks the node and makes our less than/greater than comparison like a normal BST. What’s different is that we call the appropriate recursive insert call (remember F(A, F)? This inserts X somewhere into the left side of Node, and F(B, F) inserts X somewhere into the right side), and pass the result to the balance function.
The final clause handles a match between X and Y and returns the Node and its branches unmodified.

Balance

Why do we need a balance function? In case our data being inserted into the tree is more ordered than we may have expected. A vanilla BST with inputs [3,2,1] will be a glorified list. We force the situation by inserting a red node in the tree and causing a situation where the parent of the newly inserted red node is also a red node. This violates the constraint that a red node’s children must be black nodes. There are four possible combinations of this violation:

  1. (B)-Left->(Red)-Left->(Red)
  2. (B)-Left->(Red)-Right->(Red)
  3. (B)-Right->(Red)-Left->(Red)
  4. (B)-Right->(Red)-Right->(Red)

Each of those possibilities maps to the first four clauses of the balance function. The fifth clause passes a node back unchanged. So let’s look at the first clause. This clause is activated when a black node’s left child is red, and that red node’s left child is also red.

      B3
     /   \
   R2     *
  /   \
R1     *

So we unpack the three nodes and return the three nodes rotated to remove the red violation.

Variable Meaning Value
A R1′s Left node undefined
X R1′s Data 1
B R1′s Right node undefined
Y R2′s Data R2
C R2′s Right node undefined
Z B3′s Data 3
D B3′s Right node undefined

Unpacking from the pattern match, we then pack up a new tree structure according to the clause’s definition:

33
#node{color=red, left=#node{color=black, left=A, data=X, right=B}, data=Y, right=#node{color=black, left=C, data=Z, right=D}};

This essentially replaces the black node having a red child and red grandchild with a red node that has two black nodes for children. The next illustration shows the result of the balance call:

      R2
     /   \
   B1    B3

Now, the bubbling up of the red node may cause a red violation with the parent and grandparent of R2, which will be handled as the recursion of Ins() unwinds.

When the initial Ins() ends (line 28), the resulting node is the root of the new tree, which we then unpack into the data, left, and right fields. We then force the root node to be black by creating the root node with the unpacked parts, forcing color=black.

So there you have it. Simplified, with a lot of things glossed over/ignored, but this is my port of the red-black code listing on page 28. Looking forward to progressing through the book more and increasing my data structure- and Erlang-fu.

Further fun: Read Chris’s reflections 10 years after publishing his book.

Symfony/Propel Memory Issues

Tuesday, October 6th, 2009

I have a bulk import process that needs running nightly. Currently there are around 4,200 “rows” to process, which actually can encompass many tables so row is not entirely appropriate. The problem is that the script poops out after ~200 “rows” with memory limit errors. While increasing the memory limit is do-able, I am not interested in that as a solution currently.

First, I recorded some numbers to benchmark where the script was in memory consumption. The first number is the “row”, the peak is how much memory the script has allocated, and the mem is the delta in memory allocation per row.

0 peak: 41,103,408 mem: 29,884,416
1 peak: 42,440,264 mem: 1,310,720
2 peak: 43,613,848 mem: 1,310,720
3 peak: 43,893,960 mem: 262,144
4 peak: 44,223,040 mem: 262,144
5 peak: 44,896,296 mem: 786,432
6 peak: 45,671,560 mem: 786,432
7 peak: 45,865,952 mem: 0
8 peak: 46,418,272 mem: 786,432
9 peak: 47,917,888 mem: 1,310,720
10 peak: 48,566,312 mem: 786,432

After the initialization phase, memory allocation increases fairly steadily and it is not long until the 128M memory limit is reached. This is unacceptable as I know some “rows” should be much closer to 0 as nothing is imported on the majority of rows.

My first solution was to disable logging:

sfConfig::set('sf_logging_enabled', FALSE);

The initial memory allocation was decreased, but the running deltas remained higher than expected.

Second, I inserted a ton of unset() calls in the various functions. This dropped my deltas a little:

0 peak: 30,611,472 mem: 20,971,520
1 peak: 31,969,760 mem: 1,310,720
2 peak: 32,180,112 mem: 262,144
3 peak: 32,333,216 mem: 262,144
4 peak: 32,525,144 mem: 262,144
5 peak: 32,656,616 mem: 0
6 peak: 32,863,736 mem: 262,144
7 peak: 33,103,264 mem: 262,144
8 peak: 33,455,544 mem: 262,144
9 peak: 33,754,288 mem: 262,144
10 peak: 33,984,976 mem: 262,144

But allocation still killed the import before it could complete. Browsing through various sites, I discovered Propel had a hard time cleaning up circular references, which meant PHP couldn’t garbage-collect that memory. However, to combat this, Propel 1.3 offers a static method disableInstancePooling that allowed me to override Propel’s desire to keep instances around.

Adding:

Propel::disableInstancePooling();

to the beginning of the import gave me these results:

0 peak: 26,569,632 mem: 17,301,504
1 peak: 28,582,152 mem: 2,097,152
2 peak: 30,455,352 mem: 1,835,008
3 peak: 30,536,176 mem: 0
4 peak: 30,536,176 mem: 0
5 peak: 31,517,088 mem: 1,048,576
6 peak: 31,534,152 mem: 0
7 peak: 31,552,120 mem: 0
8 peak: 31,589,632 mem: 0
9 peak: 31,695,504 mem: 0
10 peak: 31,695,504 mem: 0

Now new memory was allocating only when the import was actually doing something of significance. In fact, watching the import proceed with the deltas displayed, I could observe the memory decreasing at times, prolonging the life of the script by orders of magnitude. Whereas before the script was processing ~200 “rows”, it currently processes the whole batch (4,237 “rows” currently) in one go.

As the importable “rows” increase, I know I won’t be butting up against memory limits for some time.

iwlagn: Microcode SW error detected. Restarting 0×82000000.

Saturday, August 22nd, 2009

If you have gotten the above error in your syslog, you probably are not able to connect to wireless APs that require WPA passphrases, but can connect to ones that require WEP or no security. While searching for solutions, there were some that offered solutions for controlling the power of the card (for temperature-related issues), but those did not address my issue. Fortunately, the solution was fairly simple for my problem.

I have Ubuntu Jaunty, with the 2.6.28-15 kernel. The resolution came when I looked in synaptic at the installed linux-restricted-modules and found I had two instances from older kernels still installed. Purging those completely from the system, and retrying to connect to my WPA2-enabled AP succeeded.

Give it a shot.

The Argument For Guns

Monday, December 15th, 2008

I am not a gun-toting fellow by any means. Typically I have waffled between whether to ban some guns or leave them all available to private citizens. I know it is a slippery slope when talking bans and I don’t trust future legislators to not take advantage of a current legislator’s good intentions in limiting a subsection of firearms.

That said, I think it is always good to refresh your position with a well-articulated essay in support of your thoughts. And while I probably will not be toting any machine guns or bazookas, I think a handgun and some training might be time and money well spent. We’ll see. Until then, here’s the post that I feel articulates a good reason for the 2nd Amendment to be un-abridged by any gun laws:

The Gun is Civilization Maj. L. Caudill USMC (Ret)

Human beings only have two ways to deal with one another: reason and force. If you want me to do something for you, you have a choice of either convincing me via argument, or force me to do your bidding under threat of force. Every human interaction falls into one of those two categories, without exception. Reason or force, that’s it.

In a truly moral and civilized society, people exclusively interact through persuasion. Force has no place as a valid method of social interaction, and the only thing that removes force from the menu is the personal firearm, as paradoxical as it may sound to some.

When I carry a gun, you cannot deal with me by force. You have to use reason and try to persuade me, because I have a way to negate your threat or employment of force.

The gun is the only personal weapon that puts a 100-pound woman on equal footing with a 220-pound mugger, a 75-year old retiree on equal footing with a 19-year old gang banger, and a single guy on equal footing with a carload of drunk guys with baseball bats. The gun removes the disparity in physical strength, size, or numbers between a potential attacker and a defender.

There are plenty of people who consider the gun as the source of bad force equations. These are the people who think that we’d be more civilized if all guns were removed from society, because a firearm makes it easier for a [armed] mugger to do his job. That, of course, is only true if the mugger’s potential victims are mostly disarmed either by choice or by legislative fiat–it has no validity when most of a mugger’s potential marks are armed.

People who argue for the banning of arms ask for automatic rule by the young, the strong, and the many, and that’s the exact opposite of a civilized society. A mugger, even an armed one, can only make a successful living in a society where the state has granted him a force monopoly.

Then there’s the argument that the gun makes confrontations lethal that otherwise would only result in injury. This argument is fallacious in several ways. Without guns involved, confrontations are won by the physically superior party inflicting overwhelming injury on the loser.

People who think that fists, bats, sticks, or stones don’t constitute lethal force watch too much TV, where people take beatings and come out of it with a bloody lip at worst. The fact that the gun makes lethal force easier works solely in favor of the weaker defender, not the stronger attacker. If both are armed, the field is level.

The gun is the only weapon that’s as lethal in the hands of an octogenarian as it is in the hands of a weight lifter. It simply wouldn’t work as well as a force equalizer if it wasn’t both lethal and easily employable.

When I carry a gun, I don’t do so because I am looking for a fight, but because I’m looking to be left alone. The gun at my side means that I cannot be forced, only persuaded. I don’t carry it because I’m afraid, but because it enables me to be unafraid. It doesn’t limit the actions of those who would interact with me through reason, only the actions of those who would do so by force. It removes force from the equation…and that’s why carrying a gun is a civilized act.

Writing Excel Spreadsheets Using PHP

Thursday, July 24th, 2008

When using the Spreadsheet_Excel_Writer library from the PEAR repository, I came across an issue I didn’t see handled in the docs (as of this writing, I am using Spreadsheet_Excel_Writer 0.9.1 beta)

My application creates spreadsheets that contain order information. Part of each row is a list of up to 20 ISBNs and the quantities desired of each. The issue came in how to handle ISBNs that had a leading zero. When I first looked through the PEAR docs for the library, a Worksheet method, writeString, looked to be the solution. However, the end result was that while the leading zero was maintained, the cell’s format was still numeric. This resulted in the application receiving the generated xls to then drop the zero, resulting in an invalid ISBN.

Looking over the internals of the Worksheet::writeString method didn’t reveal an undocumented feature that would ensure a cell was read as text, regardless of its contents. I next looked at the Format::setNumFormat method as I knew it contained ways to format the number as currency, timestamp, fractions, etc. You could then pass this Format object as the optional fourth parameter to the Worksheet::write method.

Contained in the Format::setNumFormat docs was a link to the OpenOffice.org documentation of the Excel File Format (found here, pdf). Interested in how exactly the file was structured, I read on. What I learned that was directly applicable is that each cell contains a pointer to a format definition, or XF record, and it was this XF record where formatting was stored. From the doc, section 4.6:

All cell formatting attributes are stored in XF records…The cell records themselves contain an index into the XF record list. This way of string cell formatting saves memory and decreases the file size.

So if two cells use the same formatting, like the ISBN columns would, each cell would contain a pointer to the XF record that would tell Excel the cell was text. Seciton 4.6.1 lists the 6 groups of formatting attributes, the first of which is number format, which is then an index to a FORMAT record. Okay, we’re on to something here. Further in the pdf, in section 5.49, we see the definition of the FORMAT record. Lo and behold, the table of formats from the setNumFormat page is listed in the pdf, but we see that the PEAR listing is incomplete. Scanning the complete table in the pdf, we see index 49, type Text, format string ‘@’. Bingo.

Our code for formatting numeric data as text in a string goes a little something like this (modified from the PEAR example code):

$workbook = new Spreadsheet_Excel_Writer();
$worksheet =& $workbook->addWorksheet();
 
// We'll show dates with a three letter month and four digit year format
$text_format =& $workbook->addFormat();
$text_format->setNumFormat('@');
 
$worksheet->write(0, 0, "Without formatting");
$worksheet->write(0, 1, '0123'); // cell contains 123
 
$worksheet->write(1, 0, "With formatting");
$worksheet->write(1, 1, '0123', $text_format); // cell contains 0123

To verify, generate the xls and open it. Right click the cells to modify the format of the cell, and see that the first cell is formatted as a general number, and the second cell is formatted as text.

The meta-moral is to read the docs and follow references to get at the source material. Had I not opened the pdf, it may have been a few more time units finding the information on Google. Plus, I learned a lot more about an important file format. I can sleep easy knowing I’m that much more knowledgeable.

Announcements

Monday, April 28th, 2008

Thought I’d go ahead and announce, mainly to myself, that I will be working through SICP. The rub…doing it in Javascript. Seems as though most other languages are covered (I know Erlang is taken) and since I am doing an increasingly large amount of Javascript, coupled with the eventual prevalence of server-side Javascript, I figured it best to start getting intimate. What I like about this task is that since SICP has been so widely covered on the web, I have many resources to aid in better understanding the material (and it is some thick material). Anyway, I’ve begun chapter one and will post the chapters, as well as excerpts I find interesting, in no pre-defined timeframe.

Oh yeah, and I’m engaged.

Michael Scheuer and Ron Paul

Friday, February 22nd, 2008

There may not be a better authority on Osama Bin Laden than Michael Scheuer. Intimately involved with the tracking down of bin Laden from at least 1996 to 2004, Scheuer has also written several books dealing with the handling of the Middle East by our government over the last 40 years or so. So when this man speaks on the Middle East and bin Laden, he speaks with authority that is unrivaled by most anyone else.

With that in mind, have a listen to an interview he gave recently (video was posted February 19th, 2008). Two things, among the many, that I found enlightening: first, Scheuer makes it clear that bin Laden and al Queda do not hate us for our freedoms, liberties, etc, as Bush, Guiliani, et al, have tried to ram into the conversation. It is about our involvement in the Middle East that bin Laden fights against. Second, of all the presidential candidates, Scheuer believes Ron Paul “gets it”.

Having a girlfriend invested in the green movement, I’d be remiss to comment on another bit of Scheuer’s interview and I’ll paraphrase my understanding of his remarks. When you look at the Middle East, what is there that is of interest to the US? Oil, obviously. Hmm… umm… gee… well… Not much else! So if our government were to get serious about investing in green energy and not using it to garner support while not producing results, we’d lose our interest in the Middle East, at least from a policy perspective. So using less oil = stopping the support of terrorism!

Here’s my beef for the current crop of Bush clones: they preach Christianity, family values, and all that. Fine, all well and good. However, it seems not a week goes by that a Bush supporter in the Congress doesn’t go down in flames with a scandal. But most important of Jesus’ teachings was the Golden Rule: Do unto others as you would have them do unto you. Take a moment and think back to how mad, upset, fearful, irate, how incensed with anger you were on September 11th, 2001. Planes were high-jacked and rammed into the World Trade Center. Now imagine that level of violence occurring everyday. Now double it, and double that. You’re starting to get an approximation of what the average Iraqi goes through each day. Imagine having to cope with all of those emotions everyday. Imagine, upon waking, not knowing whether you’d live or die in some suicide blast or gun fight. A terrible world for anyone. And yet our government is subjecting a country to that everyday with their occupation.

I implore you, regardless of political affiliation, to investigate Michael Scheuer’s writings and interviews and see an expert talk about the situation. Then compare that to the view given by your favorite candidate.

More important than any other issue today is our foreign policy, including the economy. Our next president must understand what’s at stake with respect to the rest of the world, not with respect to a small part of it (namely the European Union countries).

The slim silver lining here is two-fold. Wean our economy and way of life off oil and we lose interest in the Middle East, and, support Ron Paul and bring a man into office that is knowledgeable in both foreign policy and the economy.

Join the REVOLUTION

Fibonacci stream

Monday, February 4th, 2008

The Fibonacci sequence: teacher of recursion for so many Computer Science students. But can it also teach us about streams? Yes! The function to build a stream (in Javascript):

var fib_stream_maker = function() {
  return (function() {
    var a = 0;
    var b = 0;
    var c = 1;
 
    return function() {
      a = b;
      b = c;
      c = a + b;
      return c;
    }
  })();
}

Let’s break this down so Ben can follow along. First, the inner most function:

return function() {
  a = b;
  b = c;
  c = a + b;
  return c;
}

This anonymous function returns the next number in the sequence. Looking one level of scope higher, we see the variables a, b, and c declared:

function() {
  var a = 0;
  var b = 0;
  var c = 1;
 
  return function() {
    a = b;
    b = c;
    c = a + b;
    return c;
  }
}

So we initialize the variables and then return a function that increments those variables, local to the inner function’s scope, so we can have multiple instances of the function running without collision of variables. To build the stream factory, we wrap the initialization function in parentheses, creating a continuation, and then execute the wrapped function, creating an initialized fib stream function. This is then set to return when the fib_stream_maker is called as a function.

var fib_stream = fib_stream_maker();
 
fib_stream(); // returns 1
fib_stream(); // returns 2
fib_stream(); // returns 3
fib_stream(); // returns 5
fib_stream(); // returns 8, etc...

This is only touching the surface of streams but I thought it was pretty cool that the Fibonacci sequence can be utilized to teach such important concepts as continuations and streams. Code on!

*Update*

While explaining the inner workings of the above code to CD, she asked a very astute question, one that Ben probably would not have, “What about going backwards in the stream?” A just question. Let’s look at a table of how the values of a, b, and c act as the stream goes forward first (this will help us design our algorithm later).

  a b c Returns
Creating fib_stream 0 0 1  
fib_stream(); 0 1 1 1
fib_stream(); 1 1 2 2
fib_stream(); 1 2 3 3
fib_stream(); 2 3 5 5

So to go backwards, what do we need to do to values of a, b, and c? We need to assign b’s value to c, a’s value to b, and the difference of c and b to a, and still return c. In code, this would look like:

c = b;
b = a;
a = c - b;
return c;

To integrate this into the above example, we need to pass a boolean parameter to the inner-most lamda function and test to see whether to forward or reverse the stream. Let’s see the inner-lamda now:

return function(go_forward) {
  if ( go_forward ) {
    a = b;
    b = c;
    c = a + b;
  } else {
    c = b;
    b = a;
    a = c - b;
  }
 
  return c;
}

We may want to put an additional test to see if we are at the beginning of the stream again:

return function(go_forward) {
  if ( go_forward ) {
    a = b;
    b = c;
    c = a + b;
  } else if ( a == 0 && b == 0 ) {
    ; // do nothing
  } else {
    c = b;
    b = a;
    a = c - b;
  }
 
  return c;
}

Let’s see it all as one big fun function:

var fib_stream_maker = function() {
  return (function() {
    var a = 0;
    var b = 0;
    var c = 1;
 
    return function(go_forward) {
      if ( go_forward ) {
        a = b;
        b = c;
        c = a + b;
      } else if ( a == 0 && b == 0 ) {
        ; // do nothing
      } else {
        c = b;
        b = a;
        a = c - b;
      }
      return c;
    }
  })();
}

And there you have it. Thanks CD for bringing up this interesting idea! What a nerd!

Save $150 Billion Much?

Friday, February 1st, 2008

It’s a sad state of affairs that we as voters must wade through so much posturing and pandering by the presidential candidates. Particularly hard is when we find out after they are elected that their words were vaporous and meaningless. What’s a voter to do?

A study released January 29th of this year by the National Taxpayers Union Foundation helps tax payers cut through the facade and see the real truth, expressed in hard numbers. Keep in mind that the United States has trillions of dollars ($9,200,874,834,693.13) in debt, is spending close to $1 trillion a year on Iraq and Afghanistan, and is facing the housing market implosion. Now, with all this economic unrest, which candidates actually want to do something about it and save some dough?

The four respective frontrunners in the two parties (John McCain, Mitt Romney, Hillary Clinton, and Barack Obama), proposed overall fiscal policy agendas whose net effect would raise annual federal outlays between $6.9 billion and $287.0 billion.

The top-tier GOP candidates often portrayed as “conservative” (Mitt Romney and Mike Huckabee) actually called for significantly larger spending hikes ($19.5 billion and $54.2 billion, respectively), than the so-called “moderate conservative” (John McCain, $6.9 billion).

Among Democrats, Barack Obama, often described as ideologically more “moderate” than Hillary Clinton, actually has the larger agenda of the two ($287.0 billion vs. $218.2 billion).

Defense-related spending items received the highest proposed spending increases among Republican candidates. Huckabee and Romney, for example, offered $67.2 billion and $40.6 billion, respectively. Among Democrats, Clinton’s biggest boost goes toward health care ($113.6 billion) and Obama’s for economy, transportation, and infrastructure ($105.0 billion).

Two of the eight candidates proposed sufficient spending cuts that more than offset their new spending plans: Rudy Giuliani (-$1.4 billion) and Ron Paul (-$150.1 billion).

Taking into account that Rudy Giuliani has dropped out, this makes Ron Paul the only candidate that actually wants to save the country some money, and he wants to do it on a large scale. Why are we pouring in so much money in taxes, to support a government that doesn’t represent us? Why would you support a candidate that wants that trend to continue? Where is this money going to come from?

Would you rather not pay income taxes? I know I would. What if you got to keep an extra third of your income? Don’t you think that’s a bigger chunk than a proposed $300 tax rebate Congress is now considering to “stimulate” the economy? I know it is significantly more for me. I would rather spend the money that I earned than some small rebate the government gives me. We don’t know the source of that rebate either. The administration is currently engaged in deficit spending, racking up more debt to pass on to future generations. How long until China calls in those debts?

It’s time to make the government stop spending, and the only way to do that is by electing Ron Paul, the only candidate left that is 100% for real about cutting spending and saving US citizens their hard-earned income. Read his views, compare them with an open mind to the other candidates, and you’ll see Dr. Paul is truly about getting our country back on track.

Join the REVOLUTION

MySQL -> CSV

Wednesday, January 30th, 2008

Always on the lookout for increases in efficiency, I love when I find a slick snippet of command line goodness that makes a hard sounding task simple and quick. I was tasked with creating an email list from a database and putting it into a csv format, and had only the command line to interface with the DB. My first attempt revolved around using the SELECT … INTO OUTFILE syntax. Unfortunately, I was unable to write out to a file with the DB user I had access to. What’s a fella to do?

Unix pipes to the rescue.

First, the whole command:

echo “select * from example;” | mysql -u user -p dbname | tr ‘^V^I’ ‘,’ > filename.csv

Let’s break this down, in case Ben is reading and can’t follow along. The echo statement contains your query. It is sent to the mysql command, which connects you to the database and executes the query, returning the data in tab-delimited format to the console. The tr command reads from STDIN, and replaces tabs (Ctrl-V Ctrl-I) with whatever delimiter you want (in this case the comma). The final touch is sending it to a file of your choosing.

*Note* – You actually have to type the Ctrl-V Ctrl-I when entering this command. Copy/paste won’t cut it in the example above.

*Note* – You typically do not want to actually enter your mysql password on the command line, as commands run are typically logged. Omit the password to force mysql to ask for it (it won’t interfere with the query). And if you don’t have your mysql access password protected, WTF? You’re asking for trouble.

So there you have it. Simple, easy to follow, effective. As always, this example can be extended into a variety of different ways. It’s up to you to figure it out (you can, of course, pay me to figure it out).