Category Archives: Exhibits

Follow up to Dave Itzkoff’s NYT column about his 4 year old and home video, “Yellow Submarine & Me” .


Follow up to Dave Itzkoff’s NYT column about his 4 year old and home video, “Yellow Submarine & Me”  .

(I posted this as a comment on his greeting on Redit. Never been signed up on Redit before. I couldn’t send a message on Twitter and the letters section for the article was closed. I liked what he wrote, I hope he enjoys this additional info.)

Hi Dave, I’m Bill Abbott and I greatly enjoyed your NYT piece about “Yellow Submarine“. My kid, now 22, was also a big fan at that age. Great stuff! Same kid prefers “Help!” to “Hard Day’s Night”. Admittedly, “Help!” has more tigers, and the four attached home front doors leading to one room, with John’s bed below floor level. How I wanted one of those! Same kid offered a Nina Simone song as “what’s going through my mind now” this afternoon. I have no complaints.

Not long after “Yellow Submarine“, we were lucky enough to have another pre-schooler loan us a copy of “My Neighbor Totoro“. We didn’t know the film, didn’t know Miyazaki or Studio Ghibli. But we learned in a hurry! VERY kid friendly, and (spoiler) their mom is in the hospital but gets better! No Hollywood Movie disease! Totoro? You’ll meet the neighbor. You’ll be happy you did.

Then my brother loaned us a VHS of “The Way Things Go“. Its a 31 minuite Rube Goldberg machine made of industrial and consumer junk, in a disused factory setting. One thing knocks into a second, which tips a third, whick pulls a string, which releases a weight that falls on the end of a folded, partially inflated, vinyl boat, which unfolds, starting a tire rolling up (!) a ladder, which hits a second tire, starting it, and then a third, and a forth… you get the idea. Eventually the rhythms of the events , repetitions and variaions become identifyable, and after that, you start seeing the pauses where they had to reload the camera, every 3 minutes to 3:30 or so. I’ve probably seen it 100 times by now. When it ends, the delighted child says, “Again!” So always leave enough time to watch it twice.

Around age 5 or so, the family across the street loaned us a copy of “Spy Kids 2“. There were 3 “Spy Kids” movies, by Robert Rodriguez, and now there’s a fourth. We started with “Spy Kids 2”, because that’s what our neighbors loaned us, and they were right! Like “Night At The Museum 2“, “Spy Kids 2” explains nothing. There are characters. They have relationships. It will be come clear as it goes along. And there aren’t 30 seconds wasted in either film. “Spy Kids 2” has the great cast (Alan Cumming, Teri Hatcher, Cheech Marin, Danny Trejo, Tony Shalhoub.) of the first film, adding Ricardo Montalban and Holland Taylor as the Kids grandparents, on their mother’s side, a second Spy family, mom, dad, sister, brother, and Steve Beucimi as the mad scientist hiding in the volcano on the invisible island because he’s afraid of the creatures he’s created. Half to himself, he wonders “…if God hides in Heaven because He’s Afraid of what He created.”

“Spy Kids” explains everything, how the Kids parents (Antonio Banderas, Carla Gugino) work for the OSS, and the kid’s Uncle Machete built the tree house next to their house. You get more explanation about the Cumming and Shalhoub characters. Then truey odd stuff happens, big adventures, and it winds up ok. Takes a while, but OK. That’s nice but its not the one to start with.

Spy Kids 3” involves video games and Sylvester Stalone, not as successful in my opinion. ßtart with “2”, then watch “1”. Be happy.

If you liked “Totoro” then “Kiki’s Delivery Service” is a good second helping.

If you like “The Way Things Go“, there are two follow-ups, “Rendezvous“, “C’était un rendez-vous”, by Claude LeLouch, offers an 8 and a half minute, completely illegal, drive through Paris starting at about 5:30 am, so a man can meet his wife at Sacré-Cœur Basilica A “rendezvous”. They embrace in the headlights of his car. The whole thing is one shot, from the front of the car. What you see is the streets. The stop lights (they are red, the driver doesn’t even lift their right foot). Pidgeons. An early dog-walker, a trash truck. The route includes the courtyard of the Louve, because you used to be able to drive through it.

A second follow-up to “The Way Things Go” is “Rivers and Tides. Andy Goldsworthy Working With Time“. It starts with Goldsworthy up before the sun, in Newfoundland. He has a little cup of water and some icicles, which he breaks into short pieces with angled ends. He is using the water to glue them to a rock, then build a loop that goes out, curves, and returns to the rock. With one loop in place, he goes to the other end of the rock and makes tne next loop, higher. And back and forth. When he’s done, he steps back to take a photograph, and thats when the sun rises. The whole icicle “sewn” back and forth “through” the rock lights up like a Neon lamp. Like Steve Martin’s gag “arrow through the head”.

I had admired Goldsworthy’s work on exhibit around the Bay Area, and in books like “Hand To Earth”, but in the movie, you see an imperinant, temporal side of what he does. He builds something between the low tide and high tide mark, and the water rises and inundates it. He pins together bracken with thorns, and the little puffs of a light wind wrench it appart. All the rest of the film consists of wathching Goldsworthy go out into the wild world, make something with what he finds, take a picture, and leave it. And film of projects he did in the past. He narrates everything. Not every project succeeds. There’s a pinecone-ish shape he likes to build with stones, and he’s trying on a rocky shingle beach, and he hasn’t figured out how to use the rock. It keeps falling. Be talks about it while he works.

Another project is just jaw dropping. He’s drawn to the meandering shape of an old river on a nearly level plain, big loops that will be come oxbows, etc. He draws one in light snow on a frozen stream. He is offered a  wall in a gallery, and he builds a meander on it, using a soft, porus, material, and soaks it with water. Then he covers the whole wall with mud. So its a uniform, hand-smoothed, wall, entirely made of mud. And he lets it dry. Well, part of it dries quickly, there’s no water source under it. But part dries slowly, stays dark, and when it does, eventually dry, its immediately aparent where the meander is because the mud  that dried quickly has one characteristic set of cracking and the mud that dried slowly has a different looking cracking, and the two couldn’t be clearer in their difference. Although both are dried mud, the same dried mud. You can see the shape he wanted to show. How cool is that?

*Fortunate* Motorcyclist survives driving off cliff


http://www.cnn.com/videos/us/2017/08/11/motorcycle-plunges-off-cliff-santa-monica-mountains-california-orig-trnd-lab.cnn/video/playlists/caught-on-camera/

My comments to CNN:

Cliff-diving motorcyclist Matthew Murray, 27, passes a “25 MPH” advisory sign in the 12th second of CNN’s video clip. This is in the 2nd run through of the crash video. In the 15th second he’s going 68 MPH as he starts to lean into the turn. He’s still going more than 50 MPH as he slides off the pavement and onto the dirt. Text on the screen says something to the effect that he “was following the turn when he thinks his steering locked up”. The video shows no such thing. He was going too fast, and could not turn sharply enough to follow the turn. He started at more than 2.5 times the advised speed. He left the pavement at 2 times the advised speed. His speed “locked” his path, not his steering.

Get the an accurate map of the curve, the size and tread pattern of the motorcycle tires and a description of the motorcycle (make, model, horsepower, brakes,weight-as-crashed) and rider (weight). Give to “Mythbusters”. Have them duplicate the failure, during deceleration, then do a binary search for the steady speed at which a motorcycle on those tires, at that weight, could follow that turn. Braking uses traction, does that change maximum speed?. Find the entry speed, before braking, that would allow the bike to make the turn. Put a GoPro on the bike for comparison pictures, and a second one showing where the front tire touches the road.

A Software Tester’s journey from manual to political tester


I wrote this some years ago. I should simplify the context and incorporate what I reference from the OP and other responders, so that it stands alone. But this has  meaningful observations which took effort to reach, so I’m putting a copy up here to start with.

Wow, no exaggeration! I can see every event that befell poor Jim happening in the real world. HOWEVER, Jim’s a fortunate fellow, he has management attention at all! AND they look at results. AND there is a perception (no matter how shakily based) of overall product quality.

Jim was no worse than anyone else until he got automation started and mistook his personal satisfaction and enjoyment for the company’s obvious goal of shipping a stable or improving level of quality with fast turnaround on bugs and needed enhancements. This is engineering, not art. Its not self actualization, its a commercial business or a service enterprise which creates value.

All the way down this sad story, Jim accepts product failures, and testing failures. You Can Never Ignore Failures. Period. He should have turned political at that point and realized that Test, like anything, needs to be sold, shown to be valuable and productive, and needs allies. Therefore, tests need to actually be valuable and productive, and needs to make it easy for people to accept them, adopt them, and feel they are important support in their own success. Therefore he needed to measure success, as understood by his customers (developers, support, users) and maintain or improve its integrated value. Accepting failures leads to dead astronauts, wasted billions, wrongful convictions, Senate Select Committees, Frontline specials, sub-Redits, and worse.

Instead of seeing failures as a very, very, high priority, Jim turns into a man with a solution, wandering around, looking for a way to apply it. A tawdry tale, rendered no less tawdry by its oft retelling. Not insignificantly, Jim’s manager is clearly a weak and ineffective character who should have seen problems coming, or reacted when they appeared. Once Jim had made the case for automation, they might have hired someone who knew something about automation, or contracted with very carefully defined goals.

Jim might have split his team up front. He needed manual testers, who carried on the work that had been being done, with as much success as possible, and brain power applied to improve results and lower cost. A front line to hold success. Then a test automation group who focused on test automation with clear and obvious benefits

The automation environment needed to be something:

  • …anyone could run;
  • … which worked from a shippable product, as well as a release candidate or development build;
  • …which could be triggered directly from a product build, so the build group-and-release group ran it every time;
  • …which could be configured to run anything from a single, new, test to all existing tests
    • in a developer’s environment, before check-in, or
    • at any subsequent point, including on a previously shipped release with a support issue.

Setting up the test environment, creating a test to get the product to say “Hello world”, and recognizing that as a test pass ought to take no more than an hour longer than simply setting up the product. That assumption has to be proved every release or two with a calibrated innocent new-hire from somewhere.

Since all tests start by installing the product, license, etc, and starting it, the first thing to automate would be that. If there were changes in that functionality, over product history, the automation could start with the newest, but it had to support them all. Having this ‘smoke test’ be part of a full build would pay dividends to everyone, everywhere, and by designing with backward compatibility and future adaptability, thrash could be minimized, or at least recognized.

This would be a good time to look through the bugbase to determine where the most bugs were being found, where the most escapes were happening, and where the most critical bugs were coming from. Besides looking backward, a forward look at the product roadmap and with developers and management could highlight areas of future leverage

In parallel with automation, all of the above should be considered when selecting manual tests. Tests which never fail should be reduced relative to tests which find failures. Something that fails for diverse reasons may be a great canary in the coal mine, or might be a too fragile sponge that soaks up maintenance effort. In any event, continual improvement of the manual testing should run in parallel with introducing automation. After a small number of releases, the manual tests available should exceed the resources to run them. Selection of the ‘vital few’ should in intentional, not happenstance.

Most people can see the limitation of record and play back, so things should never stop there. The only tools worth looking at are tools that can be edited and rapidly expanded by iteration. Cut and paste is the lowest form of iteration and rapidly grows nightmares. Algorithmic test point generation is desirable, but data driven testing should get strong consideration. Algorithmic generation of literal tables which are then applied as tests separates the thing that needs to be done over and over, running the test, from the thing which is done less frequently, generating the test points.

In my life, I’ve seen a few of the failures in Jim’s story, but a lot of failures of usability by others, or by anyone, complete lack of testing in development plans. Test suites (with running tests) abandoned and no-longer run, until the next great hope get started. And far too little curiosity about which tests should be run, automatically or manually, to get the most bang for the buck.

Like I said, Jim is lucky!

View in discussion

Lets re-learn Python!


OK: here we go. I learned enough Python to write some, and to follow a lot of Jesse & Co’s at VMware. But I didn’t write all that much, I couldn’t check in anything, because there was not way to  test check-in candidates BEFORE going live. Or, at least, I couldn’t find one. And when I asked for help, I didn’t get what I needed.

But now I’m re-learning, since everyone says they want want proficiency in Python in their new hires. Better brush up on it then. .

So step one.  The canonical program in any Python book goes something like:

print (‘Lesson_1.py with single quote’)
print (2 ** 902)

to show off the easy familiarity Python has with very large numbers.

So I expanded on that. More print statements and if else and elif, Adding a demo of indents being isolated – The block for “if” must be all the same indent, the block for  else need to all be the same. But nothing requires the “if” block to match the “else” block. All they have to be is the same within themselves. Parseable.

Next, since we’re always printing things, what does “print()” return? Not-1, according to the if-then. If we print it, its “None”.  And we can test that it equals “None” (string equals is “==”. It does equal “None”.

But not only does it NOT not equal “none”, you can’t ask that question, without declaring/creating a “none”.  But its not a compile time call. The power of late binding is that nobody has checked “none” (or “NoNe”) until the “==” gets it.

And we get a lovely error:

“what comes back when we print one char
None
no char indent
None = print returned 1 or thereabouts
Traceback (most recent call last):
File “lesson_1.txt”, line 40, in <modul
if none == print(” no char indent”):
NameError: name ‘none’ is not defined”

And now our canonical program has an error, so we can canonically use the “try”, “except”, “finally”  statents.

And if we’re  really lucky, the response will have an error and we’ll get a SECOND TRIP through the error handler!

C:\Users\wabbott\python\Lesson_1>python lesson_1.txt
Lesson_1.py with double quote
Lesson_1.py with single quote
3381084999268257576654974623465706281720622886631177741618948537770712976363039
one char indent
else four char indent
elif six char indent
no char indent
print returned not-1 or thereabouts
what comes back when we print one char indent
None
None == print()
None == print returned 1 or thereabouts
we always do this, but don’t make any mistakes!
Traceback (most recent call last):
File “lesson_1.txt”, line 57, in <module>
if none == print(“none == print()”):
NameError: name ‘none’ is not defined

and there we go.

 

# Lesson_1.py
# picking-up the Python thread again, 5 years later.
# All the recruiters hope I know it, better look into that and perhaps I can find a job.
#

#!/usr/bin/python – ha!

try:

print (“Lesson_1.py with double quote”)
print (‘Lesson_1.py with single quote’)
print (2 ** 902)

# Python uses indentation instead of curly braces to identify blocks. Kind of a nice idea.

if 1:
print( ” one char indent”) # this one prints
else:
print( ” two char indent”)
if 0:
print( ” if three char indent”)
else:
print( ” else four char indent”) # this one prints

 

if 0:
print( ” if five char indent”)
elif 1:
print( ” elif six char indent”) # This one prints
elif 0:
print( ” elif seven char indent”)
elif 1:
print( ” elif eight char indent”)

 

 

if print(“no char indent”):
print(” print returned 1 or thereabouts”)
else:
print(”  print returned not-1 or thereabouts”)

print ( print (” what comes back when we print one char indent”))

 

if (None == print(“None == print()”)):
print(” None == print returned 1 or thereabouts”)
else:
print(” None != print returned not-1 or thereabouts”)

 

if none == print(“none == print()”):
print(” none == print returned 1 or thereabouts”)
else:
print(” none != print returned not-1 or thereabouts”)

 

if NoNe == print(“NoNe == print()”):
print(” NoNe ==44 print returned 1 or thereabouts”)
else:
print(” NoNe != print returned not-1 or thereabouts”)

#  except Argument:
# print(“The argument is>”, Argument, “< ” )

print(“And look, now it fell through!”)

finally:

print(“we always do this, but don’t make any mistakes!”)

# ———-X———-X———-X———-X———-X———-X———-X———-X———-X———-X

Image

Father’s day tides at Moss Beach:


Here’s the tide table for this coming weekend at Moss Beach, just north of Princeton By The Sea, at the north edge of Half Moon Bay. High tide, +6 feet, at Midnight between Friday and Saturday, 1:00am between Saturday and Sunday. Low, low, tides at 7:00am, -1.5 feet!! on Saturday, -1.25 feet, at 7:48am, Sunday.
So, by crackie, we’ll be there as early as we an on Sunday. Sunrise is before 6:00am, so no shortage of light. Do a web search and you’ll discover this place has the best tidepools that ever existed- perhaps 1/4 mile or more along the coast, as much as 200 yards off shore of the normal high tide mark. A huge shelf of very low quality rock, normally around or perhaps a bit below the 0 foot level, that will be a good foot above sea level on Sunday Morning.

Recursion, working it out in advance


In a recent pair of interviews, I was asked tree data structure questions, and I flubbed the first one. Hacking at a function that received a pointer to a node and that I needed to use as the launching point for recursion, not the recursive bit itself. Not pretty. NEXT time, I managed to gather up my wits, with a bit of help from my interviewer, Jim Gill, I managed to thread the needle and there it was, a recursive operation that worked. Sho-‘nuf!  That original is at the bottom of this post- a complete, working version, follows this introduction. Its about 180 lines, with a lot of white space.

And here’s the deal. You can’t make  a sensible recursive routine by simply getting the pointer and recalling that top level routine. YES recursion needs something that takes a pointer to node, and yes,  you call it with a child of the original node. But there’s more to it. A non-recursive superstructure which supports a recursive heart.

So here’s a complete, working, version, that compiles and runs using “gcc” on Mac OS 10.5.8. It takes a bit more than what I started with. “C” and other versions will follow, as separate postings.

Macintosh-6:interview Bill4$ cat recursion_v.cpp
/* recursion_v.cpp */
/* Follow-up to ___ recursion problem with Jim Gill, web prowling question at ____ */

/* input:
(M)
|   \
(N)  (P)
|  \    \
(Q) (S)  (T)
(3 level b tree, M has two children, N and P, and N has two children, Q and S.  P has one child – T.)

output:
Q, S, T, N, P, M

*/

#include <iostream>
#include <vector>

/* Structure in which the input data arrives: */

struct node {
std::vector <node*> children;  std::string name;
};

/* Structure the result vector (array) is built from: */
struct nameNLevel  {
std::string name;   int level;
};

/*
* Synopsis: void recur( node* n, int level, std::vector* nsNLs )
* args:
* node*    n     this node, which has a name, may have children
* int        level    number of steps down the tree
* std::vector    nsNLs   pointer to the vector of node-name, level structs we’ll want to report
* returns:
* no return value. Node name and level are put into the vector of nameLevel structs.
* Mar 27, 2011  Bill Abbott
*/

void recur( node* n, int level, std::vector <nameNLevel>* nsNLs ){

/* To collect additions, nsNLs vector must be passed as a pointer! */
/* Unlike an array in C, an std::vector isn’t passed as a pointer automatically! */
nameNLevel* nNL = new nameNLevel;
nNL->name = n->name;
nNL->level = level;
nsNLs->push_back( *nNL );

int vecIdx = nsNLs->size() – 1;

//    std::cout << nsNLs->size() << ”  ” << vecIdx << ”    “;
std::cout << (*nsNLs)[ vecIdx ].level << ”  “;
std::cout << (*nsNLs)[ vecIdx ].name << ”  “;
std::cout << (*nsNLs)[ vecIdx ].name.size() << ”  “;
std::cout << (*nsNLs)[ vecIdx ].name.c_str() << ”    “;

std::cout << (nsNLs->back()).name << ”  ” << (nsNLs->back()).level << ”  ” << n->name << ”  ” << level << ”  “;
std::cout << nsNLs->size() << ”  ” ;
std::cout << n->children.size() << ”  ” << (0 != n->children.size()) << “\n”;
if ( 0 != n->children.size()) {   /* there are children */
for (int childCount =0; childCount < ( n->children.size()); childCount++ ){
recur(  n->children[childCount], level+1, nsNLs ); /* recursive call- children & next level… */
} /* for int childCount… */
} /* if ( 0!=  */

} /* recur *

/*
* Synopsis: void passThrough( node* n )
* args:
* node*    n     this node, which has a name, may have children
* returns:
* no return value. creates and outputs vector of node names,
* “highest” level first, in ascending order of child vector contents..
* Mar 27, 2011  Bill Abbott
*/

void passThrough( node* n ) {
std::vector namesNLevels;
int level = 0;

recur( n, level, &namesNLevels );

std::cout<< namesNLevels.size()  << ”  ” << “\n”;

int maxLevel = 0;
for (int i=0; i < namesNLevels.size(); i++ ) {
std::cout<< maxLevel << ”  ” << i << “\n”;
if (namesNLevels[i].level > maxLevel) {
maxLevel = namesNLevels[i].level;
} /* if */
} /* for */

/* note: recursion isn’t getting the data in the order we want… */
/* so, order them before printing. */

for (level=maxLevel; level >= 0; level–){
for (int i=0; i < namesNLevels.size(); i++ ) {
if (namesNLevels[i].level == level){
std::cout << namesNLevels[i].name <<  ” “;
} /* if (namesNLevels…) */
} /* for i */
} /* for level */

printf( “\n”);

}

/*
* Synopsis: int main( int argc, char* argv[] )
* args:
* int        argc    count of command line arguments
* char*    argv[]    vector of zero-terminated arrays of char containing command line args
* returns:
* no return value. creates a tree of nodes, outputs vector of node names,
* “highest” level first, in ascending order of child vector contents..
* Mar 27, 2011  Bill Abbott
*/

int main( int argc, char* argv[] ) {

/* 3 level b tree:
* M has two children, N and P, and
*    N has two children, Q and S.
*        Q has no children
*        S has no children
*    P has one child – T.
*        T has no children
*/

node* T = new node;
T->children.clear();
T->name = “T”;

node* S = new node;
S->children.clear();
S->name = “S”;

node* Q = new node;
Q->children.clear();
Q->name = “Q”;

node* P = new node;
P->children.push_back(T);
P->name = “P”;

node* N = new node;
N->children.push_back(Q);
N->children.push_back(S);
N->name = “N”;

node* M = new node;
M->children.push_back(N);
M->children.push_back(P);
M->name = “M”;

passThrough( M );

return( 1 );

————- Example output, with my debug couts—————-

Macintosh-6:interview Bill4$ c++ recursion_v.cpp
Macintosh-6:interview Bill4$ a.out
0  M  1  M    M  0  M  0  1  2  1
1  N  1  N    N  1  N  1  2  2  1
2  Q  1  Q    Q  2  Q  2  3  0  0
2  S  1  S    S  2  S  2  4  0  0
1  P  1  P    P  1  P  1  5  1  1
2  T  1  T    T  2  T  2  6  0  0
6
0  0
0  1
1  2
2  3
2  4
2  5
Q S T N P M
Macintosh-6:interview Bill4$

————————– Here’s how this started:——————–

Ok- it was whiteboard code and didn’t compile. I’m working on that. Staring with std::vector blahblah  which seems like some really kewl Java/C++ library good stuff. What Kernighan and Ritchie were hoping for.

input:
(M)
|     \
(N) (P)
|     \    \
(Q) (S) (T)
(3 level b tree, M has two children, N and P, and N has two children, Q and S.  P has one child – T.

output:
Q, S, T, N, P, M

typedef struct node {
std::vector <node*> children;  std::string name;
}

typedef nameNLevel {
std::string name;   std::int level;
}

void passThrough( node* n ) {
std::Array namesNLevels;
int level = 0;

recur( n, level, namesNLevels );

int maxLevel = 0;

for (int i=0; i
if (namesNLevels[i].leve l> maxLevel) {
maxLevel = namesNLevels[i].level;
} /* if */
} /* for */

/* note: recursion isn’t getting the data in the order we want… */
/* so, order them before printing. */

for (level=0; level =<maxLevel; level++){
for (i=0; i<
if (atoi(namesNLevels[i].name) == level){  printf( “%s “, namesNLevels[i].name } /* longer but more robust */
} /* for i */
} /* for level */

printf( “\n”);

}

void recur( node* n, integer level, std::Array nsNLs ){
/* its an array, gets passes as a pointer anyhow */
nsNLs.pushback( new nameNLevel( n->name, level));

if ( 0 != n->children.count()) {   /* there are children */
for (int childCount =0; childCount < ( n->children.count()); childCount++ ){
recur(  n->children[childCount], level+1, nsNLs );
/* recursive call- children & next level… */
} /* for int childCount… */
} /* if ( 0!=  */

}

A nice page at IBM regarding recursion:

http://www.ibm.com/developerworks/linux/library/l-recurs.html#

Good stuff!

Corrected captions for the Denver Post’s Plog of WWII in the Pacific.


Have a look at the well chosen pictures at the Denver Post’s Photo Blog or Plog. http://blogs.denverpost.com/captured/2010/03/18/captured-blog-the-pacific-and-adjacent-theaters/1547/

Sadly, the captions seem to have been either the intentionally uninformative wartime stuff, or edited to reduce meaning. I ended up with strong feelings about a bunch of the captions and sent them back the following suggestions. You may snicker knowingly if you please. I stopped after photo #19, and I tried to hit the meaningful stuff, and wound up sending them the following as comments. In each case I’ve put the photo caption and then my comment:

“2: December 7, 1941: This picture, taken by a Japanese photographer, shows how American ships are clustered together before the surprise Japanese aerial attack on Pear Harbor, Hawaii, on Sunday morning, Dec. 7, 1941. Minutes later the full impact of the assault was felt and Pearl Harbor became a flaming target. (AP Photo)”

Not to quibble but shore installations (Hickam Field) are already aflame, bombs have clearly gone off in the water of the harbor, torpedo tracks are visible and an explosion appears to be illuminating the third ship from the left, front row, the USS West Virginia. This photo is seconds, not minutes, from the full impact being felt. It is credited “Photo #: NH 50931” by the National Archives.

“4: December 7, 1941: The battleship USS Arizona belches smoke as it topples over into the sea during a Japanese surprise attack on Pearl Harbor, Hawaii. The ship sank with more than 80 percent of its 1,500-man crew. The attack, which left 2,343 Americans dead and 916 missing, broke the backbone of the U.S. Pacific Fleet and forced America out of a policy of isolationism. President Franklin D. Roosevelt announced that it was “a date which will live in infamy” and Congress declared war on Japan the morning after. (AP Photo)”

The battleship USS Arizona had already sunk, on an even keel, as she still lies today, before this photograph was taken. Note the forward main gun turret and gun barrel, in the lower left. The forward mast collapsed, as shown, into the void left by the explosion of the forward magazine, which sank the ship. The flames are from burning fuel oil. The fires were not extinguished until December 8, so this picture may have been taken on the Day of Infamy, of the day after. Compare to official U. S. Navy photo Photo #: 80-G-1021538, taken on the 9th of December, after the fires were out, showing the forward mast in the same shape.

“9: April 18, 1942: A B-25 Mitchell bomber takes off from the USS Hornet’s flight deck for the initial air raid on Tokyo, Japan, a secret military mission U.S. President Roosevelt referred to as Shangri-La. (AP Photo)”

When asked where the US bombers that struck Japan on April 18, 1942 had flown from, President Roosevelt replied (humorously) “Shangra La”, an imaginary paradise invented by novelist James Hilton. He showed shrewd tactical sense, the imaginary location was placed on the Asian mainland, opposite the direction the B-25s had actually came from. The U. S. Navy later had an air craft carrier named the “USS Shangra-la”, making it the only US ship named after an imaginary place, work of fiction, or a presidential joke, your choice.

(not shared with the Denver Post – I built a model of one of the Doolittle raiders and posted this writeup about it: https://billabbott.wordpress.com/2009/03/13/building-itale…olittle-raider/)

“10: June 1942: The USS Lexington, U.S. Navy aircraft carrier, explodes after being bombed by Japanese planes in the Battle of the Coral Sea in the South Pacific during World War II. (AP Photo)”

The Battle of the Coral Sea is usually dated May 4–8, 1942, not June, 1942. This photograph must have been taken after 1500 (3:00pm) on May 8, and may be seconds after the “great explosion” recorded at 1727, 5:27pm. It is Official U. S. Navy Photo #: 80-G-16651. The USS Lexington was scuttled by US destroyer torpedos and sank about 2000, 8pm, that day.

“17: June 1942: Crewmen picking their way along the sloping flight deck of the aircraft carrier Yorktown as the ship listed, head for damaged sections to see if they can patch up the crippled ship. Later, they had to abandon the carrier and two strikes from a Japanese submarine’s torpedoes sent the ship down to the sea floor after the battle of Midway. (AP Photo/U.S. Navy)”

Belongs directly after Photo 11, showing the damaged and listing USS Yorktown. The two photos were taken the same day, after the second Japanese air attack on the Yorktown, after noon, June 4, 1942. This is official US Navy Photograph #: 80-G-14384.

“18: Oct. 29, 1942: U.S. Marines man a .75 MM gun on Guadalcanal Island in the Solomon Islands during World War II. (AP Photo)”

75mm gun, not .75 (100 times bigger!). 75mm is slightly less than 3 inches. .75 would be slightly less than .030 inches, 1/10 the size of a “30 caliber” aka 0.30″ rife bullet. Given the short barrel, light construction and high elevation, its probably a howitzer and not a gun. “Artillery piece” might be more constructively ambiguous.

“19: October 16, 1942: Six U.S. Navy scout planes are seen in flight above their carrier.”

SB2U Vindicators were withdrawn from all carriers by September, 1942. Marine SB2U-3s operated until September, 1943, but only from land. The photo may have been released or dated October 16, 1942, but is unlikely to have been taken on that date.

(I’ve edited the original captions in for reference here – what I sent didn’t quote the captions, except for #18. I rebel at mumbojumbo like .75mm or .20mm, conflating the common “.(something)” inch dimensions for inch dimension ammunition with the dimension “mm”.

Generally “0.(something)” is the recommended format for dimensions, but “50 caliber”, “.50 caliber”, “.45-“, “30-” etc., clearly intersect with 75mm, 20mm or 9mm and produce a muddle in the mind of writers and editors…)

If the NRA really cared about educating people, they’d work on this issue.

White Box QA Test of a 3 text-field and 2 pushbutton web panel…


In an interview, I was asked how I would construct a White Box QA test for a screen with

Inputs:
a Name field,
a password field,
a passwordConfirm field,
an OK button and
a Cancel button.:

I set down my best effort, below, on paper, and then checked it against a software testing book I have- “How to Break Software”. I was fairly pleased with what I’d come up with, since what the book says is to concentrate on generating each and every error message. More or less the same as what I had come up with:

Graphically:
——————————————————
name Password Password Screen

Name: [ ______________________]
Password: [_______________]
Password conf: [_______________]
[ OK ] [ Cancel ]

(Implied outputs:
Error Message: [==============];
Dialog box: msg [=============], [ OK ];
Status message: [============]; )
——————————————————

Note that the “Name”, “Password” and “Password conf” lines are explicitly outputs as well as inputs. They are set to something when the screen comes up. The Passwords might or might not be replaced with “*”s or big black dots. [Cancel] might or might not clear the strings

Inputs: Name, Password, PasswordConf, Ok_button, Cancel_button

(I’m conflicted on one point- Password1 and Password2 are useful definitions *inside* where keeping track that they are two, very similar, pieces of information is important. For a user, “Password” and “Password Confirm” are better definitions. I have to pick one nominclature and use it consistently.)

OUTPUTS:
In addition to text in the Name, Password and Password Confirm fields, at least one or two of the following should be available:

Error Message: I assume that we have some space to output a message on error, Have to remember to blank this once we’re out of the error state.

Dialog box: If there’s a message that requires acknowledgement, then a dialog box is really what we’re talking about (modal use of the buttons in the ‘normal’ interface would be evil.) Of Necessity, a dialog box includes both an output line (which may be an error mentioned OR something else..) and an acknowledgement pushbutton.

Status Message: (blank), (ok), (error), (reset), ? – a complex screen, interface or underlying program might have an internal state, and for testing, it would be nice to show it.

By “White Box” I presume we mean we know something about how it works inside, so we know if the screen is well defined and not subject to sequence effects… or we know we DO have to address sequence effects..

For each input, there are relevant lengths, because Name and Password typically have minimum and maximums, and there are error messages relating to them:
For any text input: Name, Password, PasswordConfirm, etc., the 5 possible lengths are:
(1 character,
minimum number of characters – 1,
minimum number of characters,
maximum number of characters,
maximum number of characters + 1)

For each input, there is an acceptable character set and characters which are not allowed:
Alpha: [A-Z,a-z]
numeric: [0-9]
Alpha no case: [Aa]-[Zz]
Shift-numeric: [0-9,[!@#$%^&*()]
Special chars: [`-=[]\;’,./], [~_+{}|:”?].

Out of these categories, or a literal list of values, we can make acceptedNameChar and acceptedPasswordChar sets. We can also make unAcceptedNameChar and unAcceptedPasswordChar sets. Obviously overkill for testing the little screen this started with but worth considering in the case of algorithmically generating a bunch of non-identical test cases for a large set of screens or other objects-under-test.

name, passWd and passWdConf strings of characters are sets of the 5 possible lengths of the acceptable characters, or acceptable + unAcceptable

PRESUMING sequence doesn’t matter, before the Ok_Button is clicked, the test input and output vectors would look like:

Name PwdA PwdB , ErrorOut
—– ——- ——– ———— ————
“a”, “b”, “c” expect errors: Less than minimum , b & c don’t match…
minName-1, minPwdA, minPwdA (expect error: Less than minimum name error)
minName, minPwdA-1, minPwdA (expect error: Less than minimum passwd1)
minName, minPwdB, minPwdB-1 (expect error: Less than minimum passwd2)
minName, minPwdA, minPwdB Ok (expect error: passwds don’t match)
minName, minPwdA, minPwdA Ok (expect success)
minName, minPwdB, minPwdB Ok (expect error, name used already with different passwd- or does this just reset the password to the new one?
maxName, maxPwdB maxPwdB Ok (expect success)
maxName, maxPwdB, minPwdB Ok (expect error, name used already)
maxName, maxPwdA, maxPwdA Ok (expect success)
maxName + 1 , maxPwdB , maxPwdB error More than maximum error.
maxName, maxPwdB +1 , maxPwdB error More than maximum, pwds don’t match.
maxName1 , maxPwdA , maxPwdA+1 error More than maximum, pwds don’t match.

The vectors of input values and single outputs might expand to walking a blank through valid data. walking valid data through blanks. etc.

I prefer using arrays, arrays of structs and enums as indexes to handle this kind of thing. Because I find it easier to inspect and see whether its correct or not. Since the same values are used over and over again, it seems better controlled with the repeated values coming from a single variable.

enum lengths={ aChar, minM1, min, max, maxP1, numLengths };

String[] name=new String( “a”, “minim”, “minimu”,

“minimum_minimum_minimum…minimum_minimum_minimum”,

“minimum_minimum_minimum…minimum_minimum_minimumX” );

String[] passWd=new String( “a”, “minim”, “minimu”,

“minimum_minimum_minimum…minimum_minimum_minimum”,

“minimum_minimum_minimum…minimum_minimum_minimumX” );

String[] passWdB=new String( “b”, “binim”, “binimu”,

“binimum_minimum_minimum…minimum_minimum_minimum”,

“binimum_minimum_minimum…minimum_minimum_minimumX” );

Name, PwdA, PwdB , ErrorOut?
—– —— —— ———— ————
name[ aChar ], passWd[ aChar ], passWd[ aChar ], errors: Less than minimum.
name[ aChar ], passWd[ aChar ], passWdB[ aChar ], errors: Less than minimum , Password and PasswordConf don’t match…
name[ minM1 ], passWd[ min ], passWd[ min ], error: Less than minimum name error
name[ min ], passWd[ minM1 ], passWd[ min ], errors: Less than minimum passwd1, passwords don’t match
name[ min ], passWd[ min ], passWd[ minM1 ], errors: Less than minimum passwd2, passwds don’t match
name[ min ], passWd[ minM1 ], passWd[ minM1 ], errors: Less than min. chars, both pwds.
name[ min ], passWd[ minM1 ], passWdB[ minM1 ], error: passwds don’t match
name[ min ], passWd[ min ], passWd[ min ], expect success
name[ min ], passWdB[ min ], passWdB[ min ], error, name used already with different passwd- or does this just reset the password to the new one?
name[ max ], passWd[ max ], passWd[ max ], expect success
name[ max ], passWdB[ max ], passWdB[ max ], error, name used already?
name[ maxP1 ], passWd[ max ], passWd[ max ], error More than maximum name error.
name[ max ], passWd[ maxP1 ], passWd[ max ], errors More than max pwd, pwds don’t match.
name[ max ], passWd[ max ], passWd[ maxP1 ], errors More than max pwd, pwds don’t match.
name[ max ], passWd[ max ], passWdB[ max ], error, pwds don’t match.
name[ max ], passWd[ maxP1 ], passWd[ maxP1 ], error More than max pwd.

For symmetry, I suppose name, passWd and passWdB could include a second set of strings which incorporate unacceptable characters and 5 more enums to pick them (or an “un” value to addd… or there should be three more arrays named unName, unPassWd, unPassWdB.

Point is, there are a lot of different error messages implied by this relatively simple panel, and to be certain that it behaves for each and every build.

Generally, I think its a good thing to get each error by itself from each possibly position, but not to get too worked up about combinatorials…. so walking a too short or too long string through the three inputs is fine, but having to wrangle TWO too long or too short or one of each is probably overkill- Its worth having ALL the inputs be errors to be sure that arbitrary collections of errors work, together, and you’re done, unless there’s some reason to think errors interact.

50 books every geek should read- from Monster.com


Ok, lets see: I’ve read 16 of these, gave up on another and have 2 in-progress.

I think there are a few good books missing:

1) “The C Programming Language” – Kernighan and Ritche. Not only a great book about programming, especially for beginners, it also shows how clear a programming text can be, how little needs to be said, and how to spiral around the same problems with increasingly capable and complicated programs.

2) “The C++ Programming Language” – Stroustrup. By comparison to C, a much thicker book, containing K&R’s language and a whole lot more, for practical coding and for object oriented techniques.

3) “The Codebreakers” – Herman Kahn A huge book and one that ends in the era where crypto was still a government issue, mostly. But a great history, and clear proof that no cypher system, or code book, is 100% unbreakable.

4) “Seizing the Enigma” – most complete discussion of BREAKING Enigma I’ve seen so far. There are any number of good lessons here, starting with, a small, motivated, team can accomplish what is considered impossible. Never treat the opposition with contempt. Define your requirements as well as you can, do what you can to satisfy them, pay attention to what actually happens.

The actual analytic technique to break Enigma was cooked up by two Polish intelligence officers who could see how the wind was blowing in the late 1930s. When the Germans invaded, they escaped with their method and presented it to the French. The French passed it on to the British before they collapsed. The technique wouldn’t do for rapid recovery of plain text from a well operated system but it could break in by brute force, with some time, and it could also rapidly exploit any laxness in technique by the cypher users. Whereas the Germans believed that Enigma was essentially unbreakable and never seriously looked for its weaknesses, or their own in using it.

Code and cipher trade-craft was good in the Kriegsmarine, so-so in the Wehrmacht and lousy in the Luftwaffe, oddly echoing Hitler’s complaint that he had a Christian Navy, a Reactionary Army and only one National Socialist (Nazi) armed force, the Luftwaffe. The Brits mounted a frontal assault on Luftwaffe Enigma traffic and got what they needed because of bad practices by the users. With the Wehrmacht they got enough to combine with conventional intelligence, what the Soviets gave them from “Lucy”, from the Italians sending cables to each other, etc., to get the job done. The Kriegsmarine used Enigma intelligently, so that frontal assaults hit a blank wall. Fortune gave the Brits the keys, the initial rotor position for each message, occasionally, and they knew what they were missing, so they made it their business to GET the keys, through espionage, Soviet salvage of a sunken German ship, the capture of a shipboard weather station in the North Atlantic, the US Navy’s capture of U-505. Every six months when the key changed, they had to get the new one and did, EACH TIME. And tight security at the Allied end allowed the Germans, all of them, to ignore any suspicion that their cyphers and codes were less than 100% secure. They had no “Red Team”s, or even someone looking at the pattern of Allied luck in finding lone U boats, bombing the right place at the right time, etc. Convinced of their own superiority, like the Japanese, they caught “victory disease” and when the tide turned, retained a confidence that events did NOT justify. Lucky for us.

“Snow Crash,” Neal Stephenson
“Neuromancer,” William Gibson
“I, Robot,” Isaac Asimov  <———- 1
“Hitchhiker’s Guide to the Galaxy,” Douglas Adams  <———– 2
“Do Androids Dream of Electric Sheep?” Philip K. Dick  <————– 3
“Ender’s Game,” Orson Scott Card
“The Time Machine,” H.G. Wells  <————– 4
“Microserfs,” Doug Coupland  <————— 5
“Flatland,” Edwin A. Abbott  <——- tried, couldn’t get into it. Should try again I suppose
“1984,” George Orwell  <—————- 6
“Brave New World,” Aldous Huxley  <————— 7
“iCon,” Jeffrey S. Young and William L. Simon
“iWoz,” Steve Wozniak and Gina Smith
“Hard Drive: Bill Gates and the Making of the Microsoft Empire,” Jim Erickson
“The Visual Display of Quantitative Information,” Edward Tufte  <——————- 8
“Don’t Make Me Think: A Common Sense Approach to Web Usability,” Steve Krug
“The Non-Designer’s Design Book,” Robin Williams
“Tog on Interface,” Bruce Tognazzini  <—————– 9
“User Interface Design for Programmers,” Joel Spolsky
“Revolution in The Valley: The Insanely Great Story of How the Mac Was Made,” Andy Hertzfeld
“The Soul of a New Machine,” Tracy Kidder  <——————- 10
“Where Wizards Stay Up Late,” Hafner and Lyon
“Dealers of Lightning: Xerox PARC and the Dawn of the Computer Age,” Michael A. Hiltzik
“The Cuckoo’s Egg,” Cliff Stoll  <—————- 11
“The Perfect Thing: How the iPod Shuffles Commerce, Culture, and Coolness,” Steven Levy
“Longitude: The True Story of a Lone Genius Who Solved the Greatest Scientific Problem of His Time,” Dava Sobel  <– 12
“The Code Book,” Simon Singh
“Cryptonomicon,” Neal Stephenson
“Crypto,” Steven Levy
“The Pragmatic Programmer: From Journeyman to Master,” Andrew Hunt, David Thomas
“Code Complete: A Practical Handbook of Software Construction,” Steve McConnell  <—— working on it
“Design Patterns: Elements of Reusable Object-Oriented Software,” Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides  <— working on it
“Dreaming in Code,” Scott Rosenberg
“The Mythical Man-Month: Essays on Software Engineering,” Frederick P. Brooks  <———- 13
“Beautiful Code: Leading Programmers Explain How They Think,” Andy Oram
“Cathedral and the Bazaar,” Eric S. Raymond
“The Long Tail,” Chris Anderson
“The Future of Ideas,” Lawrence Lessig
“On Intelligence,” Jeff Hawkins
“In the Beginning was the Command Line,” Neal Stephenson
“Code: Version 2.0,” Lawrence Lessig
“The Wisdom of Crowds,” James Surowiecki
“The Singularity Is Near: When Humans Transcend Biology,” Ray Kurzweil
“Gödel, Escher, Bach,” Douglas Hofstadter  <——— 14
“Gut Feelings,” Gerd Gigerenzer
“A Brief History of Time,” Stephen Hawking  <————- 15
“Hackers and Painters: Big Ideas from the Computer Age,” Paul Graham
“The Evolution of Useful Things,” Henry Petroski  <————– 16
“Getting Things Done,” David Allen
“Upgrade Your Life: The Lifehacker Guide to Working Smarter, Faster, Better,” Gina Trapani

“Gut Feelings,” Gerd Gigerenzer

Monogram’s old Mosquito nose transparencies..


My straight-out-of-the-box Monogram Mosquito is getting closer to being done. I lightly brushed Future floor wax over the clear nose and the two windows into the bomb-aimer’s compartment, sanded the fuselage mating surfaces flat and straight, sanded the clear part edges (only edges) so the glue would have something to work on, and glued them together with Testor’s blue label Non Toxic liquid glue.

On the nose windows, I stretched a modest strip of tape across the width of the window (up and down, not fore and aft) on the OUTSIDE, leaving all 4 corners exposed. Then I pressed the little window in place against the tape, and when I felt it was all seated correctly, I wicked glue between the parts from the two front corners.

Naturally the first of the little windows fit perfectly, so I wasn’t as much on my guard and the other one didn’t and I didn’t catch it, at first. I used a paint brush handle, parts clipper cushoned handle, etc, to push the slightly sunken widow out into its frame. Each day I’d wick in a little of the liquid glue to melt it slightlty free, then push. I told you! After two days, it was acceptable and I stopped.