lizard-socks programming blog
Formatting with ternary operators

A ternary statement (condition ? trueObj : falseObj) can condense your code quite a bit, but you have to be careful to ensure it’s still readable.

Here’s a statement I’m using in one of my C# applications:

WiiPixelFormat format =
    selmapMarkFormat != null
        ? selmapMarkFormat.Value
    : useExistingAsFallback && !createNew
        ? toReplace.Format
    : Utilities.HasAlpha(newBitmap)
        ? WiiPixelFormat.IA4
        : WiiPixelFormat.I4;

Expanded out as a series of “if” statements, it would look like this:

WiiPixelFormat format = {some value that will be overwritten anway};
if (selmapMarkFormat != null) {
    format = selmapMarkFormat;
} else if (useExistingAsFallback && !createNew) {
    format = toReplace.Format;
} else if (Utilities.HasAlpha(newBitmap)) {
    format = WiiPixelFormat.IA4;
} else {
    format = WiiPixelFormat.I4;
}

The code is about as clear as the ternary statement (if not more so), but the many brackets and parentheses can make it hard to see at a glance that the structure is assigning a single value to a variable, and nothing else.

However, it at least enforces a structure. A ternary statement could look like this:

WiiPixelFormat format = selmapMarkFormat != null
        ? selmapMarkFormat.Value : useExistingAsFallback && !createNew
        ? toReplace.Format : Utilities.HasAlpha(newBitmap)
        ? WiiPixelFormat.IA4 : WiiPixelFormat.I4;

It doesn’t seem unreasonable, but the placement of the line breaks is misleading, distracting from what’s actually going on here. It should be more like this:

WiiPixelFormat format = selmapMarkFormat != null ? selmapMarkFormat.Value
        : useExistingAsFallback && !createNew ? toReplace.Format
        : Utilities.HasAlpha(newBitmap) ? WiiPixelFormat.IA4
        : WiiPixelFormat.I4;

Not as bad, but still not as clear as the version on top.

Visual Basic parameter/index confusion

VB.NET, unlike C#, uses parentheses “()” for both function arguments and indexes.

.NET, of course, lets you use indexing operators not just on arrays, but on other ordered collections as well - lists, etc. This extends to strings. In C#, the expression "something"[2] is the character 'm'.

Also, in VB.NET - but not in C# - you can call a parameter-less function without the parentheses. FunctionName acts as FunctionName() would.

This can lead to some problems if you’re not careful. Here’s a function that takes an integer as its parameter, and returns a string:

Function Say(num As Integer) As String
Return “There are ” & num & ” of those.”
End Function

At some point, you would call:

Dim str = Say(8)

But let’s say you change the function later so it doesn’t take any arguments:

Function Say() As String
Return “There are too many to count!”
End Function

Instead of throwing an error, running Say(8) will give the following result:

e

The (…) syntax is now being used as an index operation on the function call Say, and it returns a character instead of the string you expected.

Getting ASCII values of characters in PHP

In several languages (i.e. Java or C) you can do something like this to a char value:

char ch = ‘n’;
ch—; // sets ch to ‘m’

But PHP doesn’t have a char datatype. Instead, if you need to do this, represent your character as a string (either single or double quotes will work) and use the chr and ord functions:

$ch = “n”;
$value = ord($ch); // $value is now 110
$value—;
$ch = chr($value); // $ch is now “m”

Also remember that you can access each character in a PHP string by using it like an array.

JSpinner and bytes

I’m making a Swing application that uses a JSpinner to change a byte value. I want to assign the value to a byte, but the JSpinner uses Integer or Double objects, and the getValue() method returns Object.

There are a few different ways to accomplish this inside a ChangeListener added to the JSpinner. None of them are all that elegant:
int ival = (Integer)spinner.getValue(); // assumes the JSpinner uses integers and not doubles
byte b = (byte)ival;

byte b = Byte.parseByte(spinner.getValue().toString()) // converts to String: safer, but unneeded overhead

byte b = ((Number)spinner.getValue()).byteValue() // most efficient, but confusing parentheses

This will NOT work:

byte b = (byte)spinner.getValue();

An alternate method (making a variable for the SpinnerNumberModel) allows for more elegant code. This is what I had been using:

JSpinner spinner = new JSpinner(new SpinnerNumberModel(5, 1, 10, 1));
panel.add(spinner);

Changing my code slightly offers a more streamlined approach.

SpinnerNumberModel model = new SpinnerNumberModel(5, 1, 10, 1);
panel.add(new JSpinner(model));

A ChangeListener can be added directly to the SpinnerNumberModel. Additionally, using a SpinnerNumberModel provides the method getNumber(), which returns a Number object, eliminating the need for casting.

byte b = model.getNumber().byteValue();

Carbon dioxide, calculus, and getting data from a graph

I’m currently enrolled in a college course about conservation of the environment. A recent reading assignment was an article in the Journal of Forestry about climate change and American forests, written by researchers from the US Forest Service. The article contains a graph showing the carbon emissions and sequestration by American forests from 1700 to 2000, plus two projections up to 2010. Positive values on the graph show how much carbon is being released from the forests, in metric megatons (Mt) of carbon per year; negative values show carbon sequestration – how much carbon is being taken out of the atmosphere per year due to forest regrowth.

Carbon graph

I realized that using calculus, I could create a graph of the total changes in carbon due to forest clearing/regrowth since 1700, measured in metric megatons of carbon. I just had to integrate from 1700 to x on the original graph for each year x on the new graph.

If you just want to see the graph, scroll to the bottom of the post :)

Read More

Fork of xfce4-verve-plugin with DuckDuckGo support

This command-line box for the Xfce panel can direct you to DuckDuckGo for queries beginning with “!”.
You can also use it just as a search engine box by changing settings in the properties dialog – in this mode, it supports DuckDuckGo, Google, Wolfram|Alpha, Wikipedia and more.
You can also add more than one box to your panel, and each will have its own settings.

Source code at: https://github.com/IsaacSchemm/xfce4-verve-plugin (designed as a Debian source package that can be compiled under Debian or Ubuntu withdebuild -us -uc)

Posting to Twitter from the CLI

My current OS (other than the Windows 7 that came with my computer) is a customized Ubuntu 10.10 running Trinity Desktop Environment. TDE is a maintenance fork of KDE 3.5, the first desktop environment I used with GNU/Linux, and still the only one that supports my panel arrangement (see below.)
The command-line bar allows me to run commands without opening a terminal, and it rests above the main panel. Kicker may be an unwieldy piece of software, but it works.

I began to wonder if I could post to Twitter from the TDE panel. Since it’s essentially old software, finding an applet was unlikely, so I focused my efforts on finding a way to use the terminal to post tweets. I found several websites that suggested using curl, but Twitter no longer supports basic authentication, so this method doesn’t work anymore.

Something that did work was the Ruby gem console_tweet. I installed it using:
sudo aptitude install rubygems
sudo gem install console_tweet

When I tried to run the setup from the terminal:
twitter setup
I ran into this error:

Invalid gemspec in [/var/lib/gems/1.8/specifications/console_tweet-0.1.3.gemspec]: invalid date format in specification: "2011-12-06 00:00:00.000000000Z"
/usr/lib/ruby/vendor_ruby/1.8/rubygems.rb:926:in `report_activate_error': Could not find RubyGem console_tweet (>= 0) (Gem::LoadError)
from /usr/lib/ruby/vendor_ruby/1.8/rubygems.rb:244:in `activate_dep'
from /usr/lib/ruby/vendor_ruby/1.8/rubygems.rb:236:in `activate'
from /usr/lib/ruby/vendor_ruby/1.8/rubygems.rb:1307:in `gem'
from /usr/local/bin/twitter:18

I fixed this by editing /var/lib/gems/1.8/specifications/console_tweet-0.1.3.gemspec and changing
s.date = %q{2011-12-06 00:00:00.000000000Z}
to
s.date = %q{2011-12-06}

Then I was able to run the setup and authenticate it as a Twitter app.

For convenience’ sake, I decided to write a small GUI wrapper using kdialog (included with Trinity.) I named the file “tw” and put it in /usr/local/bin. GNOME or Xfce users would substitute zenity here, with its different arguments.

#!/bin/sh
if kdialog --yesno "Would you like to post this tweet?\n\n$*";then
kdialog --msgbox "$(twitter tweet "$*")"
fi

Now I can tweet by typing into my panel command bar:

Trinity desktop

Confirmation dialog

Output of console_tweet

Message posted on Twitter

UPDATE (June 14, 2012): I am now using Xfce4 with the verve command-line plugin. The only change I had to make was to use zenity instead of kdialog, and the “tw” script now works perfectly with Xfce.

Java .jar in console (Windows)

In Java, it’s easy to distribute your software. Simply put
it in a .jar file and it will launch automatically when the user
double-clicks it. But what if you want them to be able to see the
console output? Well, in Windows you just need to make a one-line
batch file:

@java -jar jar-file

Replace “jar-file” with the actual .jar filename.

Finding symlinks to files in the same directory

This shell script will return the names of symbolic links in the current directory that link to other files in the current directory. It will not return the names of regular files, or of symbolic links to files in other folders.

#!/bin/sh
ls -la |grep ^l |awk '{ print $8,$10 }'|while read i;do
if echo $i|awk '{print $2}'|grep -qv "/";then
echo $i|awk '{print $1}'
fi
done
Simulating boolean variables in shell scripts

Most programming languages have a “boolean” variable type; that is, one that can store a value of “true” or “false”. An advantage to using Boolean variables rather than representing yes/no outcomes with integers is that it simplifies the if statement.

//Java example
boolean fileExists = true; //Assign variable

if (fileExists) {
System.out.println("The file exists");
}
// or you can use:
if (!(fileExists)) {
System.out.println("The file does not exist");
}

This made me realize that there is a quick way to handle true/false values in Unix shell scripts:

##shell example
EXISTS=true #Assign variable

if $EXISTS;then
echo "The file exists"
fi
#or you can use:
if ! $EXISTS;then
echo "The file does not exist"
fi

In this code, $EXISTS is actually a command that is run, and the if statement checks its exit value. “true” and “false” are commands that simply do nothing and return with values 0 and 1, respectively.

This way, you can avoid having to use the test (or “[ … ]“) command, and your code will look a bit nicer. Just be sure the variable is set to either “true” or “false” and not to, say, “aptitude remove -y firefox”.