Mini Tutorial: Bashing hello.py

April 11th, 2014 by kludgecode

This post is related to Coursera’s Programming for Everyone course.

“Why fire up a text editor when I have a command line?” is the sort of question that I never really asked when I was running Windows as my primary operating system. My default approach was to look for a button to click on. But it’s the sort of question that naturally arises as I spend more time with Linux.

After navigating to the directory where I want to hello.py to live:

[prog4everyone]$ touch hello.py  
[prog4everyone]$ echo print "'hello world'" >> hello.py 
[prog4everyone]$ cat hello.py 
print 'hello world'
[prog4everyone]$ python hello.py  
hello world

touch hello.pytouch creates an empty file named ‘hello.py’ if it does not already exist. Otherwise it changes the timestamp of an existing file.

echo print "'hello world'" >> hello.py has two parts.

  1. The first part is echo print "'hello world'". echo simply repeats what is given as input. In order to pass the double quotation marks " for “hello world” through the echo command, the quotation marks need to be nested in single quotes '. Alternatively, to pass single quotes around ‘hello world’ through echo, they must be must be wrapped in double quotations. In other words echo print '"hello world"' and `echo print “‘hello world’” will both pass good Python syntax.

  2. The second part is >> hello.py. It takes the output of the first part and appends it to the end of the file “hello.py”.

cat hello.py – The cat command concatenates the contents of various files and ouputs the result. In this case the output is sent to the screen, and since only one file is provided as input to cat we just get the contents of that file [i.e. print 'hello world']

python hello.py – This calls the python interpeter with “hello.py” as input. This returns hello world.

Now I know some people are probably upset since using touch to create the hello.py is completely unneccessary because redirection will create a new file if one doesn’t already exist. For example:

[prog4everyone]$ echo print "'goodbye world'" >> goodbye.py
[prog4everyone]$ python goodbye.py
goodbye world
[prog4everyone]$ 

is even more efficient. Please accept an apology. I know that being enamoured with touch to create empty files is unhealthy and compulsive.

Racket: Windows COM-object Example

January 10th, 2014 by kludgecode

This morning’s lesson from investigating a StackOverflow question (which I have not answered):

#lang racket
(require ffi/com)
(define ie (com-create-instance "InternetExplorer.Application"))
    (com-invoke ie "Navigate" "http://stackoverflow.com/questions/21038482/how-to-pass-box-unsigned-int-to-com-invoke")
(com-set-property! ie "Visible" #t)

It is taken from an extended example in the Racket email archives.

How I am learning Git on Windows

January 8th, 2014 by kludgecode

Preramble:

My interest in version control arises in no small part from the years of using informal systems and loose in house standards for managing documents for architectural projects. If it was just the case that every office archived their projects differently, the world would be a better place. It would be better even if each individual did so, but the delta between the number of architectural projects and the number of ways in which they are archived and managed is rather small…at  best. Some projects have different methods for each type of document, and sometimes these are changed with a project’s phase.

Introduction

As I started to get more serious about learning to program, I started using version control out of three motivations: for access to code from both laptop and desktop; as a way to backup my work; and because of my interest in the general problem. What I have found is that using version control not only solves the technical issues and resolves my curiosity, it also structures my thinking as I develop projects. The implicit symmetry between the local and remote repositories is something worth seeking [Perlis, Epigram 6].

Feature Presentation

I have a free account on Github and use the Windows app. The interface has a Metro look, but it’s not a Metro app. The downside of Github is that all free account repositories on Github are public, and I have a use case, coursework for Coursera classes, that make public repositories inappropriate.

For that I have a free account on Bitbucket because it allows private repositories. I access that using Atlassian’s free version of SourceTree. What I like about SourceTree is that it exposes more of the guts of version control. If command line Git is C, it’s Java, and the Github app is…well, it’s an app.

The mention of the command line is not accidental. Once I start wanting to do something a little advanced, the step by step descriptions for implementation will invariably use the command line because at it’s core Git is not an app; it is a system with a command language, and the command language maps directly onto Gits underlying concepts in a specific way versus the generic language of click here, select that, type this, click there…etc. of app usage.

As a twenty odd year user of Windows, it feels very unnatural to say this, but learning the command line is something to be embraced. Then again Emacs feels unnatural from that perspective too.

Lastly

My thanks to Eric Sink for the free! [hard!] copy of his book Version Control by Example which he graciously provided as an “Offer HN:” a couple of years ago. It provides consistent examples which cover the general issues across different types of version control systems. When I finally got around to using version control, I reread it more thoroughly than when I was merely interested in the topic.

Links:

Amazon Affiliate Link to Eric’s book.

Non-Affiliate Link to Eric’s book.

Expanded from this HN comment.

Documentation is a Feature

December 31st, 2013 by kludgecode

The problem

As Alice in Wonderland {1}, I think about all the times I have chased around documentation structured where eggs links to bacon and sausage; bacon links to sausage and eggs; and sausage links to bacon and eggs and when spam is what I needed, and eventually it turns out on the one-hundred and seventeenth round trip, I notice that there is a link to spam right there at the bottom of the pages for eggs and sausage and bacon; hot linked in the phrase “Lobster Thermidor aux crevettes with a Mornay sauce, garnished with truffle pâté, brandy and a fried egg on top of spam.”

I have started thinking that part of the reason this happens is that hyperlinks are nothing more than GOTO, and sure, since GOTO is just JMP and JMP is fundamental to computing, there’s nothing inherently wrong with hyperlinks [or GOTO]. It’s just that circular GOTO constructs don’t fit with well with my brain’s bias toward pattern matching upon the obvious.

The other factor is not a product of recent thinking: open source documentation tends to be a ball of mud.

It has this tendency because it’s hard work to write and good documentation for a project of any significance and a lot less fun than writing code for people who write the code that requires all that documentation. The fun part is self explanatory, but the hard work is because good documentation looks more like the 2000 pages of GNU Emacs manuals or Knuth’s 1962 book about compilers than Java-doc. Good documentation is built around a narrative, or several narratives when there are multiple manuals, and each of these narratives is structured to have a beginning, middle, and end.

When the foundation document in a documentation project doesn’t have an appendix or two, it should be heeded as a warning not celebrated as a feather in the cap. Good documentation recognizes that there’s always something more to say, and tries to say it.

Documentation as a competitive advantage.

Four or five years ago when my father, whose early professional career entailed Algol on paper tape and ended using Wolfram’s SMP on Vax’s decided he wanted to learn word processing, spreadsheets and databases; I recommended he just purchase a copy of Office. Being Dad, this of course meant he chose Libre Office because it did everything he wanted to do. Technically, he was correct. The reason he went out and bought Office last year was because his local Barnes and Nobel and even Amazon had a poor selection of books about Libre Office, and more books about Office than there are trolls on the Internet [approximately].

This wasn’t surprising. He is a consumer of documentation and the right answer for him was pretty obvious to me. Being a similar consumer myself going back to the Amiga ROM Kernel Manuals. The quality of documentation is why I’ve decided EMACS is worth the effort of learning. It reminds me of the old hard bound reference manuals that used to ship with Auto-Cad. It was the quality of Microsoft’s documentation and its availability in hard copy that led me to stay on the Microsoft Stack until making a baby step to Racket and its above average documentation. The quality of Racket’s documentation is a byproduct of a writing culture it inherits from the academic world.

Apple is easy to write about

Though it is easier to write documentation for Microsoft products than for open source projects because there are easy assumptions about the context in which the reader operates. SQLserver, unlike MySQL, is only relevant with a narrow range of operating systems and under a few very similar licensing agreements and business models. MySQL could be running anywhere.

But nothing is easier to write about than Apple, it’s perhaps the reason why their devices are so popular with journalists. The reason is that Apple has established a ubiquitous language and this allows it to control the narrative. We talk about “App stores for Android” and despite the protestations, P. T. Barnum’s adage {2} that all that matters is if your name is spelled correctly holds true.

The Mozilla Conundrum

My list of great open source documentation projects is unfair. Mozilla’s documentation of all things browser related is phenomenal. It educates developers about the entire domain of which Mozilla’s projects form just a part. Unfortunately, it does not provide any momentum toward the adoption of Firefox. The decision to use Firefox is not made by the users of their developer portal. Decisions about Firefox are largely made one at a time by non-developers and usually based upon very few meaningful technical criteria.

For some software companies, however, “going Mozilla” and setting out to comprehensively document an industry segment, competitors and all, might provide strategic advantage. For a B2B oriented company based upon open source, documenting the larger domain demonstrates larger interest in helping potential customers find solutions to their problem irrespective of an established customer-vendor relationship.

A company providing a primary research resource for a larger market, above and beyond simply providing documentation for their own products, is able to honestly express the open-source ideals for a sound business purpose.

The fundamental ethic of the open-source movement is goodwill. The user must trust that the author is trying to solve the problem they say they are trying to solve. More interestingly, the author must trust that use of the software, in the worst case, causes the author no harm, and in better cases might just provide the author with some benefit. It is the ethic: we are not dividing a pie, your profit is not my loss.


{1} see Alan J. Perlis, Epigram 48

{2} Barnum allegedly said, “I don’t care what they say about me, just make sure they spell my name right.”

A Literate Programming Example in Racket

December 18th, 2013 by kludgecode

This post is based on an extended example. The source files for it are available on Github

The weaved output from those source files can be seen here on the project page.

Racket’s scribble/lp language allows programs to be written in the Literate Programming Idiom. The documentation, however, is not very clear. This should not be particularly surprising because Racket’s documentation is sometimes lacking when it comes to features outside the core and when something between very basic material and detailed reference is needed.

The process of weaving is where scribble/lp is a bit confusing. Unlike documents in scribble/base or scribble/manual, documents written in scribble/lp cannot be directly rendered to HTML or LaTeX. This is why DrRacket does not provide “the easy button” when it sees a scribble/lp document because documents written using #lang scribble/lp use the file extension .rkt not .scrbl.

This means that a Racket Literate Program requires a second document written in either scribble/base or scribble/manual. It can be very simple:

#lang scribble/manual
@require[scribble/lp-include]
@title{Literate Programming Example}

The file for weaving has a file extension of .scrbl. To weave LPexample.rkt we run the scribble command on its corresponding .scrbl file. In this case: LPexample.scrbl.

A scribble/lp file contains both the code for tangling into a program or library and the text for weaving into a document. Like its parent scribble, scribble/lp allows direct input of text. The code to be tangled is delineated:

@chunk[<example_main>
       <example_requires>
       <example_exports>
       <example_body>]

Because this is the first @chunk it is treated as the main chunk. This is mentioned briefly near the bottom of the scribble/lp documentation. If you don’t want the first@chunkto serve as the main chunk, then use:

@chunk[<*>
   <example_requires>
   <example_exports>
   <example_body>]

It can be placed anywhere in the document to serve as the main chunk. However, I have tried it, and it really doesn’t add anything for clarity.

The two items which should be taken away because they effort to tease out of the documentation are:

  • Weaving requires a second file where a file with a .rkt file extension is referenced using lp-include.
  • Tangling treats the first chunk differently unless the <*> special name is used.

Step for Character Ranges in Haskell

December 8th, 2013 by kludgecode

One of the side of effects of taking Dan Grossman’s Programming Languages course at Coursera is removing some mental block I’ve had in regard to just loading up and playing with a new language.* Late last week in it was Node.js – just for the sake of a question on StackOverflow – one that got me thinking about Racket’s Htdp2/Universe teachpack. Today it was Haskell based on reading this post on HN over the weekend.

Anyway, I had Learn You a Haskell open to the introduction of lists, and started playing around with the step argument for ranges of ranges of characters:

ghci >['b'..'z']                  -- a range of characters
"bcdefghijklmnopqrstuvwxyz" 
ghci >['a', 'b'..'z']             -- if a is the first character
"abcdefghijklmnopqrstuvwxyz"      -- then it the same as 1?
ghci >['b', 'b'..'z']             -- nope
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbInterupted  --with Cntrl-c

ghci >['a', 'c'..'z'] -- every other letter.
"acegikmoqsuwy"
ghci >['a', 'd'..'z'] -- every third letter.
"adgjmpsvy"

I think I’m going to like Haskell – it feels like a more expressive SML.

  • I give a great deal of credit to the thought Grossman put into the first exercise in Ruby which essentially created that expectation that learning enough of a language to read and modify some simple code was reasonable.

Generating Permuations in Racket Using ‘for/list

December 3rd, 2013 by kludgecode

Generating a list of permuations in Racket:

> (for/list ([i '(1 2 3)]
             #:when i
             [j "abc"]
             #:when j
             [k '( 'a 'b 'c)])
    (list i j k))
'((1 #\a 'a)
  (1 #\a 'b)
  (1 #\a 'c)
  (1 #\b 'a)
  (1 #\b 'b)
  (1 #\b 'c)
  (1 #\c 'a)
  (1 #\c 'b)
  (1 #\c 'c)
  (2 #\a 'a)
  (2 #\a 'b)
  (2 #\a 'c)
  (2 #\b 'a)
  (2 #\b 'b)
  (2 #\b 'c)
  (2 #\c 'a)
  (2 #\c 'b)
  (2 #\c 'c)
  (3 #\a 'a)
  (3 #\a 'b)
  (3 #\a 'c)
  (3 #\b 'a)
  (3 #\b 'b)
  (3 #\b 'c)
  (3 #\c 'a)
  (3 #\c 'b)
  (3 #\c 'c))

The Hacker School Application : overkill for FizzBuzz

December 1st, 2013 by kludgecode

Today, I applied to Hacker School, just because I could, or maybe because it gave me an excuse to code up FizzBuzz or in this case CracklePop. Buried in the last week of Coursera’s Programming Languages course, I debated Ruby, SML and Racket, but in the end, the choice of Racket was simple…I’m a Lisphead.

The solution is based around a generalized fizzbuzz solver that works over an arbitrary range of positive integers and takes any two factors to be replaced by corresponding strings. The interesting parts of the exercise were decomposing the various functions and generating the output in a reasonable way.

In the end, I added some code to validate the arguments to the function – a sort of compromise since I didn’t want to deal with the module system and implement contracts. It paid off since I now have some better error passing style after reading the examples in the Racket Guide.

Code for the “snapcrackle” implementation is available on Github: https://github.com/brudgers/Racket/blob/master/snap-crackle.rkt

#lang racket
;;; DataType FizzBuzz
;;; is int or string


;;; (int . string)(int . string) int int -> listof FizzBuzz
;;; Function fizz-buzzer :
;;; fizz-buzzer is a general function for solving 
;;; fizzbuzz type problems with two explicit conditions:
;;; [fizz and buzz] and one implicit condition [fizzbuzz]
;;;      An interesting extension would be solving fizzbuzz problems for
;;;      any arbitrary number of pairs.
;;; the first argument is a pair consisting of
;;;    + an int upon which an input argument should fizz
;;;    + the string which a fizz should return
;;; the second argument is a pair consisting of
;;;    + an int upon which an input argument should buzz
;;;    + the string which a buzz should return
;;; the third argument is the lower bound of the fizzbuzz's range
;;; the fourth argument is the upper bound of the fizzbuzz's range
(define (fizz-buzzer fizz-pair buzz-pair start stop)
  (let* (;; (int . string) -> (int . string) | raises error
         ;; validates 'fizz-pair and 'buzz-pair
         [validate-pair 
          (lambda (pr name)
            (let ([int (integer? (car pr))]
                  [string (string? (cdr pr))])
              (if (not int)
                  (error 'fizz-buzzer "first element of ~a cannot be coerced to an integer" name)
                  (if (not string)
                      (error 'fizz-buzzer "second element of ~a not a string" name)
                      pr))))]
         ;; integer -> integer | raises error
         ;; validates 'start and 'stop
         [validate-int
          (lambda (i name)
            (if (integer? i)
                i
                (error 'fizz-buzzer " ~a value cannot be coerced to an integer" name)))]
         ;; note that Racket documentation uses
         ;; 'car and 'cdr for dotted pair examples
         ;; so following it here [see Racket Guide 3.8]
         [fizz-val  (car (validate-pair fizz-pair "fizz-pair"))]
         [fizz-word (cdr fizz-pair)]
         [buzz-val  (car (validate-pair buzz-pair "buzz-pair"))]
         [buzz-word (cdr buzz-pair)]
         ;; implicit fizzbuzz pair
         [fizzbuzz-val (* fizz-val buzz-val)]
         [fizzbuzz-word (string-append
                         fizz-word buzz-word)]
         ;; generate the range of integers over which to iterate
         [iterations (range (validate-int start "start")
                            (+ (validate-int stop "stop") 1))]  ; 'range output not inclusive
         ;; int -> FizzBuzz
         ;; a helper for our map function
         [aux (lambda(int)
                (cond [(= int 0) int]
                      [(= (modulo int fizzbuzz-val) 0)
                       fizzbuzz-word]
                      [(= (modulo int fizz-val) 0)
                       fizz-word]
                      [(= (modulo int buzz-val) 0)
                       buzz-word]
                      [else int]))])
    ;; return a list of FizzBuzz
    (map aux iterations)))


;;; list -> side effect
;;; prints the contents of a list without 
;;; the enclosing parenthesis
(define (print-list lst)
  (letrec 
      ;; any -> string
      ;; string ends with a newline character
      ([formatter (lambda (x) (format "~a ~n" x))]
       ;; listof any -> string
       [aux (lambda (lst)
              (if (null? lst)
                  ""
                  (string-append (formatter (car lst))
                                 (aux (cdr lst)))))])
    (display (aux lst))))


;;; -> side effect
;;; a classic fizzbuzz using "snap" and "crackle"
(define crackle-pop
  (lambda ()(print-list(fizz-buzzer '(3 . "crackle")
                                    '(5 . "pop") 
                                    1 100))))

(crackle-pop)