[headshot of jjohn] [Taskboy]
.

Sections

Games

More jjohn Links

Search


Joe's Journal

List all entries


Jacked

17th August 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

In the software/hardware paradigm that bifurcates humanity, I'm squarely in the software camp. However, I have successful created a CAT 5e run of ethernet cable that goes from the basement to my second floor office terminating in a real, honest to goodness RJ-45 jack in my wall. I couldn't be more proud. If you attempt to install wired ethernet in your home, be aware of the following:

1. Running the cable is the hardest part of the job

If you have a new home, running cable is as easy as getting into the walls before the drywall/plaster is installed. Otherwise, you'll need snake the cable through those unfinished walls in your house, like those found in basements and attics. You could also rip open your finished walls, install the wiring and patch it later, but you're clearly more butch than I. In my case, there was existing speaker wire that went from the basement to the attic. I simply attached one end of a 100' spool of CAT 5e cable to top of the speaker wires with copious tape. I then pulled (carefully) on the wire from the basement to get whatever gravity-assist I could. Your mileage will vary.

2. Get the right tools

You will need an ethernet jack punch down tool. You can get this at Lowes, Microcenter or many other places online. Do not confuse this with a crimping tool, which is designed to fit a male RJ-45 coupling onto the end of an ethernet cable. Punch down tools force the individual wires of ethernet into specific recepticals on the RJ-45 jack. You should not strip these wires before punch down. The act of punch down removes the casing around the wire. Some tools will cut the extra length of wire for you, but any wire cutting tool will work adequately for the job.

You might also need fish tape to help you run the ethernet cable into the hard to reach areas of your wall.

3. Read the mating diagram on the RJ-45 jack

Ethernet cabling consists of 4 twisted pairs of wires, which are typically colored brown, blue, orange and yellow. Each color has a mate that striped with white for a total of eight wires. To attach to an RJ-45 jack, each of these eight wires needs to be punched into the right saddle. Most RJ-45 jacks are sold with a diagram that explicitly shows where each wire goes. Follow the directions carefully. You cannot fudge this part.

4. Unless you have a house older than 50 years old, use new construction low voltage brackets

Low voltage brackets are the bits that are nailed or screwed into the wood of a joist so that the face plate can be attached to the wall. These seemingly simply devices come in a broad variety of forms. One of the dimensions of variation is in how the bracket attaches to the wall. Brackets that have screws or nails go parallel to the face plate are called "new construction" mounted. Brackets that have nails or screws that are perpendicular to the face plate are said to have "old construction" mounting. I can't really think of a situation where old construction mounting works, but as I said, I'm not a hardware guy. That's also why I bought an old construction mounting first. Live and learn.

It took me three days to do this admittedly simply installation, because I didn't have all the right tools and parts initially.

This is a great project for all you home-owning nerds out there. There are many more detailed web resources out there that explain the process in more detail than I've provided. Also, check out You Tube for helpful videos. There was at least one that shows how to punch down an RJ-45 jack correctly.

0

Tags:         
Let's talk about hex

8th August 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

Hex maps. Every wargamer knows them. Expert D&D players broke out of their dual-axis world during their Isle of Dread campaign to use these six-sided monsters. Here's a close up of one:

Figure 1

Hex maps, it is claimed, offer a more natural choice of direction for players who want to model open air terrain than the good old graph-paper, cartesian plane, 2 perpendicular axes maps. Graph paper maps do match up well to the four cardinal points of a compass, which is nice. Even better for programmers, these kinds of maps are easily represented with 2 dimensional arrays, a data structure that even grumpy old C supports!

Figure 2: 2D map

And it's easy to find the neighboring squares in this kind of map. Consider a coordinate system whose origin (0,0) is the upper most left corner of a grid. Going to the right adds to the x coordinate, while going left subtracts from it. Similarly, going down to the bottom of the grid adds to the y coordinate, but going up lessens the y value. If the starting square can be thought of as being at the coordinate (x,y), then neighbors can be found at predictable offsets:

  • Northern neighbor: (x, y-1)
  • Eastern neighbor: (x+1, y)
  • Southern neighbor: (x, y+1)
  • Western neighbor: (x-1, y)

It's easy to extrapolate how you could find the diagonal squares too if you wanted to, but that's not desirable for wargamers. There are at most only four equidistant neighbors for any given square on the graph paper map. Sure, you could include the four squares pointed to by the diagonals of the square, but these are more distant from the center of the square than the neighbors at the cardinal points. And that makes wargamers mad! How can you accurately plot the range of your 18th century dutch cannon using only the cardinal compass points?! Hex maps offer up to six equidistant neighbors for any given hex. And that means more accurate pathing for cannon fire. Super!

But how do you model a map in which each element has six neighbors? You could make a linked list of structures that contain pointers to each of their neighbors. But that's not a particularly natural fit and would cause a great deal of programming overhead to populate and search. Is there a way to get all the benefits of a hex map into a 2D array implementation? Yes, there is but you need to to think about a hex map in a certain way.

Look at Figure 1 again, but try to see the map as three columns of hexes stacked on top of each other. Notice that although the first column (with hexes A and D) are horizontally aligned with the last column (with hexes C and F) but the the middle colum (with hexes B, E and G) is a bit offset. This is an important detail that will affect our hex map model. We can order these hexes from left to right, top to bottom if we take into account the offset columns that happen every other time. That is, all the odd number columns are offset from the even numbered ones. We can make a horizontal row by starting with a left-most hex. Then, find the "northeastern" neighbor in the odd row. To find the horizontal neighbor of that hex, look to its "southeastern" side. In Figure 1, the first horizontal row is marked out as hexes A, B and C. Continue this alternation until you hit the last column of hexes.

Once we have a predictable sorting order for our hexes, we can use a 2D array to model this map. Why bother with a 2D for a linear list? The answer is that a 2D array naturally maps to the way computer screens are represented in most drawing libraries. 2D arrays also fit easily into an SQL database system. So, even though the thing we want could be represented in a number of ways, there's a lot of convenience to be had in thinking of (x,y) coordinates. So given a hex coordinate, how can we determine its neighbors in a 2D array? The answer is: it depends!

It depends on whether the hex is in a odd numbered column or an even numbered one. Consult the two tables below. I look for neighboring hexes in a clockwise direction starting at the top of the hex (which would be the northern neighbor).


Neighbor Coordinate offset
North (x, y-1)
Northeast (x+1, y)
Southeast (x+1, y+1)
South (x, y+1)
Southwest (x-1, y+1)
Northwest (x-1, y)

Figure 3: Calculating Neighbors for Hexes in Even Columns


Neighbor Coordinate offset
North (x, y-1)
Northeast (x+1, y-1)
Southeast (x+1, y)
South (x, y+1)
Southwest (x-1, y)
Northwest (x-1, y-1)

Figure 4: Calculating Neighbors for Hexes in Odd Columns

And for the purposes of this discussion, column 0 counts as even. Does your brain hurt a little? Mine too. Let's make this more concrete.

Using Figure 1, let's create a 2D array that maps the hexes in the right order.

  0 1 2
0 A (0,0) B (1,0) C (2,0)
1 D (0,1) E (1,1) F (2,1)
2 - G (2,2) -

Figure 5: Mapping a Hex Map into a 2D Array

I have included the coordinates of the hex in this table for easier reference. Let's walk through our algorithm to find all the neighbors of each point.


Hex N NE SE S SW NW
A (0,0) (0,-1) D (1,0) E (1,1) B (0,1) (-1, 1) (-1,0)
B (1,0) (1,-1) (2,-1) C (2,0) E (1,1) A (0,0) (0,-1)
C (2,0) (2,-1) (3,0) (3,1) F (2,1) E (1,1) B (1,0)
D (0,1) A (0,0) E (1,1) (1,2) (0,2) (-1, 2) (-1,1)
E (1,1) B (1,0) C (2,0) E (2,1) G (1,2) B (0,1) A (0,0)
F (2,1) C (2,0) (3,1) (3,2) (2,2) G (1,2) E (1,1)

Whew! That's quite a table of mind-numbing numbers! What this table is attempting to show is the neighboring hexes for each hex appearing in the left-hand column. Computations which result in a valid location are shown with that area's label. Computations that produce bum results are shown in italics, just to give you some idea how the edge cases work.

Now that you can easily find the neighbors of any hex, you can implement any of the class of algorithms designed to calculate shortest path, distance, etc. Of particular note, A* pathfinding and shortest distance routines should fall out nicely once you wrap the neighbor calculations into some kind of function.

Which is an exercise I leave for the reader. I realize that modeling hex maps is a solved problem, but I worked this stuff out for myself. Thinking of these sorts of things keeps me off the streets and high on life.

Peace out.

0

Tags:           
He's right behind you!

8th August 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

Picture of me at the Javaroom in Chelmsford taken with my Macbook's Photobooth app. Compare to the one I took here with my XO.

UPDATE: The Chelmsford Public Library is #^(%ing great. It's clean, brightly lit, full of electrical outlets and WIFI! Of course, PPTP, FTP, SMTP and some other ports are blocked, but not SSH. W00t!

0

Tags:                 
Pink eye

5th August 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

Visited Lowell General Hospital today for the first time, in which a doctor looking very much like Alton Brown informed me that my eye was swollen from non-viral conjunctivitis. I get to put jelly in my eye for three days.

So, I have that going for me.
0


Tags:         
XML::RSS::Podcast update

1st August 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

It seems that a few of you are using or trying to use the XML::RSS::Podcast module I published on this blog. As was mentioned there, modern version of XML::RSS do not support the encode function required for generating well-formed XML documents.

That's all changed thanks to Rohan Carly. [Add your thanks to Rohan in the comments.]

I present the complete version of XML::RSS::Podcast below. If you find this module useful, I'll attempt to create a CPAN module for it.

package XML::RSS::Podcast;
use XML::RSS;
use HTML::Entities qw[encode_entities_numeric encode_entities];
@XML::RSS::Podcast::ISA = qw[XML::RSS];
our $VERSION = q[1.1];

# encode by Rohan Carly
# Stolen from XML::RSS::Private::Output::Base;
sub encode {
  my ($self,$text) = @_;
  return unless defined($text);
  
  my $encoded_text = '';
  
  while ($text =~ s,(.*?)(<!\[CDATA\[.*?\]\]>),,s) {
    # we use &named; entities here because it's HTML
    $encoded_text .= encode_entities($1) . $2;
  }
  
  # we use numeric entities here because it's XML
  $encoded_text .= encode_entities_numeric($text);
  
  return $encoded_text;
};

sub as_string {
  my $self = shift;
  return $self->as_podcast_rss;
}

sub as_podcast_rss {
  my $self = shift;
  my $enc = $self->{encoding};
  my $output = qq[<?xml version="1.0" encoding="$enc"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" 
     version="2.0">];
          
  $output .= $self->podcast_start_channel;
  
  for my $i (@{$self->{items}}) {
    $output .= $self->podcast_item($i);
  }

  $output .= $self->podcast_end_channel;
  return $output .= "\n</rss>\n";
}

sub podcast_start_channel {
  my $self = shift;
  my @fields = qw[ttl title description link language 
                  pubDate lastBuildDate creator 
                  webMaster copyright
                 ];
  my @image_fields  = qw[title url description link     
                         width height];
  my @itunes_fields = qw[subtitle author summary
                         image explicit]; # Thanks Rohan
  
  my $output = "<channel>\n";
  
  for my $f (@fields) {
    if (defined($self->{channel}->{$f})) {
      my $s = $self->encode($self->{channel}->{$f});
      $output .= "\t<$f>$s</$f>\n";
    }
  }
  
  my $seen_image = 0;
  for my $f (@image_fields) {
    if (defined($self->{image}->{$f})) {
      unless ($seen_image) {
        $output .= "\t<image>\n";
        $seen_image = 1;
      }
      my $s = $self->encode($self->{image}->{$f});
      $output .= "\t\t<$f>$s</$f>\n";
    }
  }
  
  if ($seen_image) {
    $output .= "\t</image>\n";
  }
  
  # Owner name/email not handled
  for my $f (@itunes_fields) {
    if (defined($self->{channel}->{itunes}->{$f})) {
      my $s=$self->encode($self->{channel}->{itunes}->{$f});
      $output .= "\t<itunes:$f>$s</itunes:$f>\n";
    }
  }
  # Rohan's sub-cat handling code
  # Expects an array: [category, sub-category]
  if (ref $self->{channel}->{itunes}->{category} eq 'ARRAY') {
    my $major = $self->encode(${$self->{channel}->{itunes}->{category}}[0]);
    my $minor = $self->encode(${$self->{channel}->{itunes}->{category}}[1]);
    $output .= qq[\t<itunes:category text="$major">\n];
    $output .= qq[\t\t<itunes:category text="$minor">\n];
    $output .= qq[\t\t</itunes:category>\n];
    $output .= qq[\t</itunes:category>\n];
  }

  return $output . "\n";
}
  
sub podcast_end_channel {
  return "</channel>\n";
}

sub podcast_item {
  my $self = shift;
  my $item = shift;
  
  my @fields = qw[title guid pubDate description link];
  my @itunes_fields = qw[author subtitle summary 
                         duration keywords explicit];
  
  my $output = "\t<item>\n";
  for my $f (@fields) {
                     
    if (defined($item->{$f})) {
      $s = $self->encode($item->{$f});
      my $perma = "";
      if ($f eq "guid") {
        $perma = qq[isPermaLink="false"];
      }
      $output .= "\t\t<$f$perma>$s</$f>\n";
    }
  }
  
  if (ref $item->{enclosure}) {
    $output .= "<enclosure";
    for my $f (qw[url length type]) {
      if (defined $item->{enclosure}->{$f}) {
        $output .= sprintf("$f=%s", $self->encode($item->{enclosure}->{$f}));
      }
    }
    $output .= "/>";
  }
  
  for my $f (@itunes_fields) {
    if (defined $item->{itunes}->{$f}) {
      $s = $self->encode($item->{itunes}->{$f});
      $output .= "\t\t<itunes:$f>$s</itunes:$f>\n";
    }
  }
  return $output .= "\t</item>\n";
}
1;

For an example of usage, please see the previous post cited above. Report bugs in the comments or through email. Thanks.
0


Tags:         
Updates coming

24th July 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

I have lots of updates to make, but no time.
Tags:   
RIP: George Carlin

23rd June 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

I saw George Carlin on stage three times -- once at the Cape Cod Melody Tent, a prime venue. Mr. Carlin's comedy was formative for me as it was for many people. His Occupation: Foole album was the first comedy album I'd ever heard.

Many comedians benefitted from the doors he open with his racy stuff. Lenny Bruce is rightly credited with being an earlier adopter of blue language into his routine, but Carlin made the rough stuff palatably rather than merely raunchy and angry.

His political stuff was always a decade ahead of the pack. As he drifted into his golden years, he didn't mellow, but became more pointed on his attacks at the establishment. He was the very icon of what stand-up comedy means to me.

The seven famous words on his web site sum up it best: we love you and we'll miss you.
0


Tags:         
Five-year-olds of doom

5th June 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

Finally, a meaningful survey on the web (via classicaljunkie).

Don't let their size fool you: these critters are dangerous in numbers.
0


Welcome to the Landed Gentry

2nd June 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
(5/5)
  ?

I have bought my first house. It's the biggest thing I've ever bought and it will require more care and feeding than any pet I've owned.

On the upside, I now have the right to vote and smoke old guy cigars.

Level me up one.
0


Tags:     
Leostream is hiring

25th May 2008 PermaLink    Add to Del.icio.us    Sumbit blog to Digg
 
  ?

After five years, Leostream is finally got a careers page with [EDIT: some] content on it. The times, they are a-changin'!

If you're a self-motivated developer interested in working in the virtualization market (which is ridiculously hot right now), please consider sending your resume to Leostream. You'll find all the particulars on the company web site, but I can list some of the things we're looking for in an engineer:

  • C++ or Perl. These are the two primary development languages we use. C++ for Windows dev and Perl for Linux dev. Java is also a nice to have.
  • You need to understand socket programming and networking cold. I don't care if you can actually resolve the address space of a given netmask, but you should know what a netmask is.
  • You should have some experience with RPC mechanisms and XML-RPC/SOAP in particular.
  • At least understand what a virtual machine is. If I said, "what's a VMX file", you should know that it's the VMware config file for virtual machines. If I said "VHD", you should think of the MSVS/Xen virtual disk format.
  • You have to be self-directed. Leostream is growing fast and you'll need to puzzle out a lot of details for yourself. Of course, that's not to say there's no support for new developers. But, you'll need to keep your own task list up to date. :-D
  • Tolerance for start-ups. Leostream does not have the amenities of larger companies. If that's important to you, you'll need to look elsewhere.

Also note that I'm not the hiring manager. Please do not send your resumes to me.

Cheers.
0


Tags:         
 

copyright © Joe Johnston
<jjohn @ taskboy.com>
RSS