Tuesday, July 26, 2011

typedef[ine]

The typedef keyword introduces a new type. The #define directive provides a textual substitution mechanism. When does this matter? Consider the following source:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "str_type.h"

size_t length (CharPtr str) { return strlen(str); }

void message () {
    CharPtr str = malloc (255);
    if (! str) { return; }
    strcpy (str, "The Message");
    printf("%s\n", str);
    free (str);
}

int main () {

    CharPtr str = "Some Static String";
    CharPtr str1, str2, str3;

    printf ("Length: %d\n", length (str));
    message ();
    printf ("sizeof(str1): %d\n", sizeof (str1));
    printf ("sizeof(str2): %d\n", sizeof (str2));

    return 0;
}

If str_type.h contains

typedef char * CharPtr;

Then the output of running that program is

Length: 18
The Message
sizeof(str1): 8
sizeof(str2): 8

However, if that file contains

#define CharPtr char *

You instead get

Length: 18
The Message
sizeof(str1): 8
sizeof(str2): 1

Notice that since the CharPtr is no longer a type you get

char * str1, str2, str3;

after the processing phase of translation and the asterisk only binds to the first variable leaving the remaining two as plain char variables.

Use #define directives only to provide textual substitution prior to translation; it does not interact with - or compliment - the type system.

Friday, July 15, 2011

Double Standard

In almost all instances it is a bad idea to place multiple distinct scales on a single plot. Not only does it require more of the reader in terms of deciphering the message, it also lessens the impact of the chart itself. Instead of a reader being able to associate the vertical data with an immediate estimated value in their mind they now have a two step process to determine a value. First, they must choose which scale applies - then they must consult the appropriate scale to derive a value. This is all a bad thing.

I also feel this is a common way to try and hide information in plain sight. Consider the following graph, what points define where the two lines intersect? (Here's a hint - they don't) This layout lends itself to all sorts of slight of hand when talking to or describing data.



Usually, I would claim that any graph that did this could be better provided as either a multiplot or two separate graphs. However, the other day I saw an instance where it made perfect sense: temperature. Plotting temperature with two separate scales is actually a representation of two separate mathematical functions that represent the same property; in effect the graph acts as a lookup table for the user for translating from one function to another. As an example, consider the following:



A glorified lookup table to be sure - but entirely functional.

Moving forward, I've modified my view to something more along the lines of: "Dual scales are useful when they both describe a single property in two distinct ways." Any measurement that can be represented in a variety of ways falls into this category: temperature (Fahrenheit v. Celsius), time (24-hour v. 12-hour), distance (miles v. kilometers), and so on.

Tuesday, July 5, 2011

Progress

[EDIT] This code is now available on github: libpbar

cURL ships with one. wget uses it's own. OpenSSH (scp) even comes with it's own version. Indeed, I've written several variations myself over the years. Sooner or later, if you are doing something that processes large amounts of data or takes a long time to complete and you are working in a command-line environment you will write your own, too. A progress bar.

I did a quick search for existing progress bar libraries but came up with little outside of Ruby and Python wrappers around what the packages I mention above are already doing [1]. For mostly selfish reasons, I've decided to write a library that fixes my redundant behavior moving forward. Once I am able to provide a proper build system I will put this code up on github - my unfamiliarity with autotools may delay this a bit.

What this library aims to provide is a consistent interface for programatically displaying a progress bar outside of a GUI environment. It does not try to provide a package similar to Pipe Viewer (pv) which is a complete, standalone program for monitoring processes activity. Instead, to keep things simple, libpbar will initially provide a class with the following public interface:

class ProgressBar {
public:
    ProgressBar (::size_t cap);
    void update (::size_t n = 1);
};

With three implementations provided with the library: TextProgressBar, ColorProgressBar, GraphicalProgressBar. These provide basic text functionality, color text, and a GTK+-based object respectively. Using any of these facilities is as simple as:

int flags = TextProgressBar::SHOW_VALUE | TextProgressBar::SHOW_COUNT;
TextProgressBar pb(100,flags);

They each do as you might expect:
TextProgressBar:

ColorProgressBar:

GraphicalProgressBar:

The nice thing about the GUI version is that the hosting program doesn't need to be a GUI application. For this version of the progress bar a separate thread is used to spawn the graphical interface and as much as possible is done to shed the window treatments to expose just the progress bar itself.

I've got to expand on this by allowing some way to encode message text with format strings and allowing user-defined color modifications. The basics are there, however, and I should now be free from writing yet another progress bar implementation.


[1] This is a solved problem and certainly my fruitless search does not imply any lack of existing tools