Posted by Tom Moertel
Sun, 10 Aug 2008 18:12:00 GMT
As an update to my previous post on the 2008 convention of the Historical Construction Equipment Association, I have posted an action-packed video of a Type-B Erie steam-powered shovel! Wait until you see this old beast belch steam and smoke and you hear it chug, clank, and huff and puff – it’s like stepping back in time. And it’s definately fun stuff!
I took this footage on 8 August 2008 in Brownsville, Pennsylvania. (I also have footage of other equipment – dozers, draglines, trucks, shovels, and more. Let me know if you’re interested, and I’ll upload those, too.)
Update: I have uploaded the rest of my footage to flickr:
- Thew “O” steam shovel
- Dragline
- CAT 955 bulldozer
- CAT D8 bulldozer
- Vintage Army dump truck
See them all in
my HCEA 2008 photostream.
Posted in fun stuff
Tags fun_stuff, hcea, hcea2008, steam_shovel, video
4 comments
no trackbacks

Posted by Tom Moertel
Sun, 10 Aug 2008 00:23:00 GMT
Today, my dad and I went to the 2008 annual convention of the Historical Construction Equipment Association. We were impressed with the quantity and quality of the machinery on active display: steam shovels, dozers, graders, crawlers, scrapers, cranes, steamrollers, and a bunch of other old but well-maintained construction equipment. I’m talking dozens of massive machines – not just sitting there, but working!
This year’s convention is in Brownsville, Pennsylvania and runs through August 10, 2008. If you are within driving distance and think smoke-belching, earth-shaking construction equipment is fun stuff, don’t miss it. There’s still time to go.
If you can’t make it, I took some photos for you. Not quite the real thing, but better than nothing.

Posted in fun stuff
Tags fun_stuff, hcea, hcea2008
1 comment
no trackbacks

Posted by Tom Moertel
Thu, 17 Aug 2006 06:21:00 GMT
As promised, here’s a Perl version of a dynamic-programming-based solver
for the Google Code Jam “countPaths” problem. It is a straight
translation of my improved Ruby implementation.
As you might expect, the Perl version was pretty fast. It proved faster than the
other scripting-language implementations I tried (in this rather unscientific benchmark, not to be taken seriously):
All timings were taken while solving the maximum-size, all-the-same-letter
problem on my 1.8-GHz Opteron box.
Here’s the Perl implementation:
#!/usr/bin/perl
# Tom Moertel <tom@moertel.com>
# 2006-08-16
#
# Perl-based solution to the Google Code Jam problem "countPaths".
# See http://www.cs.uic.edu/~hnagaraj/articles/code-jam/ for more.
use strict;
use warnings;
use List::Util 'sum';
use Math::BigInt;
sub count_paths {
my ($grid, $word) = @_;
my $rword = reverse $word;
my $rowmax = $#$grid;
my $colmax = length($grid->[0]);
my ($slab, $sum);
for my $i (0 .. length($rword) - 1) {
my $char = substr $rword, $i, 1;
($slab, my $previous_slab) = ([], $slab);
for my $r (0 .. $rowmax) {
my ($row, $line) = ($grid->[$r], $slab->[$r] ||= []);
for my $c (0 .. $colmax) {
$line->[$c] = $char ne substr($row,$c,1) ? 0 : $i == 0 ? 1 : do {
$sum = 0;
my $clo = $c > 0 ? $c - 1 : $c;
my $chi = $c < $colmax ? $c + 1 : $c;
for my $nr (($r>0 ? $r-1 : $r) .. ($r<$rowmax ? $r+1 : $r)) {
for my $nc ($clo .. $chi) {
$sum += $previous_slab->[$nr][$nc]
if $nr != $r || $nc != $c;
}
}
$sum;
}
}
}
}
sum map @$_, @$slab;
}
print count_paths([("A"x50)x50], "A"x50), $/;
# 3.03835410591851e+47
Update: I simplified the code a whisper by
removing an unnecessary variable
$counts. Here’s a diff
if you’re curious about what’s changed:
--- countpaths.pl.orig 2006-08-18 00:16:56.000000000 -0400
+++ /countpaths.pl 2006-08-18 00:19:30.000000000 -0400
@@ -19,11 +19,11 @@
my $rword = reverse $word;
my $rowmax = $#$grid;
my $colmax = length($grid->[0]);
- my ($counts, $slab, $sum);
+ my ($slab, $sum);
for my $i (0 .. length($rword) - 1) {
my $char = substr $rword, $i, 1;
- ($slab, my $previous_slab) = ($counts->[$i] ||= [], $slab);
+ ($slab, my $previous_slab) = ([], $slab);
for my $r (0 .. $rowmax) {
my ($row, $line) = ($grid->[$r], $slab->[$r] ||= []);
for my $c (0 .. $colmax) {
Update 2: Augmented the introductory paragraph with a parenthetical
comment that reminds readers that these single-fuzzy-data-point-style
timings should not be taken seriously. Also removed the word
“bested,” which might suggest that there is an optimization
contest in play. Please, no wagering.
Update 3: Stripped another variable ($j), which was
completely unused and leftover from previous implementation. (See
why you shouldn’t code late at night?)
Posted in programming, perl, fun stuff
Tags code, countpaths, google, jam, perl, puzzles, wordpaths
2 comments
no trackbacks

Posted by Tom Moertel
Wed, 16 Aug 2006 22:54:00 GMT
Here’s a Ruby version of a dynamic-programming-based solver
for the Google Code Jam “countPaths” problem. It is essentially
the same as my earlier Haskell-based solution (see Update 2), but much slower. Whereas the Haskell version solves the maximum-size, all-the-same-letter problem in about 0.9 second, the Ruby version requires about 71 seconds. Maybe somebody who understands Ruby’s internals better than I do can come up with some optimizations.
Here’s the code:
# Tom Moertel <tom@moertel.com>
# 2006-08-16
#
# Ruby-based solution to the Google Code Jam problem "countPaths"
# See http://www.cs.uic.edu/~hnagaraj/articles/code-jam/ for more.
class WordPath
include Enumerable
def initialize(grid, word)
@grid, @rword, @counts = grid, word.reverse, {}
end
def self.count_paths(grid, word)
new(grid, word).solve
end
def solve
final_index = @rword.length - 1
inject(0) { |sum, rc| sum + count_from(final_index, *rc) }
end
private
def count_from(i, r, c)
@counts[[r, c, i]] ||= begin
match = @rword[i] == @grid[r][c]
case
when i == 0 && match then 1
when match then subsum_of_neighbors(r, c, i - 1)
else 0
end
end
end
def subsum_of_neighbors(r, c, i)
sum = 0
rowlen = @grid[0].size
for nr in [r - 1, r, r + 1]
next if nr < 0 or nr >= @grid.size
for nc in [c - 1, c, c + 1]
next if nc < 0 || nc >= rowlen
next unless r != nr || c != nc
if count = count_from(i, nr, nc)
sum += count
end
end
end
sum
end
def each
@grid.each_index do |r|
@grid[0].size.times { |c| yield([r, c]) }
end
end
end
# TESTS
if ENV["TEST"] || ENV["BIG_TEST"]
require "test/unit"
class TestWordPath < Test::Unit::TestCase
if ENV["BIG_TEST"]
def test_big_problem
assert_equal \
303835410591851117616135618108340196903254429200,
WordPath.count_paths(["A"*50] * 50, "A"*50)
end
end
if ENV["TEST"]
def test_count_paths
w = WordPath
assert_equal 1,
w.count_paths(%w{ABC FED GHI}, "ABCDEFGHI")
assert_equal 2,
w.count_paths(%w{ABC FED GAI}, "ABCDEA")
assert_equal 0,
w.count_paths(%w{ABC DEF GHI}, "ABCD")
assert_equal 108,
w.count_paths(%w{AA AA}, "AAAA")
assert_equal 56448,
w.count_paths(%w{ABABA BABAB ABABA BABAB ABABA}, "ABABABBA")
assert_equal 2745564336,
w.count_paths(%w{AAAAA AAAAA AAAAA AAAAA AAAAA}, "AAAAAAAAAAA")
assert_equal 0,
w.count_paths(%w{AB CD}, "AA" )
assert_equal 1,
w.count_paths(%w{A}, "A")
end
end
end
end
Set the BIG_TEST and/or TEST environment
variables to run the test suites. For example:
$ TEST=1 ./countpaths.rb
Loaded suite countpaths
Started
.
Finished in 0.02062 seconds.
1 tests, 8 assertions, 0 failures, 0 errors
Unless somebody beats me to it,
I’ll whip up a Perl version for comparison.
Update: I managed to speed up my code by a
factor of 17. Now the execution time for the maximum-size,
all-the-same-letter problem is down to 4.2 seconds,
which is comparable with implementations in other
languages.
Ivan Peev’s Python implementation, for example, is only slightly faster
at 2.8 seconds.
A performance killer in the previous version was using
a single big hash for my cache. Now I use a 3D array:
counts[[i,r,c]] # one big hash (slower)
counts[i][r][c] # 3D-array (faster)
An additional advantage of the 3D-array is that I can peel off slabs
as I descend the outer layers of nested loops. For instance,
instead of writing:
for i in 0 .. 10
for j in 0 .. 10
sum += counts[i][j]
end
end
I can lift the counts[i] slab out of the inner
loop to eliminate j array-indexing operations:
for i in 0 .. 10
slab = counts[i]
for j in 0 .. 10
sum += slab[j]
end
end
Here’s the new code (sans the unit tests, which haven’t changed):
class WordPath
A = Array
def self.count_paths(grid, word)
rword = word.reverse
rowmax = grid.size - 1
colmax = grid.first.size - 1
for i in 0 .. rword.size - 1
letter = rword[i]
previous_slab, slab = slab, A.new(rowmax+1) { A.new(colmax+1) }
for r in 0 .. rowmax
row, line = grid[r], slab[r]
for c in 0 .. colmax
line[c] = unless letter == row[c]
0
else
if i == 0
1
else
sum = 0
clo = c > 0 ? c - 1 : c
chi = c < colmax ? c + 1 : c
for nr in (r > 0 ? r - 1 : r) .. (r < rowmax ? r + 1 : r)
for nc in clo .. chi
sum += previous_slab[nr][nc] if nr != r || nc != c
end
end
sum
end
end
end
end
end
sum = 0
for r in 0 .. rowmax
for c in 0 .. colmax
sum += slab[r][c]
end
end
sum
end
end
Update 2: I tweaked the code snippet above to remove a variable
that I just noticed wasn’t actually doing anything.
Posted in ruby, fun stuff
Tags code, countpaths, google, jam, ruby
3 comments
no trackbacks

Posted by Tom Moertel
Tue, 15 Aug 2006 21:01:00 GMT
Via the article on this year’s Google Code
Jam on
Slashdot earlier today, I found Hareesh Nagarajan’s write-up of a previous
year’s Code-Jam
problem. Since
Google often comes up with interesting problems, I decided to give
this one a go.
The problem: count the ways to find a word by walking on a grid
You are given a rectangular grid of letters and a word to find.
You must compute the number of ways to find the word within the grid
using the following rules:
- start at any cell within the grid
- from there, move to any of the cell’s eight neighboring cells
- continue moving from that neighbor to its neighbors, and so on,
until you have spelled out the word
- you may visit cells more than once, but you cannot visit
the same cell twice in a row (i.e., you must move for each turn)
For instance, consider the following grid, taken from the examples in
the problem statement:
ABC
FED
GAI
If you were asked to find the word “AEA” on this grid, you could do it in
four ways:
Way --Move---
1 2 3
1: *BC ABC *BC
FED F*D FED
GAI GAI GAI
2: *BC ABC ABC
FED F*D FED
GAI GAI G*I
3: ABC ABC *BC
FED F*D FED
G*I GAI GAI
4: ABC ABC ABC
FED F*D FED
G*I GAI G*I
If you were asked to find “ABCD”, you could do it in only one way:
Way --Move--------
1 2 3 4
1: *BC A*C AB* ABC
FED FED FED FE*
GAI GAI GAI GAI
If you were asked to find “AAB”, you could not:
there are no “A” cells on the grid that have other “A” cells
as neighbors.
The tricksy nature of the problem
As you might expect from Google, this puzzle was designed to see
whether your solution can scale. A simple search will quickly bog
down because each step in the search can expand into vastly more
possibilities, as searching for “AAAA” on a seemingly harmless 2×2
grid of all “A” cells shows – there are 108 solutions.
The problem statement says that the grid may be up to 50×50 in
size and the word to find may be up to 50 letters long. Imagine,
then, that you are asked to find a word composed of 50 “A” letters
within a 50×50 grid of “A” cells. All of the cells will be valid
starting points, and each will have, on average, slightly less than 8
valid neighbors. Thus there will be about
50 × 50 × 8^49 = 4.5e47 ways to find
the word1. Tracing them all would take forever.
The trick is figuring out a more efficient way to solve the problem.
Since that’s the fun part of this problem, I won’t spoil it for you
by telling you how I did it. (If you truly want spoilers, you can study
my code.)
My solution
Here is what I came up with. I’ll present the code first and then
discuss how to use it.
Note: The code below is out of date but printed here for
continuity. See Update 5 for the most-recent revision.
{-
Tom Moertel <tom@moertel.com>
2006-08-15
Haskell-based solution to the Google Code Jam problem "countPaths";
see http://www.cs.uic.edu/~hnagaraj/articles/code-jam/ for more.
-}
module Main (main) where
import Control.Monad
import Data.Array
import qualified Data.Map as M
main = do
word:gridspec <- liftM words getContents
print $ (countPaths word (toGridArray gridspec) :: Integer)
countPaths word@(p:_) gridArray =
sum . M.elems $ foldl step state0 (zip word (tail word))
where
state0 = M.fromList [(cell, 1) | (cell, q) <- assocs gridArray, p == q]
neighbors = toNeighborMap gridArray
step state fromto = M.fromListWith (+) $ do
steps <- M.lookup fromto neighbors
(start, count) <- M.assocs state
cells <- M.lookup start steps
cell <- cells
return (cell, count)
toGridArray gridspec@(l1:_) =
listArray ((1,1), (length gridspec, length l1)) (concat gridspec)
toNeighborMap gridArray =
M.fromListWith (M.unionWith (flip (++))) $ do
(cell, p) <- assocs gridArray
cell' <- neighbors8 cell
guard $ inRange (bounds gridArray) cell'
return ((p, gridArray!cell'), M.singleton cell [cell'])
neighbors8 (r,c) =
[(r+h, c+v) | h <- [-1..1], v <- [-1..1], h /= 0 || v /= 0]
-- Local Variables: ***
-- compile-command: "ghc -O2 -o wordpath --make WordPath.hs" ***
-- End: ***
My solution generalizes upon the problem statement in a few ways:
- the grid can be any size and the word any length
- the grid and word can be composed of any comparable data type, not just A–Z letters (if you use the stdin interface, the code will use Unicode characters)
- the code will compute exact counts instead of returning -1 for counts greater than 1e9
You can enter problems from the command line. Enter the word first
and then the grid, each row separated by whitespace. For example:
$ ./wordpath
AAAAAAAAAAA
AAAAA
AAAAA
AAAAA
AAAAA
AAAAA
^D
2745564336
Give it a try
This was a fun problem to solve. If you have a little spare time,
give it a try. I would love to compare results and talk about
strategies.
Update: Fixed typo: Finding “AAAA” – not “AA” – on
a 2×2 grid of all “A” letters results in a count of 108. Thanks to Joshua Volz for pointing out my mistake.
Update 2: Here’s a dynamic-programming-based implementation of countPaths that is
about six times faster than my original implementation when solving the
maximum-size, all-the-same-letter problem:
countPaths word gridArray =
sum [counts ! (length word, cell) | cell <- cells]
where
counts = listArray ((1, (1, 1)), (length word, gridSize)) $
[countFrom i cell | i <- [1..length word], cell <- cells]
countFrom i cell
| i == 1 && match = 1
| match = sum [counts!((i-1),n) | n <- neighbors!cell]
| otherwise = 0
where
match = rword ! i == gridArray ! cell
neighbors = listArray (bounds gridArray) $
[filter (inRange (bounds gridArray)) (neighbors8 cell)
| cell <- cells ]
rword = listArray (1, length word) (reverse word)
cells = indices gridArray
gridSize = snd (bounds gridArray)
See the thread started by ‘psykotic’ on reddit.com for more.
Update 3: Ivan Peev has solved the problem in Python: Solving the Google Code Jam ‘countPaths’ problem in Python. Because his implementation uses the same algorithm that my implementation in Update 2 does, it makes a good vehicle for Haskell-versus-Python speed comparisons, an interesting topic in light of the warning Google provides about using Python in the Google Code Jam:
NOTE: All submissions have a maximum of 2 seconds of runtime
per test case. This limit is used in harder problems to
force submissions to be of a certain complexity. Because of
the inherent speed differences between Python and the other
offered languages is large, some problems may require extra
optimization or not be solvable using the Python language.
Ivan reports that his Python implementation solves the maximum-size, all-the-same-letter problem in about 8 seconds on an old 1-GHz AMD Athlon. The Haskell version comes in somewhat faster at 0.9 second on a 1.8-GHz AMD Opteron. (On the same Opteron, Ivan’s code clocks in at 2.8 seconds, which is impressive.)
Update 4: I have added a Ruby implementation and a Perl implementation and timings, too. On the the maximum-size, all-the-same-letter problem, Ruby clocks in at 4.2 seconds; Perl in 1.7 seconds. See the Perl implementation for a summary table of the timings.
Update 5: As I promised reader Kartik in a comment, here is a
further-simplified, yet 25-percent-faster, version of my
implementation in Update 2. This version eliminates the cache in
favor of a current-state array that is folded through the successive
letters of the target word. The result of the fold operation is the
final state array, whose elements are summed to yield the final
result. Here’s the complete code:
{-
Tom Moertel <tom@moertel.com>
2006-08-15 (revised 2006-09-01)
Haskell-based solution to the Google Code Jam problem "countPaths"
See http://www.cs.uic.edu/~hnagaraj/articles/code-jam/ for more.
This implementation is based on the dynamic-programming strategy
mentioned by reddit.com user "psykotic":
http://programming.reddit.com/info/dni1/comments/cdp59.
-}
module Main (main) where
import Control.Monad
import Data.Array
main = do
word:gridspec <- liftM words getContents
print $ (countPaths word (toGridArray gridspec) :: Integer)
countPaths word grid =
sum . elems $ foldl move counts0 (tail (reverse word))
where
move counts c = step c $ sum . map (counts!) . neighbors
counts0 = step (last word) (const 1)
step c f = listArray (bounds grid) $ map (match c f) cells
match c f cell = if c == grid!cell then f cell else 0
neighbors cell = filter (inRange (bounds grid)) (neighbors8 cell)
cells = indices grid
toGridArray gridspec@(l1:_) =
listArray ((1,1), (length gridspec, length l1)) (concat gridspec)
neighbors8 (r,c) =
[(h, v) | h <- [r-1..r+1], v <- [c-1..c+1], h /= r || v /= c]
-- Local Variables: ***
-- compile-command: "ghc -O2 -o wordpathdp --make WordPathDP.hs" ***
-- End: ***
1 I believe that the exact count is
303 835 410 591 851 117 616 135 618 108 340 196 903 254 429 200 (approx. 3.04e47). It takes about six seconds 0.75 second to compute on a 1.8-GHz AMD64 box running Linux.
Posted in programming, haskell, fun stuff
Tags code, countpaths, google, haskell, jam, puzzles, wordpaths
9 comments
no trackbacks

Posted by Tom Moertel
Tue, 27 Jun 2006 18:21:00 GMT
I have a bunch of LectroTest news. LectroTest, as you may know, is a specification-based,
automatic testing system for Perl. It may look like Haskell’s QuickCheck, but it tastes like sweet, sweet Perl.
LectroTest 0.3500 was released
This version adds automatic tools for recording and playing back
failures. Using them, you can automatically build regression-testing
suites and incorporate them into your testing plan. All it takes
is one new line of code:
use Test::LectroTest
regressions => "regressions.txt"; # <-- that's it!
See the docs on CPAN for more.
My thanks to Steffen Müller, who suggested the feature and is already
using it in cool stuff such as Number::WithError.
Slides from “Testing Tips with LectroTest” are now online
You can get the slides from my talk to the Pittsburgh Perl Mongers on
2006-06-14 here: Talk / Testing Tips with
LectroTest.
In the talk, I covered some of the newer LectroTest features, such as
regression testing and Test::LectroTest::Compat, which lets you mix
LectroTest with other Perl testing modules.
The LectroTest Emporium opens!
I have very little artistic ability. Nevertheless, alarming numbers
of people seem to love the fiercely metallic mascot I created for
LectroTest.
At the last Perl Mongers meeting, for example, people
actually told me (somewhat sternly) I should put the adorable LectroTest Robot on
t-shirts. I am now delighted to announce that I have taken their
advice:
Introducing: The LectroTest Emporium
Some important points:
- Yes, it’s a CafePress store
- I’m not making any money on these things
- I’m using direct printing, not heat-transfer printing, so
the Robot won’t crack, feel stiff, or suffer from a yellowish
transfer background. (CafePress has a comparison of the methods if you want the full details.)
Some items I have moral reservations about offering:
- LectroTest Robot Teddy Bear -
Who would be so reckless as to allow something as fierce and as powerful
as the LectroTest Robot to come into direct contact with a defenseless, cuddly
teddy bear?
- LectroTest Robot Baby Bib -
Actually, this is a great idea: your infant and the Robot
exist in a symbiotic relationship. When your baby gets food all over the
bib, the Robot will consume it (using a electrochemical process not
entirely dissimilar to our human concept of “digestion”). Thus is the
baby cleaned and the Robot fueled. It’s win-win.
- LectroTest Robot Dog T-Shirt -
I am fairly certain that the immense weight of the Robot would easily
crush any smaller animal. This product strikes me as a very bad idea.
The T-shirts, on the other hand, are the robot’s meow. Check out the
full collection at The LectroTest Emporium.
Posted in perl, fun stuff, testing, marketing, talks
Tags lectrotest, perl, testing
1 comment
no trackbacks

Posted by Tom Moertel
Thu, 23 Mar 2006 21:51:00 GMT
I ran across a fun programming puzzle (via
Raganwald):
Given a deck of n unique cards, cut the deck i cards from top
and perform a perfect shuffle. A perfect shuffle begins by putting
down the bottom card from the top portion of the deck followed by
the bottom card from the bottom portion of the deck followed by
the next card from the top portion, etc., alternating cards until
one portion is used up. The remaining cards go on top. The problem
is to find the number of perfect shuffles required to return the
deck to its original order. Your function should be declared as:
static long shuffles(int nCards,int iCut);
Please send the result of shuffles(1002,101) along with your
program and your resume to ‘resume’ at nextag.com.
It’s a fun problem, so give it a try before reading on.
Warning: small spoilers ahead
Read more...
Posted in programming, haskell, fun stuff
Tags haskell, puzzles, shuffles
3 comments
no trackbacks

Posted by Tom Moertel
Fri, 12 Aug 2005 16:00:00 GMT
Tonight’s meeting of the Pittsburgh Perl Mongers
was held at the World Headquarters of the Professional Amateur
Pinball Association to coincide with the
PAPA 8 World Pinball Championships.
To say it was a cool meeting doesn’t do it justice. Not only did we
hear a fun talk on writing CGI-contained Mason applications by our own
Dan Wright, but after the meeting
we wandered around and
played fabulous, well-maintained vintage pinball machines and fine 1980s-era video games.
And we watched the world’s best pinball players compete.
And we ate junk food. Yeah!
By all means, do look at the PAPA 8 photos. And if you need the love
that only good pinball can provide, experience PAPA 8 for yourself:
the tournament runs for the next few days.
A big thanks to PAPA for hosting us!
—Tom
Posted in perl, fun stuff, pittsburgh
no comments
no trackbacks

Posted by Tom Moertel
Mon, 11 Jul 2005 16:00:00 GMT
I enjoy tea, especially green varieties, which taste best when infused
at less-than-boiling temperatures. The problem is that my electric
water kettle can reach only one temperature reliably: a full-boiling
212 degF. To infuse my tea, then, I have devised a simple, reliable
way of heating water to other temperatures.
I start by boiling three cups of water in the kettle. (I know that I
need at least that much to warm my cup and infuse my tea.) Then I cool
the boiling water to the desired temperature by adding just the right
amount of tap water.
The trick, of course, is determining the right amount of tap water to
add. In my house the tap water is about 80 degF. Thus to infuse at a
green-tea-friendly 180 degF, I must solve the following equation:
3 cups · 212 degF + x cups · 80 degF
= (3 + x) cups · 180 degF
Solving, I get x = 0.96, and so I draw just shy of a cup from the tap.
This boil-and-cool method is easy and effective. And it costs less
than buying a temperature-adjustable water kettle, which would
probably be inaccurate anyway.
Just one more example of how math makes life better.
Posted in fun stuff, math, food
1 comment
no trackbacks

Posted by Tom Moertel
Fri, 10 Jun 2005 16:00:00 GMT
The IEEE can always use a little grass-roots
advertising, and so I often wear my IEEE shirts when hanging out with
other technical folk. This is a great way to support the IEEE.
Upon seeing my shirts, for example, people sometimes ask me what the
IEEE logo means. I take these opportunities to explain that the logo
symbolizes the electrical engineer’s “right-hand rule,” relating
electrical and magnetic fields. When my listeners invariably lose
consciousness from boredom, I take their wallets and mail the money
therein to the IEEE. Like I said, it’s a great way to support the home
team.
The problem is, my shirts are getting a bit old, and it’s time to
replace them. So I went to the IEEE web site to order a new batch.
And they don’t sell t-shirts anymore.
A quick call to IEEE headquarters confirmed that it’s been this way since 2002.
A Google search on IEEE t-shirts shows
that many IEEE student chapters still sell t-shirts to raise
funds. Unfortunately, the shirts often lack the simple, professional
style that I seek. The Penn State
chapter, for
instance, sold t-shirts boldly proclaiming the practice of “Coed Naked
Electrical Engineering: Do it with frequency ’till it hertz.” While
I’m sure it works wonders with the ladies, it’s just not my
style.
Anyway, if you know where to get high quality, old-style IEEE
t-shirts, please let me know.
Posted in fun stuff
2 comments
no trackbacks
