Book Review – Empyrean Key

October 22, 2014

I just finished reading the first book in the Ardentia Series.  And I can’t wait for the second installment “due out early 2015” according to the end of the book.

cover photo

I enjoyed the book. While not what I’d call “excellent,” it was very good, definitely readable — one that I’d recommend to my friends who love the fantasy genre. (Full disclosure: the author is related to a friend of my wife.)  Though SparrowHawk gives it high marks.

There are a couple things to highlight in the positive category, and minor criticism.

This story builds a believable world and likeable characters — in fact, characters, like Jahna, who I want to see succeed.

Creating a world is, in my opinion — not to take anything away from Tomlinson — easy; introducing it to the reader is trickier.  A writer who creates their own world always has a choice, and a fine line to walk.  On the one hand, he or she can chose to not “explain” anything, instead telling the story wholly within the setting, and leave it to the reader to figure out the workings of the world as they go.  The other path is to write the story as one telling someone who is not at all familiar with the setting, taking time (and precious pages) to elaborate on the differences between their world and ours.

Of course it’s not a black and white, either/or decision.  In this case, I think, Tomlinson could’ve provided a more gentle introduction to the unfamiliar places, and meaning of some of the geography.  It’s not horrible, just be ready to keep track of Aedentia, and the gods and heroes, the Pithart, the place of worship, and the backwater town of Groden Cove.  None of this is hard, and perhaps I’m being overly picky.

I’m a little more critical of the introduction of the characters:

I feel now that my third point (below) is closely related to the character intros in this sense: the book, in retrospect, feels too short; and the introduction of the primary characters seemed either a little forced, or missing in depth.  What I mean is, after the fact, i read the description on Amazon.

As a not-so-perceptive telepath and amateur scam-runner, Jahna Mornglow has filled the void left by an absent father, with the friendships of a bloodthirsty bar-maid and a bullied book-worm. Her mother, scarred by the racial prejudices of her past, refuses to nurture Jahna’s Narcean abilities of prophecy and telepathy, warning her of the hate beyond the safety of Groden Cove – a beachside safe haven for misfits and those who wish to be left alone.

I wouldn’t describe Lilac as a “blooodthirsty bar-maid” — not exactly.  And Jahna’s mother’s story seems far too short to fill out that line (maybe, but I failed to get all that from just the few pages she gets).  I guess Lilac maybe is, but I don’t know if I actually think I know her, because we haven’t spent enough time together.  I don’t know if that’s just “first impression” (which, it actually isn’t), or if that’s really who she is.    Moreso with the “bookworm,” he’s acted in ways that are surprising, like I would never have expected that of him.  Again, because I haven’t spent enough time “observing” him to know what he’d do in an unfamiliar situation.

And, yet, I think that if I had another fifty pages, maybe I’d have a better sense of any of them, Lilac included.

All in all, though, I have to say, I do want to continue reading, and my last point is really just this: I just think the cliff-hanger at the end came too soon.  I want to read more, and I find that there isn’t any more, yet.

All that being said, the book did draw me in, as a story should, and I found myself experiencing the characters, and not just “reading” a book.

I did find the author’s blog.  And I eagerly look forward to reading more.

C++ Exception Problem

October 4, 2014

This is going to be a very technical post.

Gory details forthcoming, you’ve been warned.

I think I have a problem with some C++ code, and I’ve narrowed it down as much as I can.  I am using the standard exception, std::overflow_error (though that probably doesn’t matter).  I’m compiling with GCC 4.9.1 (this, I think, does matter).

So here’s the summary, with a fairly complete set of exception-handling clauses, when I throw the overflow_error exception from an activity by itself, it works; but if I have even a fairly simple string declaration and assignment, then all the exception handling gets skipped.

Details, Details

Let’s start with a “working” example; here’s the main body:

#define CHAR char
#define ATOL atol
#define MAIN main

Never mind what I was doing here

int MAIN(int argc, CHAR* argv[])
  SixFactor t(26757, -1);
  cout << "t = " << static_cast<std::string>(t) << endl;
  try {
    SixFactor e(0,0);
    e = t*t;
    cout << "got here - no exception" << endl;
  } catch (overflow_error &oe) {
    cout << "caught overflow exception: " << oe.what() << endl;
  } catch (...) {
    cout << "caught an unknown exception" << endl;
  return 0;

Strange class name?  It’s pulled from the context of the program where I noticed this.

So what’s in the constructor(s), and the operator* overload function?

class SixFactor
    SixFactor(const ulong m, const int o): _mult(m), _offs(o) {};

and later

SixFactor operator*(const SixFactor &othr) throw(overflow_error) {
  // std::string err_msg = "SixFactor mult. overflow of (";
  // err_msg += static_cast(*this) + ") * (" +
  // static_cast(othr) + ")";
  /// cerr << "throwing an exception: " << err_msg << endl;
  // throw std::overflow_error(err_msg.c_str());
  // If I uncomment even one of the preceding lines (the string decl. line)
  // then the exception below is *not* caught, but the program terminates
  // abnormally. As it stands w/ the exception only, it "works"

  throw overflow_error("this works");

Note that right now, the only un-commented code in this function is the throw statement.

What happens:


g++  -g -std=c++11 -Wall -Wextra -v -Weffc++ -Wold-style-cast  -c
      -o test_exception2.o test_exception2.cpp




t = 6*26757 - 1
caught overflow exception: this works

When it breaks

Let’s change the code

SixFactor operator*(const SixFactor &othr) throw(overflow_error) {
  std::string err_msg = "SixFactor mult. overflow of (";
  // err_msg += static_cast(*this) + ") * (" +
  // static_cast(othr) + ")";
  /// cerr << "throwing an exception: " << err_msg << endl;
  // throw std::overflow_error(err_msg.c_str());
  // If I uncomment even one of the preceding lines (the string decl. line)
  // then the exception below is *not* caught, but the program terminates
  // abnormally. As it stands w/ the exception only, it "works"

  throw overflow_error("this works");

Note: all I did is add a declaration and assignment (never mind the string doesn’t mean anything).  It shouldn’t change the operation at all.  But it does.

t = 6*26757 - 1

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
make: *** [test_exc2] Error 255

And Windoze puts up a dialog box:


So what’s going on here?

That’s my question.  I’m at the point of starting to examine assembly code; right now I don’t know, but I’m putting this out to the “world.”  In a sense, I’m crowd-sourcing for an answer, but I think my crowd might be too small.


Books Review

December 28, 2012

Finishing up blog posts from this last year; things I started, but never finished.

I’ve read two books that I ought to write a short review of.  One written by an acquaintance — a colleague of my wife’s.  Ashes, Ashes.  I have two overall reactions: first, it’s quite a long novel for a debut, but parts of it are quite well written — esp. where Darrell writes to his strength (his psychological profiles and descriptions are believable, vivid and still readable); there are points where the writing could use finer editing.  Second, I recall thinking at the end that there was a large aspect of deus ex machina — and this critique from someone who embraces the supernatural.

But speaking of the Supernatural, the second book is Heaven is For Real.  The true story of a boy who saw Heaven and returned to tell the story.

The second book is touching, and endearing, and had all the more impact on me that it was written from the perspective of the dad; and it rings true to me all the more because he admits times when he made mistakes and is honest about all the things he doesn’t understand.

So, the first is interesting, but long; I’m curious to read the sequel, and then I’ll probably have a different opinion.  I give it three stars of five, but know that it does not “end” as I’d like — and, in some sense, it doesn’t end.  But I don’t want to give away the end.  There are definitely parts, and a lot of them, that I’d emphasize, and they make great conversation starters, and the overall arch of the story is great.

And both stories — maybe a little more the second — make me want to sit down and have a talk with the author(s): ask questions, find out more, write a guide for readers…

(You may be able to tell that this post is quite old, and the stories have undoubtedly circulated, but if you haven’t yet read either or both, it’s still worth doing; neither story is specifically “dated” and both can be fresh at any time.)

Haskell Sudoku

December 22, 2012

This post is incredibly technical – it is software engineer at a deep level.  I’m not sorry.

I have a working Haskell program to solve Sudoku puzzles; right now, the board name is hard-coded, but I’m at least reading from a file, and I am quite sure there are boards I cannot solve – given my method is incomplete.
But next I am going to work on a program to run tests fr. outside Haskell, and other improvements.

The code is 17 lines in the main file (plus forty lines of “test” code); and SBoard.hs is 261 lines total. Finally, 24 lines of file reading: one main function, one sub-function and a one-liner for typed Integer square root of an Int

*BoardIO> :t sqrtInt
sqrtInt :: (Integral b, Integral a) => a -> b

(I’m no longer sure why I did that, but here’s the actual code:

sqrtInt i = floor $ sqrtFloat $ 1.0 * (fromIntegral i)

Now then, the primary function is:

main =
      b <- doRead "n.sdk"
      -- print b
      -- return (solve b)
      solv_dbg b

As you can see, I orignally called solve, which takes a Board as input and returns a Board, but since main has an IO monad, I needed the return there — which has nothing to do with “return” as most programmers know it and love it.

Sans putStrLn and print expressions, here is my main function for solving:

solve b =
  let b1 = calcUniqs b
       b2 = calcOpen b1
   if b2 == b
      then b
     else solve b2


To examine the function to calculate “unique” cells (by that I mean cells where only one value is posssible – being forced by being unique), first I need to example this utility function

    calculate a cell - if it's already known, done; 
         if there's only one possibility, done
    otherwise, it's zero for now
calc_cell c =
  let d = fst c
       u = snd c
     if d > 0
        then d
       else if length u == 1
               then head u
              else 0

This is used in the “final” expression, below.  Given tuples (a, [a]) wehere a is an Ord and also a Num (due to its usage in the function); the first is the current value of the cell (zero = blank), and the second part is the list of “possible” values for this cell — it’s possible, given the calculation of this list, that there may be multiple values even though the cell is already solved, but this function doesn’t care.  The logic is,

If this “cell” is already calculated, then we’re done, return that value; else, if the list (of possible values) length is 1, then that is the new value; otherwise, the value is (still) unknown/blank, so return zero.

I should explain, this “fell out” naturally from the way I decided to encode the Board itself, and also the resulting possible values and so on.

type Symbols = [Char]
data Board = B Symbols Int [String]

A Board is, initially, a list of symbols (identical to a string, by the way), an integer which is the square root of symbols (for a 9×9 board, this is 3), then a list of Strings (technically, I ought to make that a list of symbols, I suppose…)

One very important helper function converts the list of strings — each of which is one row — into a list of lists of integers;


The following is the “heart” of most of the calcs that follow (and precede)

   convert a board into an array of "cells,"
   where each cell is (d, [Ints]) - if d is zero, the cell is open
   the list of integers represents the possible* values there
   (* note that is not true if d is non-zero, but in that case, we don't care)
toSolve b =
        rs = arrFromBoard b
        cs = transpose rs
        ps = patches b
        unf_r = map avail rs
        unf_c = map avail cs
        unf_p = map avail ps
        sq = square b
        unf = map (\x -> map (intersect x) unf_c) unf_r
        -- the following creates an "array" (list of lists)
        -- which is the same dimensions as arrFromBoard
        idx_p = map (\r -> map (\c -> sq * (sect r sq) + (sect c sq))
                           [0..(sq*sq-1)]) [0..(sq*sq-1)]
        cmplx = map (\r -> zip (fst r) (snd r)) $ zip unf idx_p
        unf2 = map (\r -> map (\i -> intersect (fst i) (unf_p !! snd i) ) r) cmplx
        map (\r -> zip (fst r) (snd r)) $ zip rs unf2

From the inside out, the underlined map takes a list (e.g. “[0..8]”) of column indicies and returns a list of indicies of the patch for this “cell” (r, [0..8]).  That map is within a func. mapped over a list of row indicies

At the end of this, idx_p is a list of lists which represents the patch index of the corresponding cell in the board array.

So, the let section of this calculates the rows (rs), then the columns (cs), then the patches (ps) — my term for the sub-squares, 3×3 on a 9×9 board; the remaining values per row (unf_r), column (unf_c) and patch (unf_c).  Next, unf represents the “intersection” of remaining values per row and column. 

Now “cmpx” is an array of (p, [Int]) tuples – same dimensions as the Sudoku board — twice is use the “pattern”

   map (\r (zip (fst r) (snd r)) $ zip <something> <else>

Where <something> and <else> represent matching arrays; in one case, “elements” of <something>” are lists, in the other, elements of <else> are lists.   The result is an array of tuples (s_i, e_i) where each “s” and each “e” are an element of <something> and <else> respectively.
In both cases, <something> and <else> are lists of lists of elements – either [[a]], or [[[a]]]; in the easier case, a list of rows, where each row is a list of columns, where each column is a single value (an Int, say) which is the value of a cell; in the more complex case, a list of rows, of columns, where each column ‘value’ is itself a list of some data representing a list of possible values, for instance, for this cell.

… and that is perhaps the most complex description I’ll write.  (I only hope that, should I come back to read this later, it will still make sense.)


calcOpen b =
  let syms = symbols b
   --  the following assumes that the blank space (" ") is not a symbol
   B syms (square b) $ arrToSyms (map (\r -> map calc_cell r) (toSolve b)) syms ' '

So this calls toSolve on b, the Board, then “map (\r -> map…” because it’s a list of lists calls calc_cell on each element — and that’s why calc_cell takes the input it does.

The function toSolve takes a Board as input, as we’ve seen, and returns an array [a list of lists] of cells, where each cell is a tuple, which can be input to calc_cell far above.

After the map-map, the result is an array of new values, zero thru nine for a 9×9 board, and arrToSyms <array> syms ' ' converts that back to the [String] data to store in the Board.  “B...” is the board constructor.


The following code, in three functions, allows me to (pretty) print a Board

rowToStr r s =
  if length r > s 

     then show (take s r) ++ "  " ++ (rowToStr (drop s r) s)

    else show r

extraRow a s =

  if length a > s

     then (take s a) ++ [[]] ++ (extraRow (drop s a) s)

    else a

instance Show Board where

  show b =
    let s = square b
        rows = map (\r -> rowToStr r s) $ arrFromBoard b

     in unlines $ extraRow rows s

The magic, which I ought to remember, is in “instance Show Board where\n show…”

The function takes a Board [type] and returns a string.


What I’ve learned

There’s a lot to write here, but I’ve started to get the “hang” of monds — which I’ll have to write later, but others have done better.

Most important, for now, is this: the book Real World Haskell recommends that “beginners” should write the type signature first, to validate the code they get is what they intended.  I, however, took only half that advise — I thought carefully about what I wanted, but coded the function then checked the result, without including the “declaration.”  (I think I’d get the book, if I can find an updated version; there is a lot more in there than I know, yet.)



Pie in the face

November 16, 2012

Ryan was here.

A Conversation about Apps

February 1, 2012

I wrote this, literally, last year, and never published it.  Sorry it’s so late.

It started with a tweet from a friend (Siri can access Best Buy’s product catalog thru Wolfram Alpha), which encouraged me quite a bit after reading this downer (“Siri Is Apple’s Broken Promise“).

As is my wont, I responded, “I see this happening more and more (call it “app hyper linking”); I’m doing it more and more. Kids today will think no more of –”  And also, an example (Siri and Watson, or Cyc [or, now that I think of it, Wikipedia!]).

But I’m not sure Mark got that I only used Kinect as one “fer instance.”

Or maybe he did, and linked to another thought.  Then more:

“Trick is to figure out a way to get synergy from hi-res display, simultaneous site/app access and standard api for data exchange”

“I think we understand data interactions pretty well. The next breakthrough requires increased density and scale of visualization…”

I didn’t realize the full import of what that meant till now; I replied in a different direction.  Since we were talking (initially) about Siri, and I still think there’s some future to voice UI.

Then Mark added more, different thoughts (for him, the main UI of the most interesting UI of ‘the future’ is Kinect).

But I got stuck on the data thing.  Was I wrong?  I added a ref. to a story I never fully read, until now.  Here’s the conclusion from that article:

The field of astronomy is starting to generate more data than can be managed, served and processed by current techniques. This paper has outlined practices for developing next-generation tools and techniques for surviving this data tsunami, including rigorous evaluation of new technologies, partnerships between astronomers and computer scientists, and training of scientists in high-end software engineering engineering skills.

But back to what we were saying… what were we saying?

I started on the subject of “app-linking.”  The best example I have, simple though it be, is a link in my (work) e-mail to a WebEx.  From the mail app, I click the link, which switches to Safari, which somehow recognizes this is not a normal web page and launches the WebEx app.  People have complained of the lack of integration in Siri (I expect more from Apple in the months and years to come).  I remember the first time I had a full multi-OS/multi-platform experience: an old Mac iBook, running Linux, running VMWare, connected to a Windows virtual machine (it looked like Windows, felt like Linux, and had the shell of Apple).  I think this type of cross-ness will only increase, to the point where kids today won’t give a hoot (most of the time) about what “platform” their on.  Except maybe the specs of the display — and then only to figure out how to configure three “monitors” (including a wall-projector and/or a multi-panel configured LCD), and a wireless mic/headset to a back-room server of ginormous proportions [running Windows, Mac and Linux respectively] — and “apps” running in the monitor itself, communicating flawlessly with “traditional” applications, and data-manipulating back-ends software I haven’t even thought of, yet.

Our other main tangent was UIs — I like voice, Mark favors Kinect.  I think the computer from Star Trek is not that far away; but gesture-based interaction is coming nearer, too.

Haskell Trail for Sudoku

November 4, 2011

I’m going to document my “experiments” of learning Haskell, in the process of trying to write a Sudoku program — I know, I know, everyone does.  It’s not that I know more, or better, but as an educational path.

I need to specify up front that much of the code that follows is not intended as good examples, but it is what I’ve written; in fact, some of it will be decidedly bad, but I’m being more honest, and trying to learn.  If you, my friend, find a place where I’m off, wrong, and things are missing, please let me know.

Here, for example, is a “wasted” function

rdLines handle =
   Prelude.catch (
            ln <- hGetLine handle
            rest <- rdLines handle
            -- this can't be the best way to accomplish that !!
            return (ln : rest) )
       (\e -> if isEOFError e then return [] else ioError e)

What I wanted, even though I am on the wrong path, is “return ln : rdLines handle” in the proper syntax.

Here’s my main function, so far:

    given a filename, read the Sudoku board therein
    the format is: one line of the n "symbols" -- where n = s^2 for some integer s
    then n lines of n characters each
    return a board as defined above
doRead filename =
    bracket (openFile filename ReadMode) hClose
        (\h -> do
            syms <- hGetLine h
            putStrLn ("The first line length (of symbols) is " ++ (show (length syms)))
            let size = sqrtInt (length syms) in do
                lns <- rdLines h
                return (B syms (toInteger size) lns))

The nice function, giving the main structure, is bracket, which takes a first function, passing the result to the third function; and the second function is invoked whether the last succeeded or not, when it is finished.

So we open a file,  passing the result of that function (a handle) to the third function, hGetLine, debug that, the sqrtInt func. is my own creation, below, then read the remaining lines.  Better would be:

doRead filename =
    bracket (openFile filename ReadMode) hClose
        (\h -> do
            syms <- hGetLine h
            putStrLn ("The first line length (of symbols) is " ++ (show (length syms)))
            let size = sqrtInt (length syms) in do
                lns <- hGetContents h
                return (B syms (toInteger size) (lines lns)))

Cleaner, no?  That came to me in my sleep; I thought about what it is I am trying to accomplish, rather than how to do it, which was distracting me yesterday.

-- this is way too much work for that
sqrtInt i = floor (sqrtFloat (1.0 * (fromIntegral i)))

Is this really all necessary to calculate the integer (Int, if you want to be technical) square root of an integer [Int]?

I do hope some Haskell hacker, or more than one, reads this — some “help” would be nice learning; and something beyond LYaHGG [Learn You a Haskell Great Good]; that and a few others are good resources, like Real World Haskell, and probably YAHT.

What I learned from yesterday/today: Haskell is not well learned while I’m over-tired; I can’t think straight, and this more than anything else requires straight, rigorous thinking!

Commentary and Updates to my Clojure Code

August 13, 2011

So I realize my previous post was less descriptive than it could’ve been.  And it still will be, but here is the story.

The “project” I’m working on is to open a Fiddler session archive — that tool captures HTTP traffic, and can save the results…

The session archive I am interested is Tracer results from PegaSystems PRPC tools (PegaRules Process Commander), which is a series of XML results from the server (requested by the IE window open on my desktop requesting such).

So unless you’re extracting XML from a Fiddler session archive, this code won’t, by itself, be meaningful to you, but a smart programmer could adapt some of this for various purposes.  And, hopefully, the concepts may be interesting.

That said, let’s get back to the code:

I would’ve liked to replace iterEltFn with something like map, but the SingleNodeIterator won’t coerce to a sequence… Someone want to wrap it for me, I’d take that.

The main function parseIndex, changed to just this:

    (save_xml_doc (iter2addXml nil (.elements t)) "myResults" nil)

The function iter2addXml returns the combined xml document.

(defn iter2addXml [d sni]
  "If the SingleNodeIterator [sni] has more nodes, call_readXml on nextNodes,
    then if doc is nil, add_events to a new_xml_result with the contents,
    else add_events to the existing doc
   otherwise (sni has no more nodes), return the doc as-is."
  (if (.hasMoreNodes sni)
    (let [n (.nextNode sni)
	  nxt (call_readXml n)
	  i 0]
      (if (nil? nxt)
	(recur d sni)
	(let [d2 (if (nil? d)
	      c (:content nxt)
	      n (add_events d2 c)]
	  ; here we will do size checking things
	  (recur n sni)
    ;; else (no more nodes) just return the doc itself, we're done

(I realize the the code highlighter I’d used gets messed up by WordPress)  The logic is: if there are more nodes, get those, do call_readXml on the results, if the result is nil, recur without it; else add_events to either a new document (via new_xml_result) or the existing doc, then recurse; if there are no more nodes, return the existing doc.

The function call_readXml is, in my opinion, a somewhat elegant “one-liner.”

(defn call_readXml [e]
  (readXmlFile (uri_to_filename (.. e (getFirstChild) (getChildren)
				    (extractAllNodesThatMatch (new HasChildFilter
								   (new StringFilter "S")))
				    (elementAt 0)(extractLink)))))

Granted, most of this is basically a string of Java functions (“e.getFirstChild().getChildren().extractAllNodesThatMatch(...).elementAt(0).extractLink“); then pass the result to uri_to_filename and pass that result to readXmlFile.

  1. ;; read an XML file — more to do here
  2. ;; N.B. “fn” as a param means “filename” not “function”
  3. (defn readXmlFile [fn]
  4.   ;; read the filename
  5.   (let [buffRd (new (new fn))
  6.     lns (slurp buffRd)]
  7.     ;; if the file contents (lns = lines [of the file])
  8.     ;; starts with an HTTP <<status>>, continue
  9.     (if (. lns startsWith “HTTP”)
  10.       ;; split the next line (the hard way), find the whitespace of this (the status) line —
  11.       ;; what remains is the “status,” number and text —
  12.       ;; and the linebreak of the next line
  13.       (let [lnbrk (.indexOf lns \n)
  14.         dt (.substring lns (+ lnbrk 1))
  15.         idxSp (.indexOf lns ” “)
  16.         status (. lns substring (+ 1 idxSp) (– lnbrk 1))
  17.         eol (.indexOf dt \n)]
  18.         ; (println “HTTP status:” (. lns substring (+ 1 idxSp) (- lnbrk 1 )))
  19.     (if (not (= status “302 Found”))
  20.       ;; call the hdr function…
  21.       (let [[hdr r2] (hdr (struct-map header
  22.                 :status status
  23.                 :date (.substring dt 6 (– eol 1)))
  24.                   (.substring dt (+ eol 1)))]
  25.         (println “header is” hdr)
  26.         ;; then parse the remaining data from the file
  27.         (clojure.xml/parse (new (.getBytes r2))))
  28.       ;; if this was a “302 Found” status, we’re dealing with a VIP exchange,
  29.       ;; there’s nothing useful here…
  30.       (println “Location is:” (. dt substring 10 eol))))
  31.     )))

Similar to what was before, but condensed twice: I could do more, like
“(slurp (buffRd (new…” and more: using duck-streams — I’m just thinking out loud.

And the hdr function has been re-structured for easier reading:

(defn hdr [sm str]
(let [[ln rem] (nlr str)]
(.startsWith ln "Cache-Control:") (recur (add_val :control (.substring ln 15) sm) rem)
(.startsWith ln "Keep-Alive:") (recur (add_val :keep-alive (.substring ln 12) sm) rem)
(.startsWith ln "Content-Type:") (recur (add_val :type (.substring ln 14) sm) rem)
(.startsWith ln "Connection:") (recur (add_val :connection (.substring ln 12) sm) rem)
(.startsWith ln "Content-Length:") (recur (add_val :length (.substring ln 16) sm) rem)
(.startsWith ln "Content-Language:") (recur (add_val :language (.substring ln 18) sm) rem)
(= 0 (count (.trim ln))) (list sm rem)
(println "no match and length wasn't zero (i.e. unknown, non-blank line):"
(count ln) "'" ln "'"))))

This is a new function:

(defn add_events [d events] ; add these trace events (contents) to the xml doc
(type events) "]")
(if (nil? events) d ; if events was nil, just return the doc unchanged
 ;; otherwise
(let [a (attrs d)
      r (reduce (fn [v i] (conj v i)) (or (:content d) []) events)] (assoc d :content r :attrs (assoc a :count (+ (:count a) (count events)))))))

I realize I’m writing far too much code here. Sorry.
I did wind up re-writing the XML emitting code, but that’s for another day.

My Clojure Code before Updates

August 8, 2011

I’m posting the code for my “project” — the technical details of which are terse.

I’m not going to describe a lot, here, but as I go…

(If you’re not a clojure coder, look away)

  1. ;; Fiddlr_To_Xml
  2. ;; my project to convert a Fiddler2 Session Archive (.SAZ) to XML file(s)
  3. ;; for info on Fiddler2 see
  4. ;; for this to work (the unzipping of the .SAZ, anyway)
  5. ;; I’m depending on 7-Zip (as you can see below)
  6. (require ‘  ; not recommended, but to get things working…
  7. (def zipExe \”C:\\Program Files\\7-Zip\\7z.exe\”)  ; constant strings
  8. (def FiddlrCaptsDir “C:\\Documents and Settings\\gparks1\\My Documents\\Fiddler2\\Captures”)
  9. ;; given a filename (a fiddler session arhive), unzip it
  10. (defn unzip [fn]
  11.     (println “unzipping “ fn “…”)
  12.     (let [res ( zipExe “x” fn “-y” :dir FiddlrCaptsDir)]
  13.                     ;(prn res)
  14.       (println “Exit Code: “ (:exit res))
  15.       res))
  16. ; for whatever reason, I’m not getting a real exit code, but it works, so I don’t care


Now, the following felt like real functional programming (because I’m actually treating a function as a first class object):

;; my original function for printing (all) the elements of a SimpleNodeIterator
; (defn printElt [i]
;  (if (. i hasMoreNodes)
;    (let [n (. i nextNode)]
;      (println n)
;      (printElt i))));; my revised helper function — used for many things, including printing
;; given a SimpleNodeIterator, and a function
;; iterate and call fn for each
;; (I bet there’s an easier way, but this works for now)
;; I was just happy to be passing a function around
;; as an argument to another function…
(defn iterEltFn [i fn]
(if (. i hasMoreNodes)
(let [n (. i nextNode)]
(fn n)
(recur i fn))))

And using that here and here:

;; new and improved printElt — call iterEltFn w/ a function (println)

(defn printElt [i]

(iterEltFn i (fn [x] (println x))))

;; 2nd function using iterEltFn; this time, print the element, and the children

(defn printEltChild [i]

(iterEltFn i (fn [x]

(println x)

(printElt (.. x (getChildren) (elements)))



The following defines a “constant,” two helper functions and a structure (used below):

; ‘global’ filter on tracer string
(def fStr (new org.htmlparser.filters.StringFilter “/prweb/PRTraceServlet?pzDebugRequest=Trace”)); helper function to take a URI and convert to a FileName string
(defn uri_to_filename [uri]
(if (= 0 (.. uri (substring 0 6) (toUpperCase) (compareTo “FILE:/”)))
(let [r (. uri substring 6)]
(.. r (replace “%20” ” “) (replace “/” \\)))));; helper function to split a string into this line (up to CR), and the remainder…
(defn nlr [s]  ; Next Line and Rest
(let [cr (.indexOf s \n)
l (.substring s 0 cr)
r (.substring s (+ cr 1))] (list l r)))

;; creating a structure for HTTP header
(defstruct header :status :date :keep-alive :length :control :connection :type :language)

This header function is the first of things to re-do, when I move forward:

;; hdr function
;; parse the lines from a Fiddler2 server response file
;; here is an ‘example’
;;    HTTP/1.1 200 OK
;;    Date: Wed, 06 Jul 2011 18:22:56 GMT
;;    Cache-Control: max-age=0
;;    Keep-Alive: timeout=10, max=980
;;    Connection: Keep-Alive
;;    Content-Type: text/xml;charset=UTF-8
;;    Content-Language: en-US
;;    Content-Length: 76960
;; (note the ‘blank’ line at the end!)
;; the HTTP (first line, w/ status) and Date have been parsed separately, so the str argument here
;; begins at the 3rd line.  Although there is some semblence of “order” to the lines, it is not dependent on such,
;; save that the blank line be last and the last line is blank.
;; [And there’s probably a better way to structure this, as well…]
(defn hdr [sm str]
(let [[ln rem] (nlr str)]
(if (.startsWith ln  “Cache-Control:”)
(let [cc (.substring ln 15)]
(assert (nil? (:control sm)))
(recur (assoc sm :control cc) rem))
(if (.startsWith ln “Keep-Alive:”)
(let [keep (.substring ln 12)]
(assert (nil? (:keep-alive sm)))
(recur (assoc sm :keep-alive keep) rem))
(if (.startsWith ln “Content-Type:”)
(let [typ (.substring ln 14)]
(assert (nil? (:type sm)))
(recur (assoc sm :type typ) rem))
(if (.startsWith ln “Connection:”)
(let [conn (.substring ln 12)]
(assert (nil? (:connection sm)))
(recur (assoc sm :connection conn) rem))
(if (.startsWith ln “Content-Length:”)
(let [len (.substring ln 16)]
(assert (nil? (:length sm)))
(recur (assoc sm :length len) rem))
(if (.startsWith ln “Content-Language:”)
(let [lang (.substring ln 18)]
(assert (nil? (:language sm)))
(recur (assoc sm :language lang) rem))
(if (= 0 (count (.trim ln)))
(list sm rem)
(println “count wasn’t zero:” (count ln)))))))))))

The rest of this entry is presented in reverse order, so the logical flow is evident.

Here is the main function:

;; ****************************************************************************************************
;; * main function to parse an index
;; (no params necessary — the filename is at a well-known location)
;; calls printRowInfo, which does all the heavy lifting
;; (this could actually be re-structured to do the primary filtering here,
;;   and printRowInfo could be simplified…)
;; ****************************************************************************************************
(defn parseIndex []
  (let [parser (new org.htmlparser.Parser (str “file:///” FiddlrCaptsDir \\_index.htm”))
  ; iter (. parser elements) 
  ; fChStr (new org.htmlparser.filters.HasChildFilter fStr)
fCh2Str (new org.htmlparser.filters.HasChildFilter
(new org.htmlparser.filters.HasChildFilter fStr))
t (. parser parse fCh2Str)  ; a nodelist!
; (printElt iter); (printEltChild (. t elements))
    (printRowInfo (. t elements))


Which calls printRowInfo for the entire list of elements:
(comments “extracted” from quickhighlighting for “clarity”

;; ****************************************************************************************************
;; main (internal) function
;; given a SingleNodeIterator argument, iterate
;; the function passed to iterEltFn gets the text (already known to contain "pzDebugRequest=Trace"),
;; and the server filename (from the children of the first child) --
;; the link from the first element of the list, which is the anchor containing the text "S" of the children of the 1st TD elt
;; [sSvrFile from datas, which is getFirstChild [TD] getChildren extractAllNodesThatMatch
;;     {[anchors] with children which are strings equal to "S"} elementAt 0, extractLink
;; each iteration calls readXmlFile
;; ****************************************************************************************************

Of interest, see that this function relies exclusively on iterEltFn and only creates an (anonymous) function to pass to it — I could make this a defined function, separating that work out

(defn printRowInfo [r]
(iterEltFn r (fn [n]
(let [datas (. (. n getFirstChild) getChildren) ; slow way to call a member of a result
; the children of the first child (a “TableColumn” [TD]) are:
; LinkTag [A] w/ text ‘C’ (Client)
; LinkTag [A] w/ text ‘S’ (Server)
; LinkTag [A] w/ text ‘M’ (M___)
fChStr (new org.htmlparser.filters.HasChildFilter fStr)
; the following is a short-cut
; n.getChildren().extractAllNodesThatMatch(fChStr).elementAt(0).getFirstChild()…
txt (.. n (getChildren) (extractAllNodesThatMatch fChStr) (elementAt 0)
sSvrFile (.. datas (extractAllNodesThatMatch
(new org.htmlparser.filters.HasChildFilter
(new org.htmlparser.filters.StringFilter “S”)))
(elementAt 0)(extractLink))
; (println “Node =” n)
; (println “first child (data) w/ three <A> tags:” datas)
; (println “text node is” txt)
; (println “file is ” (uri_to_filename sSvrFile))
(readXmlFile (uri_to_filename sSvrFile))))))

And, finally, a good, stand-alone function to read an XML file:

;; read an XML file — more to do here
;; N.B. “fn” as a param means “filename” not “function”
(defn readXmlFile [fn]
;; read the filename
(let [buffRd (new (new fn))
lns (slurp buffRd)
h (first lns)]
;; if the file contents (lns = lines [of the file])
;; starts with an HTTP <<status>>, continue
(if (. lns startsWith “HTTP”)
;; split the next line (the hard way), find the whitespace of this (the status) line —
;; what remains is the “status,” number and text —
;; and the linebreak of the next line
(let [lnbrk (.indexOf lns \n)
dt (.substring lns (+ lnbrk 1))
idxSp (.indexOf lns ” “)
status (. lns substring (+ 1 idxSp) (– lnbrk 1))
eol (.indexOf dt \n)
; (println “HTTP status:” (. lns substring (+ 1 idxSp) (- lnbrk 1 )))
(if (not (= status “302 Found”))
;; call the hdr function…
(let [[hdr r2] (hdr (struct-map header :status status :date (.substring dt 6 eol))
(.substring dt (+ eol 1)))]
(println “header is” hdr)
;; then parse the remaining data from the file
(let [p (clojure.xml/parse (new (.getBytes r2)))]
;; ** more to do here **
;; if this was a “302 Found” status, we’re dealing with a VIP exchange, and there’s nothing useful here…
(println “Location is:” (. dt substring 10 eol))

Commentary, what there is, to follow…

What happened at my latest assignment

June 12, 2011

I’ll get back to tech. writing soon, but first my last thoughts about my ‘old’ job:

I’m writing separately about my experience with IBM in general, and here specifically about my last assignment.
Before I even showed up at my new assignment, I told them that I had already scheduled a week of vacation (first week in March) — plane tickets bought and everything, and I made no secret of that. I arrived to find that I did not have any access — either to the building itself, nor to the computer network; it took over two weeks to get everything installed and access granted (less time for the physical access, but coming to my desk did not permit me to get any work done, only attend meetings). While I was on vacation, I got an e-mail that requirements were due for my new assignment that day — not only did I get the e-mail while I was known to be out of the office, the e-mail was sent on the due date, not before.

Well, I worked as I could, learning new technology, as well as a new environment — new people, new processes (or lack thereof), new red tape…

Here is the bragging section: I started with minimal knowledge of some of these, and by the end, I had written a new method for a web service, using a framework I was unfamiliar with, communicating with the database via Hibernate (another first, for me), and also modified the client application to call the web service, and changed the UI, using JGoodies (new — though how much use of that is open for debate) — I worked on almost every layer of this n-tier architecture, Java application, using Java version 1.5 on the client, and only 1.4 on the server, running on Websphere 6.1 (new), coding in RAD 7.0.1. And the entire infrastructure was a mystery to me — I’ve never seen a diagram, yet. All the while, I navigated, a new social and political landscape — sometimes more successfully, sometimes less.

When it came to the Thursday before the due date, I had made clear that things weren’t all right, and finally let it be known clearly that the project wouldn’t be done this week, even to the point of taking the (personal) initiative to call the project manager’s boss on the phone and say, “this isn’t feasible.” So I was asked, “well, could you work the weekend.” (Note there is no question mark on that sentence — it wasn’t really a question.) Not knowing any of the players, and without any offered assistance, without communication with the people who needed to approve, that would be difficult. Arrangements were made to make two people available, and I was led to believe a third, who had key knowledge, but when I called him, repeatedly, on Saturday, he told me in no uncertain terms that he couldn’t help. By five o’clock Saturday, I’d accomplished more than I thought possible, but still called the final contact and said, “here’s where things are, and here is where they will stay — I won’t work on Sunday, and we’ll finish next week.”

It still took until Tuesday, but it was done. Then some support was given while the project was promoted, and for the next month after that, I sat and did nothing, because there was no work to do… So explain to me again why it was so important to do that last job in a rush??

That’s the most I’m going to complain, except for this — last week, I’m told there was an “all-hands” meeting (to which I wasn’t invited, and it wasn’t just me — there was at least one other person); one of the areas discussed was communication, but the meeting wasn’t communicated to everyone. [You can put your own emoticon, or exclamation here.]

Contrast that with starting my new job: I got two e-mail msgs the week before letting me know where to go and who would have my new laptop, and my initial account set-up. There was still a snafu along the way — isn’t there always? But requests for access were granted in short order and I was contributing and productive by the 3rd day.