Making OS X Command Line Behave More Like Linux (GNU)

The command-line oddities of Mac OS X’s BSD heritage drive me insane. I much prefer the behavior of the GNU toolchain, as provided by Ubuntu Linux.

To begin, first install MacPorts.

MacPorts Installation Variant +with_default_names

With several MacPorts packages, the +with_default_names variant may be specified. This causes package contents to be installed without the default “g” prefix. For example, without +with_default_names, find would be installed as gfind.

Autocompletion

1) Use MacPorts to install the bash-completion package:

sudo /opt/local/bin/port install bash-completion

2) Edit ~/.bash_profile to load the correct autocompletion script:

if [ -f /opt/local/etc/bash_completion ]; then
   /opt/local/etc/bash_completion
fi

Open a new terminal window, and commands should auto-complete according to the GNU specification.

Find

The GNU version of find helpfully assumes that, if no arguments were given, you wish to search the current directory. The OS X (BSD) version has no idea what to do without a directory specification.

sudo /opt/local/bin/port install findutils +with_default_names

This package includes find, gfind, glocate, goldfind, gupdatedb, gxargs, locate, oldfind, updatedb, and xargs.

Core Utilities

This vaguely-named package provides a large number of standard GNU tools.

sudo /opt/local/bin/port install coreutils +with_default_names

Update Path

In order to call the MacPorts-installed tools by default, your path will have to be updated to include /opt/local/libexec/gnubin/. I added the following to ~/.bash_profile:

export PATH="/opt/local/libexec/gnubin/:$PATH"
Posted in OS X, Technology | Tagged , , , , , | 1 Comment

Queue Implemented Using Stacks

Here are two solutions for using stacks to emulate a queue. The first always keeps one or both stacks empty, shifts the set of values back and forth as the caller switches between enqueuing and dequeueing. The second maintains an input stack and an output stack. All enqueued data goes directly onto the input stack. When dequeue is called, if the output stack has anything on it, it takes the topmost value, otherwise it transfers the entire input stack into the output stack.

The latter implementation is more efficient — transfer between the two stacks occurs only when dequeue is called and the output stack is already empty — as well as more compact and readable.

Stack-Swapping Implementation

This version keeps one stack empty, and swaps all content between the two each time we switch between enqueue and dequeue operations.

#include <stdio.h>
#include <stack>

// This implementation uses two stacks.  It keeps one empty, and swaps content
// whenever we switch between eprforming enqueues and dequeues.
class FakeQueue
{
    std::stack<int> s1;
    std::stack<int> s2;

	// We need to keep track of the last operation (push vs. pop) so that we can
    // resorder our stack whenever we switch between enqueue and dequeue.
	typedef enum { PUSH = 0, POP } STACK_OPS;
	STACK_OPS last_op;

	void SwapStacks();

public:
	void enqueue(int i);
	bool dequeue(int &i);

	FakeQueue() : last_op(PUSH)
	{ /* empty constructor */ }
};

// SwapStacks swaps the stack between s1 and s2.
void FakeQueue::SwapStacks()
{
	if (s1.empty())
	{
		while (!s2.empty())
		{
			s1.push(s2.top());
			s2.pop();
   		}
	}
	else
	{
        while (!s1.empty())
        {
            s2.push(s1.top());
            s1.pop();
        }
    }
}

void FakeQueue::enqueue(int i)
{
	if (last_op == POP)
	{
		SwapStacks();
		last_op = PUSH;
	}

	if (s1.empty())
        s2.push(i);
	else
        s1.push(i);
}

// Retrieves the oldest item in the virtual queue.  If the queue is empty, sets i to
// -1 and returns false.  Otherwise, it returns true.
bool FakeQueue::dequeue(int &i)
{
    if (last_op == PUSH)
    {
        SwapStacks();
        last_op = POP;
    }

    if (!s1.empty())
    {
        i = s1.top();
        s1.pop();
        return true;
    }
    else if (!s2.empty())
    {
        i = s2.top();
        s2.pop();
        return true;
    }
    else
    {
        // Queue is empty.
        i = -1;
        return false;
    }
}

int main(int /*argc*/, char ** /*argv*/)
{
    FakeQueue queue;
    int i;

    // Perform a variety of queues and dequeues to show that the queue order is
    // always maintained.

    queue.enqueue(1);
    queue.enqueue(2); // contains { 1, 2 }

    queue.dequeue(i);
    printf("Dequeued %d\n", i);

    queue.enqueue(3);
    queue.enqueue(4); // contains { 2, 3, 4 }

    queue.dequeue(i);
    printf("Dequeued %d\n", i);

    queue.enqueue(5); // contains { 3, 4, 5 }

    while (queue.dequeue(i))
    {
        printf("Dequeued %d\n", i);
    }

    return 0;
}

Input-Output Stack Implementation

This version uses dedicated input and output stacks. All input goes on the input stack. When dequeue is called, if the output stack has anything on it, it takes the topmost value, otherwise it transfers the entire input stack into the output stack.


#include <stdio.h>
#include <stack>

// The second implementation uses dedicated input and output stacks.
class FakeQueue
{
    std::stack<int> in;
    std::stack<int> out;

public:
    void enqueue(int i);
    bool dequeue(int &i);
};

void FakeQueue::enqueue(int i)
{
    in.push(i);
}

bool FakeQueue::dequeue(int &i)
{
    // Abort if our queue is empty.
    if (in.empty() && out.empty())
    {
        i = -1;
        return false;
    }

    // If the "out" stack is empty, shift the contents of the "in" stack into
    // it...
    if (out.empty())
    {
        while (!in.empty())
        {
            out.push(in.top());
            in.pop();
        }
    }

    // Pop the return value from the "out" stack:
    i = out.top();
    out.pop();

    return true;
}

int main(int /*argc*/, char ** /*argv*/)
{
    FakeQueue queue;
    int i;

    // Perform a variety of queues and dequeues to show that the queue order is
    // always maintained.

    queue.enqueue(1);
    queue.enqueue(2); // contains { 1, 2 }

    queue.dequeue(i);
    printf("Dequeued %d\n", i);

    queue.enqueue(3);
    queue.enqueue(4); // contains { 2, 3, 4 }

    queue.dequeue(i);
    printf("Dequeued %d\n", i);

    queue.enqueue(5); // contains { 3, 4, 5 }

    while (queue.dequeue(i))
    {
        printf("Dequeued %d\n", i);
    }

    return 0;
}
Posted in Algorithms, C++ | Tagged | Leave a comment

Cambodia: Sexy Time!

So, if you tell people in the US that you’re going to Thailand, they’ll often start wiggling their eyebrows, jab you in the ribs with an elbow, and mutter something about ladyboys.

This morning, I was at the Ekkamai bus station in Bangkok, waiting for my bus to Cambodia. A Thai guy, apparently a worker for one of the bus lines, started up conversation, “Hello, where you go?”

That, by the way, is basically what they say to each other all the time as a greeting. However, that’s also what all the annoying touts and taxi drivers say, which I typically ignore or answer with a confusing, “everywhere.” I haven’t yet had the nerve to respond, “your mom’s house.”

Anyway, I respond, “Cambodia. Cambusha.” A typical conversation ensues. America, San Francisco, wow, yeah, America is big, and so on.

Up waddles captain sweaty, who appears to know this man. “He’s going to Cambodia!” says my new friend. “Aha, Cambodia,” says Sweaty with a knowing wiggle of the ol’ caterpillars. He then puts one hand on the back of the other and starts pumping them.

Now, one hand on top of the other, thumbs out, happens to indicate “sea turtles” when diving, so I was a bit confused. Nooo, I’m not going to Cambodia for sea turtles…?

He saw the look of bewilderment and switched his hands around a bit. Palm to palm with some suggestive thrusting and grunting.

Oh! Oh. No! No, I’m not going to Cambodia for sex! Man, I just can’t get a break…

Posted in Travel | Tagged , , , | Leave a comment

Welcome to Cambodia

So, here’s my brief summary of how I got to Angkor Wat from Bangkok, Thailand, by land:

  1. Take a government bus from the Eastern or Northern Bangkok bus stations. Leave by 7:30am. You can probably buy your ticket the same day, just show up at 6:00am. (190 baht) You should be going to Aranyaprathet, which is on the Thailand side of the border from Poipet.
  2. I don’t think it matters much whether you get your visa in advance in Bangkok. They didn’t hassle us. Perhaps if you’re in a flood of tourists off a tour bus, you might have trouble. If they try to get more than 1,100 Thai baht, demand a receipt, get their name, and report them to the Cambodian tourism board.
  3. Immediately upon leaving the Cambodian immigration, you are required to get onto a free bus to the bus station. If the police (who are lounging off to the right, in the shade) see you getting on the back of a motorcycle taxi or into a car, they will probably stop the car and fine one or both of you. To my knowledge, nothing is stopping you from walking out of the area.
  4. The bus station is basically empty. I think you just catch a taxi there.
  5. Our taxi cost $50 for three of us to Siem Reap. We had no US dollars on us, so we paid in Thai baht, 600 each. I was later told that a taxi should cost $25 for the entire car.
  6. The taxi will drop you outside Siem Reap and hand you off to motorcycle taxies and tuk-tuks. I think these guys basically try to take you to places where they get a commision. I insisted on Two Dragons, and my driver reluctantly took me there. I then paid him $6 to haul me to Angkor Wat to see the sunset, then bring me back. I was later told that this should cost $2 or $3. Still, he was a nice guy…

Random things about Cambodia that I didn’t know:

  • The Riel (local currency) is about 4000 to one US dollar. So they pretty much just use dollars. When they give change, they’ll give partial dollars in Riel notes. I haven’t seen a US coin yet.
  • The local language is Khmer. Maybe I’m just ingorant, but it wasn’t obvious to me and I didn’t want to offend anyone by asking how to say things in “Cambodian” if that’s an external name.
  • Numbers one through ten seem unique to Khmer, but from 11 on, it sounds almost identical to Thai! I have no idea the linguistic history which causes this.
  • There is a no-man’s land between Thailand and Cambodia. There are hotels and casinos here. It’s kind of weird. Big, glitzy casinos and in front of them roll some bare-footed Cambodians pushing a home-made cart loaded with a half-ton of ice. Yep, weird.
Posted in Travel | Tagged , , , , , , | Leave a comment

Where the Hell is the Cambodian Embassy in Bangkok?

I blew nearly two days just trying to get my Cambodian visa in order to visit Angkor Wat. All this to save, what, a few minutes at the border?

So, it turns out that the Cambodian embassy is not in Lhumpin Park anymore. As of around October, 2007, it has moved to the Northeast of Bangkok, near Huai Khwang. To get there, take the “M” line to Huai Khwang or the Thailand Cultural stop on MRT. Then, ask a taxi or motorcycle to take you to the Cambodian Embassy. I’ll post the Thai for that later.

The exact coordinates are N0313.76809,E100.59631. It’s on Pratcha Uthit at Saha Kan Pramun.

Incidentally, Saha Kan Pramun is where the Harley Davidson dealership is. I don’t recommend going there, however, since Harleys are crap and their simple tee shirts are 1,200 baht!

Cambodian visa details: 1,100 baht as of January 6, 2009. Requires a passport photo and a photocopy of your current passport (10 baht if you don’t bring it, don’t know how much if you forget the passport photo). Takes about 15 minutes from the time you file your paper work. The embassy closes for lunch from, if I recall correctly, noon until 2:00pm.

Posted in Travel | Tagged , , , , | Leave a comment

Thailand: Similan Islands

Having completed my SSI Open Water certification with Princess Divers on Koh Phi Phi, I decided that I couldn’t leave Thailand without diving the Similan Islands. Unfortunately, I couldn’t justify the cost of a live-aboard trip, which could easily be in the neighborhood of $900 or more. Instead, I opted for the day-trip, which runs under $200 and includes two dives.

I booked the dive through a local travel agency in Phuket, Thailand. The cost was 6,000 Baht, including all dive gear (5,600 + 400, discounted from 500). The dive was operated by South Siam Divers.

A taxi was sent to pick me up at 6:30am. The taxi was, in fact, one of the dive shop employees, and what might have been his girlfriend. We picked up one more diver on the drive up. We arrived at the dock around 8:00am, with a planned departure of around 9:00am.

We then boarded a speedboat and began a somewhat grueling one-hour ride out to the Similan Islands. I was just beginning to feel sick just as we approached the islands and slowed. We docked with the dive boat and transferred over.

The trip leader, who I assume was the captain of the live aboard, was a friendly, well-spoken man who appeared to be Thai with what may have been an Austrian accent. His presentation of rules aboard the ship, and explanations of the diving zones were extremely comprehensible.

Our first dive was around 11am, near GPS coordinates N08.68261,E097.64328. Though I’d gotten friendly with the British guy who shared the taxi on the ride over, I was instead paired with Chubby Girl. Chubby Girl assured me that she got her license a long time back, and had plenty of experience. Unfortunately, at some point along the line, she forgot entirely how to perform a buddy check (“Bangkok Women Really Are Fine” – “BDC, Weight belt, Releases, Air, Final check”).

Once in the water, we wasted precious time because one diver didn’t have her weight belt — or just not enough weight — so she couldn’t dive. Then her dive buddy became confused. Once at our target dive depth, we were pumping a lot of air in fighting the strong currents. Ultimately, our time underwater was only around 35 minutes. In that time, I saw some interesting coral, and only a few fish.

My dive partner, Chubby Girl, was bobbing madly around. Sometimes pointed up, sometimes pointed down, sometimes below me, other times above me. Regardless, she was easy to find since, for better or worse, she’d been assigned a vibrant, neon orange wetsuit. At one point, I noticed the dive master give an angry look, then pull something from the coral, only to realize that she had somehow managed to drop one of her diving weights!

The provided buffet lunch was quit tasty, and they produced a very nice vegetarian dish upon request. No complaints there at all.

The second dive, at 1:30pm, GPS coordinates N08.67568,E097.64155, was somewhat better. Chubby Girl sat this dive out (at this point, the trip leader was referring to her as my wife, I have no idea why). Instead, I was paired with a random guy who always seemed to have trouble finding me in the water. I’d glance over to check on him, only to watch as his head swiveled around. I’d wait while he did a full-body rotation looking for me, and flash him the “okay” sign when his eyes finally met mine. Funny, since there weren’t that many stark-white, bald swimmers down there.

On this dive, we got to depth more quickly, and covered more ground. Still, however, we were fighting the current, and only managed around 37 minutes. Also, our dive master still seemed disinterested, and seemed to avoid taking us directly over the coral.

It was on this trip that I realized how good my dive class had been. I watched as two of the divers in my group dragged their heavy SPGs (air pressure gauge) along the coral, since they hadn’t tucked it through their BCD belt. Initially self-conscious that I’d be consuming air too quickly, I soon learned that everyone else was at least as inefficient as I was.

Overall, compared to the four open water dives I did around the Koh Phi Phi and the Phi Phi islands, I was very disappointed with the Similans.

Today, I took a look at the South Siam Divers flier and noticed that near the top of the right panel, it lists the destination for each day of the week. It looks like Wednesday and Sunday are the days to go, the days that visit the top-rated destinations. Oops.

Well, maybe some day I’ll return to Thailand and repeat the day trip on one of the “good” days. I’ve heard that at least one of the other Similan islands is much better, with good odds of seeing a whale shark or manta rays.

Posted in Travel | Tagged , , | Leave a comment

Thailand: One Thing I Cannot Abide About Thai Culture

Sure, Thailand is full things that seem weird to Westerners. After all, T.I.T. “This is Thailand” is the mantra of expats, uttered to sooth their frayed nerves. But all in all, it’s a fun adventure, and a very old, complex culture.

There is one, single thing, however, which just really pisses me off: their refusal to take responsibility for their pets and have them spayed or neutered.

Everywhere I go, I see stray dogs and cats. Many of them mangy, mangled, bleeding. One near Nakhon Si Tammarat was virtually hairless, obviously confused, and drooling profusely while standing in the middle of the road. Perhaps he was in the process of being poisoned?

I hear that’s how they deal with it here, by the way. Every now and then, they just go around poisoning all the stray dogs. There aren’t a whole lot of worse ways to die than poisoning.

I’m told that this is all because of their Buddhist belief system. I don’t know if it’s a refusal to “harm” animals, or if it’s some sort of “things work themselves out” attitude. Either way, it’s short-sighted, cruel, and indisputably irresponsible.

Here’s the core of the issue: dogs are the creation of humans. We domesticated them, and bred them into loyal companions, helpers, and protectors. We are 100% responsible for the existence and well-being of these creatures.

My personal belief system happens to consider both the negative repercussions of actions *and* inaction. Just as it would be wrong to bring harm to a creature, so too would it be wrong to stand idly by and allow such harm to occur.

So, the one and only thing that I will simply judge as wrong and terrible is the Thai treatment of dogs.

(incidentally, this all applies to cats, too, they just happen to stay out of sight more, so it’s less heart-wrenching)

At least one foundation is trying to help, here in Phuket:
http://www.soidog-foundation.org

Posted in Travel | Tagged , , , , , , | Leave a comment

Thailand: Things to Bring #1 – Sunglasses

Not just any sunglasses, but very dark, or reflective sunglasses. Possibly wrap-around. Maybe even a welding helmet…

Yes, the sun can get pretty bright here. But that’s not the reason you NEED sunglasses. No, the real reason is to hide your eyes and avoid harassment by street vendors and taxi drivers.

Have you ever seen video of gazelles on an African plain, suddenly alert because they spotted nothing more than a lion’s tail at a hundred yards? That’s pretty good vision, but nothing like that of Thai touts, vendors, and taxi drivers.

Let’s say you’re walking along the sidewalk (by which I mean hopping over gaping holes and mostly walking in the street since vehicles needed to park all over the sidewalk), and you happen to glance out at traffic.

*Honk honk* “Hey, where you going?” Suddenly at least one motorcycle taxi has stopped directly in your path. Obviously, despite the fact that this same guy has seen you walking around the area of your guest house several times already, and despite the fact that you made absolutely no sort of gesture whatsoever which would indicate any kind of desire for a ride, it’s *possible* that you were *maybe* considering hiring a taxi this time. So he’d better check.

Similarly, perhaps you were leaping back out of the road, since a fast-moving scooter was using up the only space available for a pedestrian, and your eyes happen to catch something glinting high on the wall.

“Aaaah, you like?” Immediately the proprietor of the stand you accidentally stepped toward is fetching an amulet of some sort that you accidentally looked at. “400 baht” You shake your head and begin to walk again, “okay, 300 baht!” “No, I didn’t want…” “200 baht!” Well, now you actually take a second look, despite yourself, since hey, 50% is 50%, right? Oops, now you’ve completely committed yourself to haggling.

Realizing that you don’t actually need a silver amulet of a tiger with a comically large penis, you shake your head and begin to walk on. “150 baht!” More shouting follows, since obviously you were merely toying with this poor vendor. You are now a bad person. All because you glanced at something out of the corner of your eye.

Posted in Travel | Tagged | Leave a comment

Mullets

The other evening, I saw what sounded like a young German man sporting a mullet which can only be described as magnificent. This is in addition to several other mullets I’ve spotted on this trip, always on the heads of Europeans.

If Europe is really “five years ahead” of us on the fashion front, then we’re doomed. Good thing I still have all my old AC/DC, Scorpions, and other butt-rock CDs. Unfortunately, I don’t have the remaining hair for a mullet (after all, it can’t be *all* “party out back”), so I’ll never be able to capture the full effect.

Posted in Travel | Tagged | Leave a comment

Open Water Dives 3 & 4, and Certification

Today, I finished dives three and four in my open water certification.

Highlight of dive 1: chasing an octopus. They’re really impressively fast. But then, apparently, they get lazy, and decide to smoosh themselves into gaps in the coral. They’re pretty well disguised until you float by, they get all pissy, and turn bright white. Bingo, cue further harrassment of the eight-armed freak.

Highlight of dive 2: sea turtles! These guys are seriously laid back. They don’t care in the least how long you spend floating mere feet from them, watching them munch away on sea anemones and, apparently, coral. Also, they have HUUUUGE eyes. The other badass thing I saw on dive two was a lionfish! Black and white, and very, very fancy. But don’t make fun of his ostentatious display, because he’s quite toxic. See http://en.wikipedia.org/wiki/Lionfish

The final step was to take my SSI written test. This is 40 questions, most of them ridiculously simple. For example: the Time To Flight function on your dive computer indicates how long the diver must wait before: A) flying, B) diving, or C) taking a hot shower.

(incidentally, it turns out that answer C isn’t as ridiculous as you might think. A long, hot shower can cause nitrogen to seep out of the body at an accelerated rate, causing all sorts of un-fun problems. But that’s really only a consideration for divers going considerably deeper)

Of course, I spent too much time studying dive tables (and I’m pretty sure the instructor was wrong about one facet of using them), and not enough studying how to treat potential, horrendous conditions like the bends or oxygen embolisms in the brain. Out of 40 total, I missed four questions. :-(

Posted in Travel | Tagged , , , , , | Leave a comment