I have a dream…

A Simple Dream

Everyone working in configuration management would like to find a way to simplify and perhaps obsolete this dreary job. The ‘impossible dream’ is that everyone writing configuration scripts can use the work of the whole community instead of re-inventing the wheel for each site and purpose. But so far, while configuration tools proliferate, it has been difficult to convince people to distribute and maintain reusable scripts for configuring systems and implementing common services. There seem to be “too many options,” “too many system dependencies,” and “too many site-specific assumptions.”

This was written in 1999. Then the XML holy grail crap became popular and managing organized complexity became even more painful.

Conway’s Game of Life implemented in Processing

Yesterday’s ugliness in implemented in Processing:

class Cell {
  int x;
  int y;
  int size;
  int live;

  Cell(int tx, int ty, int ts, int tl) {
    x = tx;
    y = ty;
    size = ts;
    live = tl;
  }

  void display() {
    stroke(0);
    if (live == 0) {
      fill(209);
    } else {
      fill(255);
    }
    rect(x, y, size, size);
  }

  void display(int c) {
    stroke(0);
    fill(c);
    rect(x, y, size, size);
  }
}

Cell[][] grid;
int[][] next;
int maxI;
int maxJ;
int size = 10;
int start = 0;

void setup() {
  size(900, 500);
  background(255);

  maxI = floor(width / size) - 1;
  maxJ = floor(height / size ) -1;
  grid = new Cell[maxI][maxJ];
  next = new int[maxI][maxJ];

  noLife();
}

void noLife() {
  for (int i = 0; i < maxI; i++) {
    for (int j = 0; j < maxJ; j++) {
      grid[i][j] = new Cell(i * size, j * size, size, 0);
      next[i][j] = 0;
      grid[i][j].display();
    }
  }
}

void draw() {
  if (start == 1) {
    runLife();
    delay(200);
  }
}

void mouseClicked() {
  if (start == 1) {
      noLife();
      start = 0;
  }

  if ((mouseX < maxI * size) && (mouseY < maxJ * size)) {
    int i = floor(mouseX / size);
    int j = floor(mouseY / size);
    if (grid[i][j].live == 1) {
      grid[i][j].live = 0;
    } else {
      grid[i][j].live = 1;
    }
    grid[i][j].display();
  } else {
    start = 1;
  }
}

void runLife() {
  int i0;
  int i1;
  int j0;
  int j1;
  int alive;

  for (int i = 0; i < maxI; i++) {
    for (int j = 0; j < maxJ; j++) {
      i0 = i - 1;
      i1 = i + 1;
      j0 = j - 1;
      j1 = j + 1;

      if (i0 < 0) i0 = maxI - 1;
      if (j0 < 0) j0 = maxJ - 1;
      if (i1 == maxI) i1 = 0;
      if (j1 == maxJ) j1 = 0;

      alive = 0;

      if (grid[i][j0].live == 1) alive++;
      if (grid[i1][j0].live == 1) alive++;
      if (grid[i1][j].live == 1) alive++;
      if (grid[i1][j1].live == 1) alive++;
      if (grid[i][j1].live == 1) alive++;
      if (grid[i0][j1].live == 1) alive++;
      if (grid[i0][j].live == 1) alive++;
      if (grid[i0][j0].live == 1) alive++;

      if ((grid[i][j].live == 1) && ((alive == 2) || (alive == 3))) {
        next[i][j] = 1;
      } else {
        next[i][j] = 0;
      }

      if ((grid[i][j].live == 0) && (alive == 3)) {
        next[i][j] = 1;
      }
    }
  }

  for (int i = 0; i < maxI; i++) {
    for (int j = 0; j < maxJ; j++) {
      grid[i][j].live = next[i][j];
      grid[i][j].display();
      next[i][j] = 0;
    }
  }
}

Two things that I find cool about Processing:

  • You can export your application as a Java applet.
  • Processing.js

atan2() implemented in bc

Dave Taylor thought that it would be a good idea to calculate in Perl the distance between two longitude / latitude points on the Earth. He also thought it would be awesome if the same could be implemented in bc.

I replied that one could easily transform in Perl the cost function from the TSP page. Dave Taylor pointed out that unfortunately atan2() is not available in bc and atan2() is used in the cost function.

“So what?” I thought. All one needs is the definition of atan2(). It turns out that one needs to define in bc the sign function and abs() too.

define sgn(x) {
        if (x == 0) {
                return(0);
        } else if (x < 0) {
                return(-1);
        } else if (x > 0) {
                return(1);
        }
}

define abs(x) {
        if (x < 0) {
                return(-1 * x);
        } else {
                return(x);
        }
}

define atan2(y, x) {
        auto pi, fi;

        pi = 4 * a(1);

        if (y == 0) {
                if (x > 0) {
                        return(0);
                } else if (x == 0) {
                        print "undefined\n";
                        halt;
                } else if (x < 0) {
                        return(pi);
                }
        }

        fi = a(abs(y/x));

        if (x > 0) {
                return(fi * sgn(y));
        } else if (x == 0) {
                return(pi * sgn(y) / 2);
        } else if (x < 0) {
                return((pi - fi) * sgn(y));
        }
}

Put the function definitions in a file (say atan2.bc) and call it from the command line as:

$ bc -l atan2.bc

The above code was written in less than ten minutes of time. I am sure that one can come up with better implementations (not calculating pi (== 4 * atan(1)) and then dividing it by 2 is an optimization directly observable). All in all it was a fun exercise, plus while searching I got to read about CORDIC.

Moleskine

Έχω γράψει παλιότερα πως μετά από μια σειρά από PDAs και SmartPhones, γύρισα σε ένα Moleskine notebook. Από τότε και για πρακτικούς λόγους το αντικατέστησα με ένα Filofax Personal. Για περιπτώσεις όμως που χρειάζομαι εκτεταμένες σημειώσεις, κείμενα που δε γράφω σε υπολογιστή (οτιδήποτε προκαλεί αυτό το “On Paper” feeling) χρησιμοποιώ πάλι Moleskine (όχι τα μικρά σημειωματάρια, αλλά τα μεγάλα squared τετράδια). Έτσι δεν είναι απορίας άξιο που έσκασα στα γέλια διαβάζοντας στο StuffWhitePeopleLike:

“Well, if a white person has a great idea, they write it by hand, if they have a good idea, it goes into the computer.”