Wednesday, November 8, 2017

If you can't find a disc, it ain't where you're looking

There's a disc golf adage that goes "If you can't find a disc*, it ain't where you're looking." I sometimes quote that to students who can't find a bug—they're often convinced that a bug lies in code that is in fact correct. I saw an interesting case of that just now with a Python function I wrote:
def precedes(w1, w2):
    if w1.count() > w2.count():
        return True
    elif w1.count() < w2.count():
        return False
    elif w1.word() < w2.word():
        True
    else:
        return False

precedes(w1,w2) should return True if w1 (a word) has a count that's greater than w2. Ties are resolved in favor of the word that is lexicograhically less.

I found that tie resolution wasn't working. I convinced myself that I must have gotten a w1 / w2 reversed, or a conditional operator backwards. I looked and looked at those three comparisons but just couldn't find anything wrong with them.


*Golf discs are about 8.5" in diameter and are often made of bright-colored plastic.

Tuesday, January 31, 2017

Google from the command line

It occurred to me that for Google searches where I don't need suggestions I can do a search by hitting a URL from the command line with this one-line shell script:

% cat gg
open https://www.google.com/search?q="$*"

Let's make one for Wikipedia, too:

% cat wk
open http://en.wikipedia.org/wiki/"$*"

Yup, I should generalize those to a script that looks at its name and maps that to an appropriate URL. Here it is:

% cat hitit
which=$(basename $0)
case $which in
    gg)
        url="https://www.google.com/search?q=$*"
        ;;
        
    wk)
        url="http://en.wikipedia.org/wiki/$*"
        ;;
esac

open "$url"

Let's add a couple of symlinks in my sbin directory:

$ ln -s hitit gg
$ ln -s hitit wk

Now, instead of

  1. Switch to Chrome (I use cmd-, 3 with Keyboard Maestro)
  2. Type cmd-L to get to the address field
  3. Type the search string, or use a Chrome "search engine" like w to hit Wikipedia.
I can do this:
% gg astroboy
% wk ruby lang

The above use open(1) on OS X but on Cygwin, which I may be moving back to, I'd hit URLs from the command line with this script:

% cat ffx
"/c/Program Files/Mozilla Firefox/firefox.exe" $*

Sunday, January 29, 2017

uniq(1) -- not just for sorted input

For years I've mostly used uniq -c with sorted input but I've recently realized that uniq is great for vertical compression/counting.

Here I pipe clipboard contents into uniq -c to see how many blank lines appear between the application of changes 6881 and 6882:

 % cb | uniq -c
      1 applying 6881, event id = 148047427, INSERT_TEXT,6239,0,6240,0,[
      1 ]
      1 applying 6882, event id = 148047428, INSERT_LINES,6240,0,7479,0,[
   1237 
      1 ]
      1 applying 6883, event id = 148047429, INSERT_TEXT,7479,0,7480,0,[
      1 ]
      1 2017-01-29 17:25:00,762 LimitedEditCodeServiceImpl WARN  - Exception applying deltas to program text
      1 java.lang.IndexOutOfBoundsException: Index: 7479, Size: 6244
      1         at java.util.ArrayList.rangeCheck(ArrayList.java:635)
      1         at java.util.ArrayList.get(ArrayList.java:411)
      1         at org.cloudcoder.app.shared.model.TextDocument.getLine(TextDocument.java:59)
      1         at org.cloudcoder.app.shared.model.ApplyChangeToTextDocument.apply(ApplyChangeToTextDocument.java:41)
      1         at edu.arizona.cs.practice.codeextraction.LimitedEditCodeServiceImpl.doLoadCurrentText(LimitedEditCodeServiceImpl.java:103)
      1         at edu.arizona.cs.practice.codeextraction.Test1.main(Test1.java:112)

Below I use uniq -c to collapse repeated lines in query output:

% cb | uniq -c
      1 +----------+---------------------+-----------------+------+
      1 | username | date                | testname        | type |
      1 +----------+---------------------+-----------------+------+
      1 | zjones   | 2017-01-19 09:22:56 | number2letter   |    2 |
      1 | zjones   | 2017-01-19 09:22:56 | number2letter   |    0 |
      2 | zjones   | 2017-01-19 09:23:16 | number2letter   |    0 |
      1 | zjones   | 2017-01-19 09:25:06 | number2letter   |    0 |
      2 | zjones   | 2017-01-19 09:25:08 | number2letter   |    0 |
      1 | zjones   | 2017-01-19 09:25:09 | number2letter   |    0 |
      2 | zjones   | 2017-01-19 09:25:10 | number2letter   |    0 |
      3 | zjones   | 2017-01-19 09:25:11 | number2letter   |    0 |
      3 | zjones   | 2017-01-19 09:25:12 | number2letter   |    0 |
      2 | zjones   | 2017-01-19 09:25:18 | number2letter   |    0 |
      1 | zjones   | 2017-01-19 09:25:31 | number2letter   |    0 |
      ...