Archive for the ‘Comp. Sci.’ Category

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
{
  public:
    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:

Compiling

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

Running

./test_exception2

Output:

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.

./test_exception2
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:
err_dlg_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.

 

Advertisements

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 =
    do
      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
  in
   if b2 == b
      then b
     else solve b2

calcUniqs

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
   in
     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;

“toSolve”

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 =
    let
        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
    in 
        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.)

Finally

calcOpen b =
  let syms = symbols b
   in
   --  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.

show

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.)

 

 

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 (
        do
            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)
		   (new_xml_result)
		   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
    d))

(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 java.io.BufferedReader (new java.io.FileReader 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 java.io.ByteArrayInputStream (.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 java.io.BufferedReader…” 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)]
(cond
(.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)
true
(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 http://fiddler2.com/fiddler2/
  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 ‘clojure.contrib.shell)  ; 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 (clojure.contrib.shell/sh 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

(via http://quickhighlighter.com)

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)))

(println)

)))

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)
(getFirstChild))
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 java.io.BufferedReader (new java.io.FileReader 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 java.io.ByteArrayInputStream (.getBytes r2)))]
;; ** more to do here **
p)
)
;; 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…

Clojure self-modifying code

December 2, 2010

One of the advantages of having my computer, and all software, re-built is the opportunity to start over.

I just re-installed Clojure.  I seem to have a backup of one project I was working on, but haven’t looked at how recent, so I’m not sure how much I saved or lost.  That aside, I thought I’d do an experiment in self-modifying code.

This is not exactly what is meant, but in a sense it is:

(def f '(fn [x] (+ x 5)))
(def add-some (eval f))
(println "add-some a func?" (fn? add-some))
(println "result =" (add-some 13))
(def l (first (rest (rest f)))) ; one short-cut
(def l2 (cons (first l)
	      (list (first (rest l))
		    7)))
(println "re-defining, kinda cumbersome, but this is only an example")
(def f2 (list 'fn '[x] l2))
(println "original list was:" f)
(println "new list is:" f2)
(def add-more (eval f2))
(println "new function result =" (add-more 13))

So what is this code? what does it do?  I define a list named f (note the single-quote at the beginning — this says don’t evaluate the list, but store it).

Then I define a function (similar to defn, but expanded) using eval of that list; testing that it is a function, and using it (the result is 18).

Next, I “modify” the list [actually, I create a 2nd list], and “re-define” the function.  Well, it’s not exactly what I was after, but I am going to “publish” my result for now, maybe add more later…

Knowing how way leads on to way
I doubted if I should ever come back

Ah, well.  If you, my dear reader, should ask questions, I’d be more than happy to answer them.

A short paragraph explaining why I blog: there are two reasons.  The first is for my own personal record of what I did, or didn’t do.  The second is if someone finds entertainment, education, or some sort of connection with what I do, then please leave a comment so I know you’re out there.
I think I would write more, and more often, if I knew I had an audience.  Or maybe not, but at least I’d have a better focus than what I just wrote.

Recovered

November 21, 2010

I am not dead, yet.  I know it’s been three months since I posted, but I’ve been overly busy.

This last week, my laptop “died.”  This is the story of my own “phoenix rising.”

There is some technical detail here, so I’ll give the short story first: my work laptop started having problems a little over a week ago, so I had to (a) send it in to try and recover some data, and (b) find a replacement — I built a Linux box on my old iBook, and installed open software to connect to my (virtual) work machine; then I had wireless networking problems, after I solved one issue.  Now I have my computer back, and most of my data and software restored.

Friday last my work laptop asked in install an update for some software — I won’t name it, and thus blame that, because it may not be directly related, or some interaction, I’m not sure.

After reboot, just at the point you’d normally get the Windows (XP) login dialog box, I got a Blue Screen Of Death.  I was only able to boot in to “Safe Mode” — not even Safe Mode with Networking or Safe Mode with Command Prompt.  Lesson learned too late: at that point, back up whatever isn’t already saved, because you’re in trouble.  But I didn’t do that.  Instead, I fiddled around until I broke it completely:  running msconfig allows you to change certain startup parameters, which didn’t help, but I was able to alter the default safe mode settings to automatically start safe mode with command prompt — with the inevitable result that now I couldn’t even start up in Safe Mode.

Drat.  So I had to ship my computer out to tech. support.  On a conference call on Friday, I mentioned, “if I have to, I’ll drive ‘downtown’ [so they can work on it],” but someone else mentioned that “downtown,” for my work technical support, is Rochester…  So I went in to Fed Ex Kinkos and just said, I’d like to send this [my laptop] to here [I got the address to send it to].  The reason being I had hopes they could recover some (all?) of my data — there are two levels of encryption, so I couldn’t just boot from CD and read the harddrive myself…

In the meantime, I had to have a computer to use; I borrowed my wife’s laptop for part of a day — since my current assignment is a position where all I really need is a virtual desktop interface to my virtual computer.  There’s something to be said for a virtual computer.  Not much, mind you, since I have limited memory, and CPU speed, but that aside, I was able to work “without difficulty” from a different computer, as long as I had a browser to use which could access the “computer” with my work saved on it.

The truth is there is/was not all that much that actually resides on my laptop itself that I couldn’t live without — which is good, because it turns out nothing could be recovered.  More on that later.

Well, under duress, I was able to build/install Linux on my old Macintosh iBook — very old.  Truth be told, I’d installed Linux previously, twice, but I never did get wireless networking operational.  But with the pressure of ‘I have to get work done,’ I succeeded where I failed before.  I connected directly to the Internet with wires — sometimes there is no substitute for a Cat 5 Ethernet cable.  This is actually the 2nd time that I needed to directly connect: a few weeks back, my laptop had trouble with all wireless networks, and tech. support then suggested that I need to un-install two applications (a connector program and the hardware drivers themselves; in order to accomplish this I had to direct connect then, also.  First (two) times I had to use a cable in a few years.

But I did it: within a matter of hours, I had a functional, operational replacement laptop, running Linux on a old iBook — a computer I could actually get work done.  I’m rather proud of that (which is silly, I know, but it felt kind of nice; especially the fact that I really had to dig to find the solution for wireless — I ought to post the link(s) that helped me do that…).

Then I needed a VDI client — did you know that VMWare has an open source ?  It took a small effort to get it to build.  The biggest problem was having the Boost libraries available (even w/ the –include-boost=no flag??).  I needed to alter a couple of environment variables before running the configure script (CPPFLAGS.  The LDDFLAGS when set, caused other problems, so I altered the Makefile directly — something I don’t like to do.  I would always prefer to follow the standard procedure to do things, but I also had to manually move the boost library in order to get things done.  And the LDDFLAGS required were to make missing symbols only warnings and not (fata) link errors..)

Then on Monday night I ran into another goofy problem: when putting the computer to “sleep,” if I did that manually (not by closing the lid, but from the menu option), then it effectively turned off the wireless network card and re-starting did not re-enable it.  It almost seems that there is a hardware-software switch.  Even re-starting the entire system did not work.  It took me quite a bit of finagling to get that worked out.

Finally, I heard on Wednesday late that nothing could be recovered, so my work laptop was being rebuilt from scratch and sent back to me.

Fortunately, when I did this two years ago, and, to a lesser degree, when I re-installed all the software on a new laptop this Spring, I started a tiddlywiki page of links to the programs I like.  I’d tried to keep these notes up to date, but unfortunately, hadn’t yet backup up the latest version (my online backup choice is DropBox), but I had and have a fairly recent version — and you can bet that as I go, now, I’ll keep the latest version online.

So I was off to the races — I spent a fair bit of time on Friday, and more on Saturday restoring what was lost.  What I’m missing is a Java utility program that I wrote for work, any admin notes that I had stored on my laptop, and my most recent Haskell work.

But what I kept was anything and everything that already lived “in the cloud” — or at least in non-local, internetized storage.  All my e-mail is basically web-based only (my work e-mail was safe — all in a Lotus Notes server out there); any interesting links to web pages were saved in del.icio.us, and most of what I want to remember is there, or starred Google Reader stories, or Read It Later.

I still have work to do restoring my sanity, but I’m almost completely back up to speed, and I have a clean machine to boot.

Note: I’ll add links later, but I wanted to get this posted.

One brag: my wife asked — Wednesday or Thursday — if people at work realized I was working without my laptop (I described it as “programming left-handed”); I told her I considered a mark of my professionalism that they did not know most of the difficulty that I encountered — I just continued working.

But I’m curious: I don’t want any sympathy, but I what have you done to protect yourself from computer problems?  Backup regularly?  If not, you can share your story when it happens.  What else?  Any ideas?

 

Latest on P != NP and Next Haskell Work

August 19, 2010

At the end of this post, I’m going to lay out my plan for further work on Haskell

Update: R. J. Lipton wrote a nice, easy overview of the problem, and a timeline of the week following for the magazine Communications of the ACM. This is probably my last work on this — I still haven’t gotten back to Haskell…

The NYT had an article on Monday, which talked around the proof, but was an interesting discussion of using “social media” to solve problems.

“At this point the consensus is that there are large holes in the alleged proof — in fact, large enough that people do not consider the alleged proof to be a proof,” Dr. Vardi said. “I think Deolalikar got his 15 minutes of fame, but at this point the excitement has subsided and the skepticism is turning into negative conviction.”

— Which means it could still be correct, but probably not.

Richard Lipton has a blog post about why proofs (in general) matters — again, a good read itself (including a “personal” note about Dr. Deolalikar original wish for privacy, and actions in that direction recently.

So on to other things — I’m giving up for now on a Haskell GUI, in favor of getting something done.  I typically resist posting “plans,” but I do tend to get more done that way, so here goes:

  • first, read an (.INI) file,
  • 2nd, parse command-line arguments (and write back the resulting file)
  • copy files/folders based on the previous two
  • and then move on to “comparative programming” for Sudoku…

So we’ll see what this next week or two brings.  I’ll be out of town this weekend, so no progress for a while…

Links with little comment (P != NP)

August 11, 2010

Updated: Two links to R. J. Lipton’s blog with possible flaws — first, an explanation of a type error (really, very readable, and recommended); and second, a serious threat (note that, altough the link does not include it, the title of the post has a question mark at the end!).

Then, a personal note — I do not know Vinay Deolalikar, but I hope he has quite a bit of internal fortitude.  I am led to believe that the discussion has been non-personal, and even, perhaps, supportive, but to have your ideas attacked is not easy, even when couched in constructive-criticism form.  I read in one set of comments a back-and-forth which indicated some derision for HP Labs (not exactly, but a definite negative vibe, and clearly I’m not alone in that perception [see the comments in the 2nd post, about 11:24 PM August 12 — sorry I couldn’t link to it…]).

FWIW, here is the wiki discussion of the proof.

(more…)