George Jones 2 년 전
커밋
3c20c8d81c
100개의 변경된 파일4347개의 추가작업 그리고 0개의 파일을 삭제
  1. 3 0
      home/public/README.org
  2. 4 0
      home/public/apt/dpkg-restore.sh
  3. 3 0
      home/public/apt/dpkg-save.sh
  4. 116 0
      home/public/babel/ob-shell-test.org
  5. 85 0
      home/public/babel/shellArrays.org
  6. 25 0
      home/public/babel/sqlite.org
  7. 9 0
      home/public/bash-filter-function.sh
  8. 21 0
      home/public/bash/args.sh
  9. 14 0
      home/public/bash/argv.sh
  10. 57 0
      home/public/bash/arrays.sh
  11. 6 0
      home/public/bash/bad.sh
  12. 272 0
      home/public/bash/bashArrays.org
  13. 177 0
      home/public/bash/bashArrays.sh
  14. 291 0
      home/public/bash/bashArraysTest.sh
  15. 24 0
      home/public/bash/bashAssociateveArrays.sh
  16. 16 0
      home/public/bash/bashFunctionsWithArguments.sh
  17. 39 0
      home/public/bash/bashGetopt.sh
  18. 117 0
      home/public/bash/bashGetopt2.sh
  19. 69 0
      home/public/bash/bashHash.sh
  20. 96 0
      home/public/bash/bashUtils.sh
  21. 13 0
      home/public/bash/bashmod.sh
  22. 5 0
      home/public/bash/chaining-commands-based-on-exit-status.sh
  23. 17 0
      home/public/bash/f-alias.sh
  24. 6 0
      home/public/bash/good.sh
  25. 22 0
      home/public/bash/imageDates.sh
  26. 146 0
      home/public/bash/jpgHasDate
  27. 15 0
      home/public/bash/lines.txt
  28. 29 0
      home/public/bash/listAllFilesInLoop.org
  29. 4 0
      home/public/bash/runAll.sh
  30. 40 0
      home/public/bash/sort_csv.sh
  31. 75 0
      home/public/bash/tests/README.txt
  32. BIN
      home/public/bash/tests/addresses.txt.gz
  33. 65 0
      home/public/bash/tests/awk-associative-array-test.awk
  34. 78 0
      home/public/bash/tests/bash-associative-array-tests.sh
  35. 32 0
      home/public/bash/tests/post-patch-test-timing.txt
  36. 31 0
      home/public/bash/tests/pre-patch-test-timing.txt
  37. 14 0
      home/public/bash/traps.sh
  38. 50 0
      home/public/bash/trim.sh
  39. 26 0
      home/public/bash/xargsWithSpaces
  40. 78 0
      home/public/bashArrays.org
  41. 1 0
      home/public/description
  42. 75 0
      home/public/elisp/babel
  43. 26 0
      home/public/elisp/batch
  44. 76 0
      home/public/elisp/gmj-set-property-dates.el
  45. 10 0
      home/public/elisp/hello.el
  46. 32 0
      home/public/elisp/org-agenda-clockreport-parameter-plist-testing.org
  47. 12 0
      home/public/elisp/replaceDefaultPropertyTimestampsOnOpen.org
  48. 44 0
      home/public/elisp/replaceTimestamps.el
  49. 35 0
      home/public/elisp/run-org.el
  50. 125 0
      home/public/elisp/scriptingUsingOrgMode.org
  51. 9 0
      home/public/elisp/somePython.org
  52. 32 0
      home/public/elisp/start-shell-with-name-of-host-as-buffer-name.el
  53. 8 0
      home/public/elisp/untabify.el
  54. 22 0
      home/public/elisp/urlExists.org
  55. 0 0
      home/public/git/bar.txt
  56. 5 0
      home/public/git/dir-locals.el
  57. 42 0
      home/public/git/git-autocommit-mode.txt
  58. 7 0
      home/public/git/qux.c
  59. 1 0
      home/public/git/setup.el
  60. 2 0
      home/public/googleMaps/pull.sh
  61. 60 0
      home/public/markdown/markdown-tests.md
  62. 59 0
      home/public/markdown/markdown-tests.org
  63. 59 0
      home/public/matplotlib/plot.org
  64. BIN
      home/public/matplotlib/plot.png
  65. 33 0
      home/public/matplotlib/spline.org
  66. BIN
      home/public/matplotlib/spline.png
  67. BIN
      home/public/matplotlib/spline2.png
  68. 54 0
      home/public/org/.bashrc.org
  69. 109 0
      home/public/org/babel-ipython.org
  70. 27 0
      home/public/org/babel-python-versions.org
  71. 15 0
      home/public/org/bable-cache-test.org
  72. 58 0
      home/public/org/bashrc.org
  73. 45 0
      home/public/org/export-bashrc.org
  74. 18 0
      home/public/org/exportTest.org
  75. 14 0
      home/public/org/exportTestPython.org
  76. 152 0
      home/public/org/exports-test.org
  77. 21 0
      home/public/org/hist.py
  78. 73 0
      home/public/org/ipython-hist.org
  79. 49 0
      home/public/org/ob-cache.org
  80. 6 0
      home/public/org/org-latex.org
  81. 50 0
      home/public/org/orgShellArrays.org
  82. 18 0
      home/public/org/orgTables.org
  83. 12 0
      home/public/org/orgTablesWithNamedTotals.org
  84. 34 0
      home/public/org/tableOutput.org
  85. 74 0
      home/public/pandas/convert_rows_to_integer.org
  86. 75 0
      home/public/pandas/data_types_in_df.org
  87. 48 0
      home/public/pandas/sample_null_rows.org
  88. 31 0
      home/public/pandas/series.org
  89. BIN
      home/public/python/__pycache__/logging.cpython-36.pyc
  90. 35 0
      home/public/python/catsortuniq.py
  91. 15 0
      home/public/python/dicts.py
  92. 44 0
      home/public/python/exercises/python/InsertionSort.py
  93. BIN
      home/public/python/exercises/python/InsertionSort.pyc
  94. 81 0
      home/public/python/exercises/python/QuickSort.py
  95. 6 0
      home/public/python/exercises/python/input.txt
  96. 68 0
      home/public/python/exercises/python/merge_sort.py
  97. 92 0
      home/public/python/exercises/python/myhash.py
  98. 16 0
      home/public/python/exercises/python/qs.pseudocode
  99. 19 0
      home/public/python/exercises/python/test_hash.py
  100. 23 0
      home/public/python/exercises/python/test_insert.py

+ 3 - 0
home/public/README.org

@@ -0,0 +1,3 @@
+This directory contains various small snippits of code, etc
+I've written in various langauges.  These are mostly learning
+exercises put here so that I remebmer what I did/learned.

+ 4 - 0
home/public/apt/dpkg-restore.sh

@@ -0,0 +1,4 @@
+dpkg --merge-avail <(apt-cache dumpavail)
+dpkg --clear-selections
+dpkg --set-selections < packages.lst
+apt-get dselect-upgrade

+ 3 - 0
home/public/apt/dpkg-save.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+# save current packages for dpgk/apt
+dpkg --get-selections > packages.lst

+ 116 - 0
home/public/babel/ob-shell-test.org

@@ -0,0 +1,116 @@
+#+Title: a collection of examples for ob-shell tests
+#+OPTIONS: ^:nil
+
+* Sample data structures
+#+NAME: sample_array
+| one   |
+| two   |
+| three |
+
+#+NAME: sample_mapping_table
+| first  | one   |
+| second | two   |
+| third  | three |
+
+#+NAME: sample_big_table
+| bread     |  2 | kg |
+| spaghetti | 20 | cm |
+| milk      | 50 | dl |
+
+* Array tests
+  :PROPERTIES:
+  :ID:       0ba56632-8dc1-405c-a083-c204bae477cf
+  :END:
+** Generic shell: no arrays
+#+begin_src sh :exports results :var array=sample_array
+echo ${array}
+#+end_src
+
+#+RESULTS:
+: one two three
+
+** Bash shell: support for arrays
+Bash will see a simple indexed array. In this test, we check that the
+returned value is indeed only the first item of the array, as opposed to
+the generic serialiation that will return all elements of the array as 
+a single string.
+#+begin_src bash :exports results :var array=sample_array
+echo ${array}
+#+end_src
+
+#+RESULTS:
+: one
+
+
+* Associative array tests (simple map)
+  :PROPERTIES:
+  :ID:       bec1a5b0-4619-4450-a8c0-2a746b44bf8d
+  :END:
+** Generic shell: no special handing
+The shell will see all values as a single string.
+#+begin_src sh :exports results :var table=sample_mapping_table
+echo ${table}
+#+end_src
+
+#+RESULTS:
+: first one second two third three
+
+
+** Bash shell: support for associative arrays
+Bash will see a table that contains the first column as the 'index'
+of the associative array, and the second column as the value.
+#+begin_src bash :exports results :var table=sample_mapping_table
+echo ${table[second]}
+#+end_src
+
+#+RESULTS:
+: two
+
+
+* Associative array tests (more than 2 columns)
+  :PROPERTIES:
+  :ID:       82320a48-3409-49d7-85c9-5de1c6d3ff87
+  :END:
+** Generic shell: no special handing
+#+begin_src sh :exports results :var table=sample_big_table
+echo ${table}
+#+end_src
+
+#+RESULTS:
+: bread 2 kg spaghetti 20 cm milk 50 dl
+
+   
+** Bash shell: support for associative arrays with lists
+Bash will see an associative array that contains each row as a single
+string. Bash cannot handle lists in associative arrays.
+#+begin_src bash :exports results :var table=sample_big_table
+echo ${table[spaghetti]}
+#+end_src
+
+#+RESULTS:
+: 20 cm
+
+** Bash shell: iterate over keys of associative array
+Bash will see an associative array that contains each row as a single
+string. Iterate over the keys.
+#+begin_src bash :exports results :var table=sample_mapping_table
+#echo ${table[spaghetti]}
+
+for i in "${!table[@]}"
+do
+  echo "$i" ${table[$i]}
+done
+#+end_src
+
+#+RESULTS:
+| third  | three |
+| second | two   |
+| first  | one   |
+
+
+
+
+
+
+
+

+ 85 - 0
home/public/babel/shellArrays.org

@@ -0,0 +1,85 @@
+* Problem
+  The behavior of array passing to shell scripts in org babel seems to
+  have changed as of (at least) org 8.3.4 with the introduction of ob-shell.el
+
+* The way it use to work
+As it appears in source https://eschulte.github.io/org-scraps/
+#+begin_example
+#+name:
+: Sun Feb  7 10:17:44 MST 2010
+
+#+tblname: fibs
+| 1 | 1 |
+| 2 | 1 |
+| 3 | 2 |
+| 4 | 3 |
+| 5 | 5 |
+| 6 | 8 |
+
+#+begin_src sh :var table=fibs
+  echo "$table" |wc
+#+end_src
+
+#+name:
+: 6      12      24
+
+#+begin_src sh :var table=fibs
+  echo "$table"
+#+end_src
+
+#+name:
+| 1 | 1 |
+| 2 | 1 |
+| 3 | 2 |
+| 4 | 3 |
+| 5 | 5 |
+| 6 | 8 |
+
+#+begin_src sh :var table=fibs :separator --
+  echo "$table" | head -1
+#+end_src
+
+#+name:
+: 1--1
+#+end_example
+
+* Testing the same thing with ob-shell
+#+begin_example
+#+name:
+: <2016-02-28 Sun>
+
+#+tblname: fibs
+| 1 | 1 |
+| 2 | 1 |
+| 3 | 2 |
+| 4 | 3 |
+| 5 | 5 |
+| 6 | 8 |
+
+#+begin_src shell :var table=fibs
+  echo "$table" |wc
+#+end_src
+
+#+name:
+: 6      12      24
+
+#+begin_src shell :var table=fibs
+  echo "$table"
+#+end_src
+
+#+name:
+| 1 | 1 |
+| 2 | 1 |
+| 3 | 2 |
+| 4 | 3 |
+| 5 | 5 |
+| 6 | 8 |
+
+#+begin_src shell :var table=fibs :separator --
+  echo "$table" | head -1
+#+end_src
+
+#+name:
+: 1--1
+
+  

+ 25 - 0
home/public/babel/sqlite.org

@@ -0,0 +1,25 @@
+# http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-sqlite.html
+# <2015-07-31 Fri>
+
+#+name: sqlite-populate-test
+#+header: :results silent
+#+header: :dir ~/tmp
+#+header: :db test-sqlite.db
+#+begin_src sqlite
+create table greeting(one varchar(10), two varchar(10));
+insert into greeting values('Hello', 'world!');
+#+end_src
+
+#+name: sqlite-hello
+#+header: :list
+#+header: :separator \ 
+#+header: :results raw
+#+header: :dir ~/tmp
+#+header: :db test-sqlite.db
+#+begin_src sqlite
+select * from greeting;
+#+end_src
+
+#+RESULTS[c20e23fd533ebd2a2fdcd8aae88aa80bc9377e81]: sqlite-hello
+Hello world!
+

+ 9 - 0
home/public/bash-filter-function.sh

@@ -0,0 +1,9 @@
+#! /bin/bash
+# demonstrate bash function filtering of stdin, stdout
+
+function 2toTWO() {
+  # subtitute all "2" characters on stdin with "TWO"
+  sed -e 's/2/TWO/g'
+}
+
+seq 12 | 2toTWO

+ 21 - 0
home/public/bash/args.sh

@@ -0,0 +1,21 @@
+#!/bin/bash
+# bash command line arg parsing
+# http://www.linuxquestions.org/questions/programming-9/processing-command-args-in-bash-367563/
+
+ARGV0=$0 # First argument is shell command (as in C)
+echo "Command: $ARGV0"
+
+ARGC=$#  # Number of args, not counting $0
+echo "Number of args: $ARGC"
+
+i=1  # Used as argument index
+while true; do
+    if [ $1 ]; then
+        echo "Argv[$i] = $1" # Always print $1, shifting $2 into $1 later
+  	shift
+     else
+   	break # Stop loop when no more args.
+     fi
+     i=$((i+1))
+done
+echo "Done."

+ 14 - 0
home/public/bash/argv.sh

@@ -0,0 +1,14 @@
+#! /bin/bash
+# ARGC and ARGV handling without $1 to make set -u happy
+set -u; set -e
+ARGV=("$@")
+ARGC=("$#")
+echo ARGC $ARGC
+# show all args
+echo ARGV ${ARGV[*]}
+# show first arg
+echo ONE ${ARGV[0]}
+# shift argv
+ARGV=("${ARGV[@]:1}")
+# show new first arg
+echo ONE ${ARGV[0]}

+ 57 - 0
home/public/bash/arrays.sh

@@ -0,0 +1,57 @@
+#! /bin/bash
+# messing with arrays
+
+# Declare an array
+declare -a foo
+
+function print_foo() {
+    # List all elements of an array    
+    for i in $(seq 0 $(( ${#foo[@]} - 1 ))); do
+	echo foo[$i] is "${foo[$i]}" 
+    done
+}
+
+function print_foo_length() {
+    # Print length of array
+    echo length of array is ${#foo[@]}
+}
+
+function foo_push() {
+    this="${1}" 
+    echo pusing "${this}" 
+    # pop last element of foo
+    foo[$((${#foo[@]}))]="${this}" 
+}
+
+function foo_pop() {
+    # pop last element of foo
+    unset foo[$((${#foo[@]}-1))]    
+}
+
+
+
+print_foo_length
+print_foo
+
+# Push onto end of an array
+echo
+echo pushing three elements
+foo_push "one"
+foo_push "Two" 
+foo_push "THREE"
+print_foo_length
+print_foo
+
+
+# Pop elements
+echo
+echo popping two elemenets
+foo_pop
+foo_pop
+print_foo_length
+print_foo
+
+
+
+
+

+ 6 - 0
home/public/bash/bad.sh

@@ -0,0 +1,6 @@
+#! /bin/bash
+# echo 'normal' outpout to stdout, error output to stderr, exit 1
+
+echo Normal output from bad.sh
+echo ERROR output from bad.sh 1>&2
+exit 1

+ 272 - 0
home/public/bash/bashArrays.org

@@ -0,0 +1,272 @@
+* What
+  Functions to perform array operations in bash
+* Why
+  - I find the native syntax obtuse
+  - I like readable, understandable code
+  - I'm pretty sure bash is not going again
+  - Arrays are useful (well, pretty fundemental) to most code.
+  - Learn more bash
+
+* Why not
+
+  From http://robertmuth.blogspot.com/2012/08/better-bash-scripting-in-15-minutes.html
+
+  #+begin_quote
+  Signs you should not be using a bash script:
+  - your script is longer than a few hundred lines of code
+  - you need data structures beyond simple arrays
+  - you have a hard time working around quoting issues
+  - you do a lot of string manipulation
+  - you do not have much need for invoking other programs or pipe-lining them
+  - you worry about performance
+  #+end_quote
+
+  To which I might add, "You find yourself writing a group of array
+  functions to make bash arrays work more like python arrays
+  
+* Who
+  - George Jones <gmj@pobox.com> 
+  - Snippits and borrowing from all over, cited.
+
+* When
+  <2015-07-30 Thu>
+
+* Where  
+
+* How
+
+  - Define obviously named functions to do array operations.
+
+    Some possibly useful references:
+    - See http://rosettacode.org/wiki/Arrays#UNIX_Shell
+    - Maybe see http://mywiki.wooledge.org/BashFAQ/006
+    - http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_02.html
+
+** Create an array
+  #+name: arrayCreate
+  #+begin_src sh  :results output :exports both
+  exec 2>&1;set -e; set -u; set +x; echo '#' `date;`
+
+  source bashArrays.sh
+
+  unset foo
+  
+  pass=0
+  fail=0
+
+  errMsg=$(arrayCreate 2>&1) || true
+  arrayTest "Test missing array name" errMsg "createArray: Missing array name."  && ((pass+=1)) || ((fail+=1))
+
+  arrayCreate foo || true
+  arrayTest "Create array with no values" foo ""  && ((pass+=1)) || ((fail+=1))
+
+  arrayCreate foo  bar || true
+  arrayTest "Create array with one value" foo bar  && ((pass+=1)) || ((fail+=1))
+ 
+  arrayCreate foo  bar baz|| true
+  arrayTest "Create array with two values" foo bar baz && ((pass+=1)) || ((fail+=1))
+
+  #+end_src
+
+  #+RESULTS[9ef573b8eac102deebccfc2800dff5a7d0214706]: arrayCreate
+  : # Sat Aug 1 10:59:04 EDT 2015
+  : pass: Test missing array name
+  : pass: Create array with no values
+  : pass: Create array with one value
+  : pass: Create array with two values
+
+
+
+  
+** Append to an array
+  #+name: arrayAppend
+  #+begin_src sh  :results output :exports both
+      exec 2>&1;set -e; set -u; set +x; echo '#' `date;`
+
+      source bashArrays.sh
+
+      unset foo
+  
+      pass=0
+      fail=0
+      echo foo baz
+
+      # --- Test Setup ---
+      testName="Test missing array name"
+      expectedResults="arrayAppend: Missing array name."
+      # --- Run test ---
+      errMsg=$(arrayAppend 2>&1) || true
+      # --- Report Results ---
+      arrayTest "$testName" errMsg "$expectedResults" && ((pass+=1)) || ((fail+=1))
+
+
+      # --- Test Setup ---
+      testName="Attempt to append one element to a non-arrray"
+      unset foo
+      foo="bar"
+      expectedResults="arrayAppend: foo is not an array "
+      # --- Run test ---
+      errMsg=$(arrayAppend foo bar 2>&1) || true
+      #actualResults=("$errMeg")
+      #echo results $results
+      # --- Report Results ---
+      arrayTest "$testName: errMsg=/$errMsg/" foo $expectedResults  && ((pass+=1)) || ((fail+=1))
+
+
+      # --- Test Setup ---
+      testName="Append one element to non-existant array"
+      unset foo
+      expectedResults=""
+      # --- Run test ---
+      arrayAppend foo bar || true
+      actualResults="${foo[@]-}"
+      # --- Report Results ---
+      arrayTest "$testName: foo=/$actualResults/" foo $expectedResults  && ((pass+=1)) || ((fail+=1))
+
+      # --- Test Setup ---
+      testName="Append one element to existing empty array"
+      foo=()
+      expectedResults="bar"
+      # --- Run test ---
+      arrayAppend foo bar || true
+      actualResults="${foo[@]-}"
+      #echo results $results
+      # --- Report Results ---
+      arrayTest "$testName: foo=/$actualResults/" foo $expectedResults  && ((pass+=1)) || ((fail+=1))
+
+
+      # --- Test Setup ---
+      testName="Append one element to existing non-empty array"
+      foo=(foo)
+      expectedResults="foo bar"
+      # --- Run test ---
+      arrayAppend foo bar || true
+      actualResults="${foo[@]-}"
+      #echo results $results
+      # --- Report Results ---
+      arrayTest "$testName: foo=/$actualResults/" foo $expectedResults  && ((pass+=1)) || ((fail+=1))
+
+  #+end_src
+
+  #+RESULTS[da4ef9abb85551ed1c13b8585c8fb352e6c82657]: arrayAppend
+
+
+
+
+
+** Test variables to see if they are arrays
+  #+begin_src sh  :results output :exports both
+  exec 2>&1;set -e; set -u; set +x; echo '#' `date;`
+
+  source bashArrays.sh
+  pass=0
+  fail=0
+
+  array="noArray"
+  if isArray 2> /dev/null ; then value="noArray is an array"; else value="noArray is not an array"; fi
+  arrayTest "isArray run with no name"  value "noArray is not an array" && ((pass+=1)) || ((fail+=1))
+
+  if isArray "" ; then value="empty string is an array"; else value="empty string is not an array"; fi
+  arrayTest "isArray with an empty string" value "empty string is not an array" && ((pass+=1)) || ((fail+=1))
+
+  foo="foo"
+  if isArray foo ; then value="foo is an array"; else value="foo is not an array"; fi
+  arrayTest "isArray run on string" value "foo is not an array" && ((pass+=1)) || ((fail+=1))
+
+
+  foo=(foo bar)
+  if isArray bar ; then value="foo is an array"; else value="foo is not an array"; fi
+  arrayTest "isArray run on array" value "foo is an array" && ((pass+=1)) || ((fail+=1))
+
+
+  #+end_src
+
+  #+RESULTS[9be0f9156f51054d6817aecee9ec4114aa8d1792]:
+  : # Sat Aug 1 09:42:59 EDT 2015
+  : pass: isArray run with no name
+  : isArray: Missing array name.
+  : pass: isArray with an empty string
+  : pass: isArray run on string
+  : fail: isArray run on array
+
+
+
+** Append to an array OLD
+  #+name: arrayAppendold
+  #+begin_src sh  :results output :exports both
+#  exec 2>&1;set -e; set -u; set +x; echo '#' `date;`
+    set -u;  set +x; echo '#' `date;`
+
+  source bashArrays.sh
+  
+  echo 
+  echo APPEND TO ARRAY
+  echo 
+
+  arrayCreate qux 2>&1 || true
+  echo qux is ${qux[@]:-}
+  echo
+ 
+  arrayAppend qux one || true
+  echo foo is ${foo[@]:-} || true
+  echo
+  
+  arrayAppend quuux two three || true
+  echo quuux is ${quuux[@]:-''} || true
+  echo
+
+  arrayAppend || true
+  echo quuux is ${quuux[@]:-''} || true
+  echo
+   
+  #+end_src
+
+
+
+
+ 
+
+
+  #
+  # Prepend to an array
+  #
+
+  #
+  # test if array contains an element
+  # http://stackoverflow.com/questions/3685970/check-if-an-array-contains-a-value
+
+  if 
+
+  #
+  # Remove element form an array
+  #
+
+  #
+  # Split to create an array
+  #
+
+  #
+  # Join array to create string
+  #
+
+  #
+  # Delete an array
+  #
+
+  #
+  # Test
+  #
+
+  arrayCreate "foo"
+
+  echo Done.
+  #+end_src
+
+  #+RESULTS:
+  : # Thu Jul 30 05:24:52 EDT 2015
+  : foo
+  : Done.
+
+
+
+ 

+ 177 - 0
home/public/bash/bashArrays.sh

@@ -0,0 +1,177 @@
+# Bash array fucntions
+#
+# Copyright (C) George Jones <gmj@pobox.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# * TODO LIST
+# ** Functions to add
+#    -arraySplit
+#    -arrayJoin
+#    -arrayPrepend (special case of append? with switch/option? wrapper?)
+#
+# ** General  TODOs
+#   - Run validation tests, mark funcions as working or not, return 1 if not working.
+#   - Figure out some way to add options/config, e.g. --noclobber for create, etc.
+
+#
+# http://www.linuxjournal.com/content/return-values-bash-functions
+# 
+
+
+
+source bashUtils.sh
+
+isArray() {
+    # Test if variable is an array
+    #
+    # Usage: isArray NAME
+    # Return: 0 if NAME is array, 1 otherwise.
+    #
+    # https://gist.github.com/coderofsalvation/8377369
+    #
+    export arrayError=""
+    
+    if [ -z "${1:-}" ]; then 
+	arrayError="isArray: Missing array name."
+	return 1
+    fi
+    
+    if [ -n "$BASH" ]; then
+        # this is officially a hack, but it seems to be the best solution.  Yuck.
+        declare -p ${1:-''} 2> /dev/null | grep 'declare \-a' >/dev/null && return 0
+    fi
+
+    arrayError="isArray: ${1} is not an array."    
+    return 1
+}
+
+arrayCreate() {
+    # Create an array.
+    #
+    # Usgae: arrayCreate NAME [element1 element2...]
+    # Ouput: NAME set as global, $arrayErr set as error message
+    # Return: 0 if defined, 1 otherwise.
+    #
+    export arrayError=""
+    
+    if [ -z "${1:-}" ]; then
+	arrayError="arrayCreate: Missing array name."
+	echo  $arrayError 1>&2 
+        return 1
+    fi
+
+    local var=${1}
+    shift
+    
+    if [ -z "${1:-}" ]; then
+        foo="foo"
+	eval "$var=( )"
+    else
+	eval "$var=(  $@ )"
+    fi
+
+    return 0
+}
+
+arrayLength() {
+   echo "Implment this.  Reurn length"
+}
+
+#
+# void addelementtoarray (string <array_name>, string <element>, ...)
+#
+
+
+	# http://www.linuxquestions.org/questions/programming-9/bash-array-add-function-example-using-indirect-array-reference-as-function-argument-815329/
+
+function arrayAppend {
+    export arrayError=""
+
+    if [ -z "${1:-}" ]; then 
+	arrayError="arrayAppend: Missing array name."
+	return 1
+    fi
+    
+    local R=$1
+    shift
+
+    echo R is $R
+
+    status=isArray $R
+    if [ ! $status ]; then 
+	arrayError="arrayAppend: $R is not an array "
+	return 1 
+    fi
+
+    echo $R is an array
+    exit 1
+
+    for A; do
+        eval "$R[\${#$R[@]}]=\$A"
+    done
+    return 0
+
+    # Or a one liner but more runtime expensive with large arrays since all elements will always expand.
+    # In this method also, all element IDs are reset starting from 0.
+    # Maybe this is also what you need since the IDs here does not need to be sorted.  A problem may occur on the former if an ID exist that is higher than the number of elements.
+    # Only that it resets all IDs everytime.
+    # eval "$1=(\"\${$1[@]}\" \"${2:@}\")"
+}
+
+
+arrayTest() {
+    # execute a test of array expected values
+    #
+    # Usage: arrayTest "test name" "expected results "actual results"
+    # Output: pass/fail message to stdout
+    # Return: 0 on pass, 1 otherwise
+
+    [ -z "${1:-}" ] && echo "arrayTest: Missing test name." 1>&2 && return 1
+    local testName="${1:-}"
+    shift
+    
+    [ -z "${1:-}" ] && echo "arrayTest: Missing expected values." 1>&2 && return 1
+    local expectedValues="${1:-}"
+    shift
+
+    [ -z "${1:-}" ] && echo "arrayTest: Missing actual values." 1>&2 && return 1
+    local actualValues="${1:-}"
+    shift
+
+    if stringsEqual "${expectedValues-}" "${actualValues-}"; then
+       echo pass: $testName
+       return 0
+    else
+       echo diff expected values and actual values 1>&1
+       diff -b  <(echo "$expectedValues" ) <(echo "$actualValues")
+       echo fail: $testName
+       return 1
+    fi
+}
+
+
+arraySplit() {
+    echo "Implment this.  Take char/regexp, split, return array"
+}
+
+
+arrayJoin() {
+    echo "Implment this.  Take char/regexp, rarray, join, return array"
+}
+
+arrayDestroy() {
+    echo "Implenet this.  unset an array."
+}

+ 291 - 0
home/public/bash/bashArraysTest.sh

@@ -0,0 +1,291 @@
+#! /bin/bash
+
+#
+# Test bashArays.sh
+
+#
+
+#
+# TODO List:
+#   - Wrap this up as an init function.   Create a "thisWorks" assosiative array
+#     indexed by the name of the function (hmm, maybe what I'm after is properties
+#     associated with variables and functions ... lisp?).  Then functions can all do
+#     something like
+#
+#         thisWorks[$myFunctionName] || \
+#             "thisWorks: $myFunctioName not working here." 1>&2 && \
+#              return 1
+#
+
+set -e; set -u; set +x; echo '#' `date;`
+
+#
+# Overall test setup
+#
+source bashArrays.sh
+
+#
+# Run bash array test functions
+#
+bashArrayTests() {
+  arrayCreateTests
+  isArrayTests 
+  arrayAppendTests 
+  reportTotals
+}
+
+#
+# Report totals
+#
+pass=0
+fail=0
+
+reportTotals() {
+  echo
+  echo "pass: Total == $pass"
+  echo "fail: Total == $fail"
+
+  if [[ $pass -gt 0 && $fail -eq 0 ]]; then
+      echo All passed.
+      return 0
+  else
+      echo Failures.
+      return $fail      
+  fi
+}
+
+
+#
+# arrayCreate tests
+#
+
+
+arrayCreateTests() {
+    testClass="arrayCreate"
+    
+    testName="$testClass: Test missing array name"
+    expectedResults="arrayCreate: Missing array name."
+    # --- Run test ---
+    arrayCreate || true
+    
+    if [ -z "$arrayError" ]; then	
+	results="Array create failed to return an error"
+    else
+	results="$arrayError"
+    fi
+    
+     # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))
+
+    #
+    # TODO use this as the model for error handling
+    #
+    # TODO change all funtions to set arrayError
+    #
+    # TODO change all tests to set results to arrayError if error else array value
+
+
+
+    testName="$testClass: Create an empty array"
+    expectedResults="NONE"    
+    # --- Run test ---
+    arrayCreate foo  || true
+
+    if [ -z "$arrayError" ]; then
+	results="NONE${foo[@]:-}"
+    else
+	results="$arrayError"
+    fi
+    
+     # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))
+
+
+    testName="$testClass: Create an array with several elements"
+    expectedResults="bar baz"    
+    # --- Run test ---
+    arrayCreate foo bar baz || true
+
+    if [ -z "$arrayError" ]; then
+	results=${foo[@]} 
+    else
+	results="$arrayError"
+    fi
+    
+     # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))
+
+
+
+}
+
+
+
+arrayCreateTestsOld() {
+    testClass="arrayCreate"
+
+# TODO
+#     Capture errors something like this
+#
+#     err=$(arrayCreate 2>&1) && echo true || echo false
+#
+#     Rework all my error tests using this.  use err for actual value if failed
+    
+    # --- Test Setup ---
+    testName="$testClass: Create an array with several elements"
+    expectedResults="bar baz"
+    # --- Run test ---
+    errMsg=$(arrayCreate foo bar baz 2>&1)
+    echo "foo is ${foo[@]-}"
+    # --- Report Results ---
+    arrayTest "$testName: errMsg=/$errMsg/" foo "$expectedResults" && ((pass+=1)) || ((fail+=1))
+
+    return 0
+}
+
+
+#
+# isArray tests
+#
+
+isArrayTests() {
+    testClass="isArray"
+
+    # --- Test Setup ---
+    testName="$testClass: test isArray wtih missing array name"
+    expectedResults="isArray: Missing array name."
+    # --- Run test ---
+
+    isArray || true
+
+    if [ -z "$arrayError" ]; then	
+	results="isArray failed to return an error"
+    else
+	results="$arrayError"
+    fi
+
+    # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))    
+
+
+
+    # --- Test Setup ---
+    testName="$testClass: test isArray on empty string"
+    expectedResults="isArray: Missing array name."
+    # --- Run test ---
+    isArray "" || true
+
+    if [ -z "$arrayError" ]; then	
+	results="isArray failed to return an error"
+    else
+	results="$arrayError"
+    fi
+
+    # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))        
+
+    
+    # --- Test Setup ---
+    testName="$testClass: test isArray on string"
+    expectedResults="isArray: foox is not an array."
+    unset foox
+    foox="foox"
+    # --- Run test ---
+    isArray foox || true
+
+    if [ -z "$arrayError" ]; then	
+	results="isArray failed to return an error"
+    else
+	results="$arrayError"
+    fi
+
+    # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))        
+
+    # --- Test Setup ---
+    testName="$testClass: test isArray on an actual array"
+    expectedResults="NONE"
+    foo=(foo bar)
+    # --- Run test ---
+
+    isArray foo
+
+    if [ -z "$arrayError" ]; then	
+	results="NONE"
+    else
+	results="$arrayError"
+    fi
+
+    # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))        
+
+
+
+
+    return 0
+}
+
+
+arrayAppendTests() {
+    testClass="arrayAppend"
+
+    # --- Test Setup ---
+    testName="$testClass: Test missing array name"
+    expectedResults="arrayAppend: Missing array name."
+    # --- Run test ---
+    arrayAppend || true
+    if [ -z "$arrayError" ]; then	
+	results="isArray failed to return an error"
+    else
+	results="$arrayError"
+    fi
+    # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))    
+
+    # --- Test Setup ---
+    testName="$testClass: Attempt to append one element to a non-arrray"
+    expectedResults="arrayAppend: foo is not an array "
+    unset qux
+    # --- Run test ---
+    arrayCreate qux
+    arrayAppend qux bar || true
+
+    if [ -z "$arrayError" ]; then	
+	results="isArray failed to return an error"
+    else
+	results="$arrayError"
+    fi
+
+    # --- Report Results ---
+    arrayTest "$testName" "$results" "$expectedResults" && ((pass+=1)) || ((fail+=1))    
+    
+
+    return 0    
+    
+    # --- Test Setup ---
+    testName="$testClass: Append one element to existing empty array"
+    foo=()
+    expectedResults="bar"
+    # --- Run test ---
+    arrayAppend foo bar || true
+    actualResults="${foo[@]-}"
+    #echo results $results
+    # --- Report Results ---
+    arrayTest "$testName: foo=/$actualResults/" foo $expectedResults  && ((pass+=1)) || ((fail+=1))
+    
+    # --- Test Setup ---
+    testName="$testClass: Append one element to existing non-empty array"
+    foo=(foo)
+    expectedResults="foo bar"
+    # --- Run test ---
+    arrayAppend foo bar || true
+    actualResults="${foo[@]-}"
+    #echo results $results
+    # --- Report Results ---
+    arrayTest "$testName: foo=/$actualResults/" foo $expectedResults  && ((pass+=1)) || ((fail+=1))
+
+    return 0
+}
+    
+
+

+ 24 - 0
home/public/bash/bashAssociateveArrays.sh

@@ -0,0 +1,24 @@
+#! /bin/bash
+
+# http://rosettacode.org/wiki/Associative_array/Creation#UNIX_Shell
+
+declare -a arglist
+
+declare -A hash
+hash=( [key1]=val1 [key2]=val2 )
+hash[key3]=val3
+echo "${hash[key3]}"
+
+arglist[${#arglist[*]}]=hash
+
+declare -A hash2
+hash2=( [key1]=val1a [key2]=val2b )
+
+arglist[${#arglist[*]}]=hash2
+
+for arg in arglist; do
+  echo key1 ${arg[key1]}
+done
+
+
+#arg["stack-size"]=("s:","stack-size:","Stack size","[0-9"]

+ 16 - 0
home/public/bash/bashFunctionsWithArguments.sh

@@ -0,0 +1,16 @@
+# Define a bash function that takes an argument
+# (in this case, because aliases don't)
+
+
+function hgt() {
+    # hgt == "history grep (for arg) tail"
+    #echo "Histroy Grep tail"
+
+    if [ -z ${1+x} ]; then
+        echo 'hgt needs an argument' 1>&2
+        return 1
+    fi
+
+    history | grep -i "$1" | tail
+    return 0
+}

+ 39 - 0
home/public/bash/bashGetopt.sh

@@ -0,0 +1,39 @@
+#!/bin/bash
+#  SOURCE: https://gist.github.com/cosimo/3760587
+#  SEE ALSO: http://stackoverflow.com/questions/15103482/bash-getopt-command-returns-its-own-parameters-instead-of-command-line-parameter
+#
+# Example of how to parse short/long options with 'getopt'
+#
+# getopt links:
+
+
+
+#   
+ 
+OPTS=`getopt -o vhns: --long verbose,dry-run,help,stack-size: -n 'parse-options' -- "$@"`
+ 
+if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
+ 
+echo "$OPTS"
+eval set -- "$OPTS"
+ 
+VERBOSE=false
+HELP=false
+DRY_RUN=false
+STACK_SIZE=0
+ 
+while true; do
+  case "$1" in
+    -v | --verbose ) VERBOSE=true; shift ;;
+    -h | --help )    HELP=true; shift ;;
+    -n | --dry-run ) DRY_RUN=true; shift ;;
+    -s | --stack-size ) STACK_SIZE="$2"; shift; shift ;;
+    -- ) shift; break ;;
+    * ) break ;;
+  esac
+done
+ 
+echo VERBOSE=$VERBOSE
+echo HELP=$HELP
+echo DRY_RUN=$DRY_RUN
+echo STACK_SIZE=$STACK_SIZE

+ 117 - 0
home/public/bash/bashGetopt2.sh

@@ -0,0 +1,117 @@
+#! /bin/bash
+# This is here as an example of doing getopt in bash without getopt
+
+# Do a quick status (git branch -vv) on one or more git repos
+#
+# Usage: gitstat [-f|-s] dir [dir...]
+#
+# -f - Fetch first
+# -s - Short Status
+
+set -e;  set -u
+ARGV=("$@")
+ARGC=("$#")
+#ARGV=("${ARGV[@]:1}") # shift ARGV
+#ARGC=${#ARGV[@]} # get count
+
+# Helper functions
+PROG=`basename "$0" | tr -d '\n'`
+
+function info()  { echo `date +%c` ${PROG}\: info: "$@" 1>&2; }
+function warn()  { echo `date +%c` ${PROG}\: warning: "$@" 1>&2; }
+function error() { echo `date +%c` ${PROG}\: error: "$@" 1>&2; }
+function debug() { [[ -v DEBUG ]] && echo `date +%c` ${PROG}\: debug: "$@" 1>&2 || true ; }
+function die()   { echo `date +%c` ${PROG}\: fatal: "$@" 1>&2 && exit 1; }
+
+
+function usage() {
+    debug "in ${FUNCNAME[0]}"
+
+    if [[ "$#" -gt 0 ]]; then
+        warn $@
+    fi
+
+    cat <<END 1>&2
+Usage: PROG [options] [args]
+
+   arguments
+     arg1               describe arg1
+
+   options
+
+    Group 1
+
+    -a|--abc            what does --abc do?
+
+    Other
+
+    -d|--debug         debug output
+    -h|--help          print usage
+    -v|--verbose       verbose output
+END
+    exit 1
+}
+
+fetch=false
+status=false
+
+function show_usage() {
+    echo Usage: gitstat [-f] [-s] [dir[dir...]]
+    exit 1
+}
+
+while [ "$ARGC" != "0" ];do
+   case "${ARGV[0]}" in
+        -h|--help)
+          show_usage
+          ;;
+        -f|--fetch)
+          fetch="true"
+          ;;
+        -s|--sleep)
+          status="true"
+          ;;
+        *)
+            if [[ "$1" =~ ^- ]]; then
+                echo unknown flag $1
+                show_usage
+            else
+                break
+            fi
+   esac
+ARGV=("${ARGV[@]:1}") # shift ARGV
+done
+
+ARGC=$#
+
+if [ "$ARGC" == "0" ]; then
+    set -- `pwd` "$@" # add pwd if no args
+fi
+
+for i in $* ; do
+
+    if [ "$i" == "-f" ]; then
+        fetch=true
+        continue
+    fi
+
+    if [ "$i" == "-s" ]; then
+        status=true
+        continue
+    fi
+
+    if [ "$fetch" == "true" ]; then
+        git fetch
+    fi
+
+    \pushd $i > /dev/null;
+    echo $i;
+
+    if [ "$status" == "true" ]; then
+        git status -s
+    else
+        git branch -vv;
+    fi
+    echo;
+    \popd > /dev/null;
+done

+ 69 - 0
home/public/bash/bashHash.sh

@@ -0,0 +1,69 @@
+#! /bin/bash
+
+set -u -e
+
+# http://rosettacode.org/wiki/Associative_array/Creation#UNIX_Shell
+
+declare -a arglist=""
+
+declare -A hash
+hash=( [key1]=val1 [key2]=val2 )
+hash[key3]=val3
+echo "${hash[key3]}"
+
+#for i in "${!array[@]}"
+#do
+#  echo "key  : $i"
+#  echo "value: ${array[$i]}"
+#done
+
+# http://stackoverflow.com/questions/6149679/bash-need-some-help-with-multidimensional-associative-arrays
+
+#arg["stack-size"]=("s:","stack-size:","Stack size","[0-9"]
+
+# The following associateve arrays define options
+# There should be one entry for each option, indexed by shortname.
+# If there is no shortname, just use a unique value (the long name?)
+#
+declare -A optShortNames	# short names of options
+declare -A optLongNames		# long nmaes of options
+declare -A optDefault		# Default value, or blank.
+declare -A optValidateRE	# Validation regular expression, or blank.
+declare -A optHelp		# Option help sring.
+
+optShortNames["v"]="v"
+optLongNames["v"]="verbose"
+optDefault["v"]=""
+optValidateRE["v"]=""
+optHelp["v"]="Be verbose"
+
+
+optShortNames["s"]="s:"
+optLongNames["s"]="stacksize:"
+optDefault["s"]="s999"
+optValidateRE["s"]="^[0-9]+$"
+optHelp["s"]="Specifiy stack size.  Integer.  Default: None."
+
+
+declare -p optShortNames
+declare -p optLongNames
+declare -p optValidateRE
+declare -p optHelp
+
+for bar in ${!optShortNames[@]}; do
+    echo
+    echo bar $bar
+        
+    echo optShortNames ${optShortNames[$bar]}
+    echo optLongNames ${optLongNames[$bar]}
+    echo optDfault ${optDefault[$bar]}
+    echo optValidateRE ${optValidateRE[$bar]}
+    echo optHelp ${optHelp[$bar]}
+
+    if [[ ${optDefault[$bar]} =~ ${optValidateRE[$bar]} ]]; then  
+	echo  valid default value;
+    else
+	echo  bad default value;
+    fi
+    
+done

+ 96 - 0
home/public/bash/bashUtils.sh

@@ -0,0 +1,96 @@
+#
+# Bash utility functions.
+#
+# George Jones <gmj@pobox.com>, 2018-12-24
+#
+
+set -e; set -u
+
+ARGV=("$@")
+ARGC=("$#")
+#ARGV=("${ARGV[@]:1}") # shift ARGV
+#ARGC=${#ARGV[@]} # get count
+
+# Helper functions
+PROG=`basename "$0" | tr -d '\n'`
+
+function info()  { echo `date +%c` ${PROG}\: info: "$@" 1>&2; }
+function warn()  { echo `date +%c` ${PROG}\: warning: "$@" 1>&2; }
+function error() { echo `date +%c` ${PROG}\: error: "$@" 1>&2; }
+function debug() { [[ -v DEBUG ]] && echo `date +%c` ${PROG}\: debug: "$@" 1>&2 || true ; }
+function die()   { echo `date +%c` ${PROG}\: fatal: "$@" 1>&2 && exit 1; }
+
+
+function usage() {
+    debug "in ${FUNCNAME[0]}"
+
+    if [[ "$#" -gt 0 ]]; then
+        warn $@
+    fi
+
+    cat <<END 1>&2
+Usage: PROG [options] [args]
+
+   arguments
+     arg1               describe arg1
+
+   options
+
+    Group 1
+
+    -a|--abc            what does --abc do?
+
+    Other
+
+    -d|--debug         debug output
+    -h|--help          print usage
+    -v|--verbose       verbose output
+END
+    exit 1
+}
+
+
+# http://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable
+
+trim() {
+    # trim leading and trailing spaces
+    local var="$*"
+    var="${var#"${var%%[![:space:]]*}"}"   # remove leading whitespace characters
+    var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
+    echo -n "$var"
+}
+
+squash() {
+    # remove all apaces
+    local var="$*"
+    echo "${var//[[:blank:]]/}"
+}
+
+lc() {
+    # lowercase
+    local var="$*"
+    echo "$var" |  tr '[:upper:]' '[:lower:]'
+}
+
+
+stringsEqual() {
+    # case-insensitive comparison with spaces removed
+    onePrime=$(lc $(squash $1))
+    twoPrime=$(lc $(squash $2))
+    [[ "$onePrime" == "$twoPrime" ]] && return 0 || return 1
+}
+
+
+stringTests() {
+    foo=" foo"
+    bar="foo "
+    foobar=" F o b"
+
+    echo "trim /$foo/ /$(trim $foo)/"
+    echo "trim /$bar/ /$(trim $bar)/"
+    echo "squash /$foobar/ /$(squash $foobar)/"
+    echo "lc /$foobar/ /$(lc $foobar)/"
+    echo "lc squash /$foobar/ /$(lc $(squash $foobar))/"
+
+    if stringsEqual "$foo" "$bar";then echo same; else echo different;fi
+}

+ 13 - 0
home/public/bash/bashmod.sh

@@ -0,0 +1,13 @@
+#! /bin/bash
+# Example of mod function in a loop
+
+start=`date +%s`
+
+for i in {1..100}; do
+  if ((i % 20 == 0)); then
+    echo $i
+    sleep 1
+    now=`date +%s`
+    echo start: $start now: $now elapsed: $((now-start))
+  fi
+done

+ 5 - 0
home/public/bash/chaining-commands-based-on-exit-status.sh

@@ -0,0 +1,5 @@
+#! /bin/bash
+# Demonstrat command chaning based on exit status of previous command
+
+./good.sh && echo RUNNING NEXT COMMAND after good.sh
+./bad.sh && echo RUNNING NEXT COMMAND AFTER bad.sh

+ 17 - 0
home/public/bash/f-alias.sh

@@ -0,0 +1,17 @@
+#! /bin/bash
+# Wrapper to find.  Case-insensitive match on substring of path.
+#
+# Usage: f NAME [other-find-args]
+
+# make sure we hvae a debug function
+debug is defined  2>/dev/null || function debug() { [[ -v DEBUG ]] && >&2 echo $*; }
+
+function f() {
+  NAME=$1
+  shift
+  REST=($*)
+
+  debug COMMAND find . -ipath '*'"${NAME}"'*' ${REST[*]}
+
+  find . -ipath '*'"${NAME}"'*' ${REST[*]}
+}

+ 6 - 0
home/public/bash/good.sh

@@ -0,0 +1,6 @@
+#! /bin/bash
+# echo 'normal' outpout to stdout, error output to stderr, exit 0
+
+echo Normal output form good.sh
+echo ERROR output form good.sh 1>&2
+exit 0

+ 22 - 0
home/public/bash/imageDates.sh

@@ -0,0 +1,22 @@
+#! /bin/bash
+# What: List image dates for files in this directory
+# 
+# How (Usage):
+#   imageDates.sh
+#
+# Who: George Jones
+#
+# When: Wed Dec 16 04:34:54 2015 
+#
+# Why: I have a lot of pictures
+#
+# Future
+#   -  possiby set image dates from file/directory names
+#      (e.g. if long ago I grouped files into directorys or put dates on scanned immages
+#      add the data to exif)
+#   -  Be more creative/general with command line arguments
+#
+# Where:
+#   - See: http://www.exiv2.org/index.html
+
+for i in *.jpg; do  when=`exif -m --tag=0x132 2> /dev/null $i`; echo \| $i \| $when \|; done

+ 146 - 0
home/public/bash/jpgHasDate

@@ -0,0 +1,146 @@
+#! /bin/bash 
+#title           :jpgHasDate.sh
+#description     :Determine if an JPEG file has a date
+#author		 :gmj@pobox.com
+#date            :Sat Dec 19 15:35:06 2015
+#version         :0.1
+#usage		 :jpgHasDate.sh [optinos] FILE [FILE...]
+#notes           :Experimeting with well-writtne bash
+#bash_version    :
+#==============================================================================
+
+set -u   # exit on undefined
+set -e   # exit on error
+# set -x # echo during execution
+
+# Useful tips
+# http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/
+readonly PROGNAME=$(basename $0)
+readonly PROGDIR=$(readlink -m $(dirname $0))
+readonly ARGS="$@"
+
+usage() {
+    if [ $# -gt 0 ]; then echo  "${PROGNAME}: $@"; echo; fi
+    cat <<- EOF
+usage: $PROGNAME [options] FILE [FILE...]
+    
+This program determins if a JPEG file has an Original Date stored
+with it and prints the filename and/or date.
+
+OPTIONS:
+   -w --withdates	Select files with dates
+   -m --missingdates	Select files with no dates
+   -p --path		Print path of matching files
+   -t --dates		Print dates of matching files
+   -v --verbose         Verbose. You can specify more then one -v to have more verbose
+   -d --debug           debug
+   -h --help            show this help
+    
+Examples:
+   print info about a single file
+   $PROGNAME --test all
+
+EOF
+}
+
+
+parseArgs() {
+    # Option parsing courtesy of 
+    # http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options
+
+
+    # NOTE: This requires GNU getopt.  On Mac OS X and FreeBSD, you have to install this
+    # separately; see below.
+    TEMP=`getopt -o wmptvdh --long withdates,missingdates,path,dates,verbose,debug,help \
+            	  -n 'jpghasDate' -- "$@"`
+
+    if [ $? != 0 ] ; then echo "getopt failed. Terminating..." >&2 ; exit 1 ; fi
+
+    # Note the quotes around `$TEMP': they are essential!
+    eval set -- "$TEMP"
+
+
+    # Set default values
+
+    # Selection Parameters
+    OPT_SELECT_WITH_DATES=false		# print files that have dates
+    OPT_SELECT_MISSING_DATES=false	# print files with no date
+    # Output Parameters
+    OPT_VERBOSE=false			# verbose output
+    OPT_DEBUG=false			# debugging output
+    OPT_PRINT_PATH=false  		# print path
+    OPT_PRINT_DATES=false		# print date
+    OPT_PRINT_ALL=true			# print all (default)
+
+    while true; do
+	case "$1" in
+	    -w | --withdates ) OPT_SELECT_WITH_DATES=true; shift ;;
+	    -m | --missingdates ) OPT_SELECT_MISSING_DATES=true; shift ;;
+	    -p | --path ) OPT_PRINT_PATH=true; shift ;;
+	    -t | --dates ) OPT_PRINT_DATES=true; shift ;;
+	    -v | --verbose ) OPT_VERBOSE=true; shift ;;
+	    -d | --debug ) OPT_DEBUG=true; shift ;;
+	    -h | --help ) usage; exit 0;shift ;;        
+	    -- ) shift; break ;;
+	    * ) break ;;
+	esac
+    done
+    
+    if [ $# -lt 1 ] ; then usage "Missing argument.  Need at least one filename."; exit 1; fi
+
+    # Defualt to printing all
+    if ! ( $OPT_PRINT_PATH || $OPT_PRINT_DATES ); then 
+	OPT_PRINT_PATH=true
+	OPT_PRINT_DATES=true
+    fi
+    
+    # Defualt to selectiing all
+    if ! ( $OPT_SELECT_WITH_DATES || $OPT_SELECT_MISSING_DATES ); then 
+	OPT_SELECT_WITH_DATES=true
+	OPT_SELECT_MISSING_DATES=true
+    fi
+
+    # Make parsing paramters readonly
+
+    readonly OPT_SELECT_WITH_DATES=${OPT_SELECT_WITH_DATES}	# print files that have dates
+    readonly OPT_SELECT_MISSING_DATES=${OPT_SELECT_MISSING_DATES}	# print files with no date
+    readonly OPT_VERBOSE=${OPT_VERBOSE}				# verbose output
+    readonly OPT_DEBUG=${OPT_DEBUG}				# debugging output
+    readonly OPT_PRINT_PATH=${OPT_PRINT_PATH}			# print path
+    readonly OPT_PRINT_DATES=${OPT_PRINT_DATES}			# print date
+    readonly OPT_PRINT_ALL=${OPT_PRINT_ALL}			# print all (default)
+
+    readonly OPT_ARGS="$@"
+}
+
+printSelectedFiles () {
+    for file in "$*"; do
+	if $OPT_DEBUG; then echo file $file >&2; fi
+	date=$(exiftool $file | grep Orig || echo "NONE")
+	date=$(echo $date | sed -e 's/Date\/Time Original\s*\:\s*//')
+	output=""
+
+	if $OPT_PRINT_PATH; then output="$file"; fi
+
+	if $OPT_PRINT_DATES; then output="$output : $date"; fi
+	
+	if $OPT_SELECT_MISSING_DATES; then 
+	    if [[ $date == *"NONE"* ]]; then
+		echo $output
+	    fi
+	fi
+
+	if $OPT_SELECT_WITH_DATES; then 
+	    if [[ $date != *"NONE"* ]]; then
+		echo $output
+	    fi
+	fi    
+    done
+}
+
+main() {
+    parseArgs $ARGS
+    printSelectedFiles $OPT_ARGS
+}
+
+main

+ 15 - 0
home/public/bash/lines.txt

@@ -0,0 +1,15 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15

+ 29 - 0
home/public/bash/listAllFilesInLoop.org

@@ -0,0 +1,29 @@
+#! /bin/bash
+
+
+#+begin_src shell  :results output :exports both
+  exec 2>&1;date;set -e; set -u; # set -x
+
+  # List all files matching glob, do something to them.
+  # Handle non-existant files/non-matching globs
+
+  touch a.txt b.txt c.txt d.dat
+  rm -f e.DNE
+
+  for i in *.txt *.dat *.DNE; do
+
+      if [ -f $i ]; then
+	  echo i is $i
+      fi
+  done
+
+  rm -f a.txt b.txt c.txt d.dat
+#+end_src
+
+#+RESULTS:
+: Tue Jul 25 06:28:55 EDT 2017
+: i is a.txt
+: i is b.txt
+: i is c.txt
+: i is d.dat
+

+ 4 - 0
home/public/bash/runAll.sh

@@ -0,0 +1,4 @@
+
+#! /bin/bash
+
+source bashArraysTest.sh && bashArrayTests

+ 40 - 0
home/public/bash/sort_csv.sh

@@ -0,0 +1,40 @@
+function sort_csv() {
+    # Sort a csv file
+    #
+    # Perform a sort of a csv file on a single numberic column
+    #
+    # Inputs
+
+    local INPUT_FILE=$1 # file to sort
+    local SORT_ON=$2 # numerc field to sort
+    local HEADER_LINES=${3:-1}  # number of header lines
+
+    # local vars
+    local SORT_THIS=`TMPDIR=. mktemp`
+    local SAVED_HEADERS=`TMPDIR=. mktemp`
+    local MOVE_SUCCEEDED=0 # track if we can restore from the tmp file
+    local RESTORE_ORIGINAL=1  # if anything goes wrong, restore original
+    # local CSV_HEADER_LINE=$((1+LINES_BEFORE_HEADER))
+
+
+    # | tee >(head -1 > $STATS_FILE) | tail -n+2 | sort -gr -k $sort_field -t,
+
+    sed -n "1,${HEADER_LINES}p" <$INPUT_FILE > $SAVED_HEADERS
+    mv $INPUT_FILE $SORT_THIS && \
+        MOVE_SUCCEEDED=1 && \
+        mv $SAVED_HEADERS $INPUT_FILE && \
+        sort -t, -gr -k $SORT_ON <(tail -n+$((1+HEADER_LINES)) $SORT_THIS) >> $INPUT_FILE && \
+        RESTORE_ORIGINAL=0
+
+    if ((RESTORE_ORIGINAL)); then
+        # do this in case anything went wrong
+        >&2 echo "sort_csv: something went wrong."
+
+        if ((MOVE_SUCCEEDED)); then
+            >&2 echo "sort_csv: restoring $INPUT_FILE from $SORT_THIS"
+            rm -f $INPUT_FILE
+            mv $SORT_THIS $INPUT_FILE
+            >&2 echo "sort_csv: restore succeeded"
+        fi
+    fi
+}

+ 75 - 0
home/public/bash/tests/README.txt

@@ -0,0 +1,75 @@
+On 2020-04-19 I reported performance issues with the associative array
+insert speeds in bash.   In less than 24 hours, there is a pattch:
+
+https://lists.gnu.org/archive/html/bug-bash/2020-04/msg00114.html
+
+This directory contains some test code I wrote and some long story
+short, insert time is now linear.
+
+Before Patch:
+
+lines_per_sec 20000.00 LINES 100000 ELAPSED 5
+lines_per_sec 13333.33 LINES 200000 ELAPSED 15
+lines_per_sec 10000.00 LINES 300000 ELAPSED 30
+lines_per_sec 7843.13 LINES 400000 ELAPSED 51
+lines_per_sec 6410.25 LINES 500000 ELAPSED 78
+lines_per_sec 5405.40 LINES 600000 ELAPSED 111
+lines_per_sec 4635.76 LINES 700000 ELAPSED 151
+lines_per_sec 4020.10 LINES 800000 ELAPSED 199
+lines_per_sec 3529.41 LINES 900000 ELAPSED 255
+lines_per_sec 3105.59 LINES 1000000 ELAPSED 322
+lines_per_sec 2777.77 LINES 1100000 ELAPSED 396
+lines_per_sec 2510.46 LINES 1200000 ELAPSED 478
+lines_per_sec 2280.70 LINES 1300000 ELAPSED 570
+lines_per_sec 2086.43 LINES 1400000 ELAPSED 671
+lines_per_sec 1923.07 LINES 1500000 ELAPSED 780
+lines_per_sec 1777.77 LINES 1600000 ELAPSED 900
+lines_per_sec 1655.30 LINES 1700000 ELAPSED 1027
+lines_per_sec 1550.38 LINES 1800000 ELAPSED 1161
+lines_per_sec 1457.05 LINES 1900000 ELAPSED 1304
+lines_per_sec 1375.51 LINES 2000000 ELAPSED 1454
+lines_per_sec 1302.72 LINES 2100000 ELAPSED 1612
+lines_per_sec 1238.04 LINES 2200000 ELAPSED 1777
+lines_per_sec 1179.48 LINES 2300000 ELAPSED 1950
+lines_per_sec 1126.23 LINES 2400000 ELAPSED 2131
+lines_per_sec 1078.51 LINES 2500000 ELAPSED 2318
+lines_per_sec 1034.20 LINES 2600000 ELAPSED 2514
+lines_per_sec 993.37 LINES 2700000 ELAPSED 2718
+lines_per_sec 955.95 LINES 2800000 ELAPSED 2929
+lines_per_sec 921.51 LINES 2900000 ELAPSED 3147
+lines_per_sec 889.41 LINES 3000000 ELAPSED 3373
+lines_per_sec 859.43 LINES 3100000 ELAPSED 3607
+
+After Patch:
+
+lines_per_sec 50000.00 LINES 100000 ELAPSED 2
+lines_per_sec 50000.00 LINES 200000 ELAPSED 4
+lines_per_sec 50000.00 LINES 300000 ELAPSED 6
+lines_per_sec 50000.00 LINES 400000 ELAPSED 8
+lines_per_sec 50000.00 LINES 500000 ELAPSED 10
+lines_per_sec 50000.00 LINES 600000 ELAPSED 12
+lines_per_sec 50000.00 LINES 700000 ELAPSED 14
+lines_per_sec 50000.00 LINES 800000 ELAPSED 16
+lines_per_sec 50000.00 LINES 900000 ELAPSED 18
+lines_per_sec 50000.00 LINES 1000000 ELAPSED 20
+lines_per_sec 50000.00 LINES 1100000 ELAPSED 22
+lines_per_sec 50000.00 LINES 1200000 ELAPSED 24
+lines_per_sec 50000.00 LINES 1300000 ELAPSED 26
+lines_per_sec 50000.00 LINES 1400000 ELAPSED 28
+lines_per_sec 50000.00 LINES 1500000 ELAPSED 30
+lines_per_sec 50000.00 LINES 1600000 ELAPSED 32
+lines_per_sec 50000.00 LINES 1700000 ELAPSED 34
+lines_per_sec 50000.00 LINES 1800000 ELAPSED 36
+lines_per_sec 50000.00 LINES 1900000 ELAPSED 38
+lines_per_sec 50000.00 LINES 2000000 ELAPSED 40
+lines_per_sec 50000.00 LINES 2100000 ELAPSED 42
+lines_per_sec 50000.00 LINES 2200000 ELAPSED 44
+lines_per_sec 50000.00 LINES 2300000 ELAPSED 46
+lines_per_sec 50000.00 LINES 2400000 ELAPSED 48
+lines_per_sec 50000.00 LINES 2500000 ELAPSED 50
+lines_per_sec 50000.00 LINES 2600000 ELAPSED 52
+lines_per_sec 50000.00 LINES 2700000 ELAPSED 54
+lines_per_sec 50000.00 LINES 2800000 ELAPSED 56
+lines_per_sec 50000.00 LINES 2900000 ELAPSED 58
+lines_per_sec 50000.00 LINES 3000000 ELAPSED 60
+lines_per_sec 50000.00 LINES 3100000 ELAPSED 62

BIN
home/public/bash/tests/addresses.txt.gz


+ 65 - 0
home/public/bash/tests/awk-associative-array-test.awk

@@ -0,0 +1,65 @@
+#! /usr/bin/gawk -f
+#! /home/gmj/bin/bash5-patched
+# This is a quick set of tests to see where bash associative arrays
+# start to slow down.   The tests will be done by generating a list of
+# IP addresses as a text file, having bash read them, add them to an
+# associative array, count them and report the time it took to do add
+# every N thousand entries.
+
+# These numbers are run using GNU bash, version 5.0.16(1)-release
+# (x86_64-pc-linux-gnu) on a system running Ubuntu 18.04.4 LTS \
+# Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz with 8gb
+
+
+# set -u; set -e; # this is bash.  be safe.
+
+
+BEGIN {
+    print "BEGIN"
+    print ""
+
+    system("gawk --version | head -1")
+
+    LINES=0 # current line count
+    REPORT_EVERY= 100000#100000 # report time, count every N lines
+    MAX_LINES=10000000 #10000000  # for testing
+    START=systime() # start time
+    print "START", START
+
+    print ""
+
+    print "PROCESSING"
+    print ""
+}
+
+{LINES++}
+{IP_ADDRS[$1]=$1}
+
+{
+    if (LINES % REPORT_EVERY == 0) {
+        #system("sleep 1")
+        NOW=systime()
+        ELAPSED=(NOW - START)
+
+        if (ELAPSED > 0) {
+            LINES_PER_SEC = LINES / ELAPSED
+        } else {
+            LINES_PER_SEC = 0
+        }
+        print "lines_per_sec", LINES_PER_SEC, "LINES", LINES, "ELAPSED", ELAPSED
+    }
+}
+
+{if (LINES > MAX_LINES) exit}
+
+END {
+    print ""
+    print "END"
+    print ""
+
+    NOW=systime()
+    ENDTIME=NOW
+    ELAPSED=(NOW - START)
+    print "ENDTIME", ENDTIME
+    print "lines_per_sec", LINES_PER_SEC, "LINES", LINES, "ELAPSED", ELAPSED
+}

+ 78 - 0
home/public/bash/tests/bash-associative-array-tests.sh

@@ -0,0 +1,78 @@
+#! /bin/bash
+#! /home/gmj/bin/bash5-patched
+# This is a quick set of tests to see where bash associative arrays
+# start to slow down.   The tests will be done by generating a list of
+# IP addresses as a text file, having bash read them, add them to an
+# associative array, count them and report the time it took to do add
+# every N thousand entries.
+
+# These numbers are run using GNU bash, version 5.0.16(1)-release
+# (x86_64-pc-linux-gnu) on a system running Ubuntu 18.04.4 LTS \
+# Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz with 8gb
+
+
+set -u; set -e; # this is bash.  be safe.
+
+echo BASH_VERSION $BASH_VERSION
+
+# Generate input text file
+#
+# Generate a text file containing a full Class A's worth of IP
+# addresses, one per line.   This is done with the CERT [[https://tools.netsa.cert.org/silk/index.html][SiLK]]
+# tool rwsetbuild
+
+ADDRESSES_FILE=addresses.txt
+
+if [ ! -f $ADDRESSES_FILE ]; then
+    echo Createing $ADDRESSES_FILE
+    echo "1.0.0.0/8" > rwset.txt
+    rm -f rwset.set
+    rwsetbuild rwset.txt rwset.set
+    rwsetcat rwset.set > $ADDRESSES_FILE
+fi
+
+# sample contents
+echo
+set -x
+head $ADDRESSES_FILE
+tail $ADDRESSES_FILE
+set +x
+pwd
+
+# Read the file, adding each line to an associative array
+# count and time.
+
+LINES=0 # current line count
+REPORT_EVERY=100000 # report time, count every N lines
+MAX_LINES=10000000  # for testing
+START=`date +%s` # start time
+
+declare -A IP_ADDRS # Array to hold IP addresses
+
+while IFS= read -r ip; do
+    LINES=$((LINES + 1))
+    IP_ADDRS[$ip]=$ip
+
+    if (( LINES % REPORT_EVERY == 0 )); then
+        NOW=`date +%s`
+        ELAPSED=$((NOW - START))
+        if (( ELAPSED > 0 )); then
+            lines_per_sec=`echo "scale=2; $LINES/$ELAPSED" | bc`
+            echo lines_per_sec $lines_per_sec LINES $LINES ELAPSED $ELAPSED
+        fi
+    fi
+
+    if (( LINES > MAX_LINES)); then
+        break
+    fi
+done < $ADDRESSES_FILE
+END=`date +%s` # end time
+
+# dump whats there
+# for K in "${!IP_ADDRS[@]}"; do echo $K --- ${IP_ADDRS[$K]}; done
+
+echo START $START
+echo END $END
+DURATION=$((END-START))
+echo DURATION $DURATION
+echo LINES $LINES

+ 32 - 0
home/public/bash/tests/post-patch-test-timing.txt

@@ -0,0 +1,32 @@
+/home/gmj/home/public/snippits/bash/tests
+lines_per_sec 50000.00 LINES 100000 ELAPSED 2
+lines_per_sec 50000.00 LINES 200000 ELAPSED 4
+lines_per_sec 50000.00 LINES 300000 ELAPSED 6
+lines_per_sec 50000.00 LINES 400000 ELAPSED 8
+lines_per_sec 50000.00 LINES 500000 ELAPSED 10
+lines_per_sec 50000.00 LINES 600000 ELAPSED 12
+lines_per_sec 50000.00 LINES 700000 ELAPSED 14
+lines_per_sec 50000.00 LINES 800000 ELAPSED 16
+lines_per_sec 50000.00 LINES 900000 ELAPSED 18
+lines_per_sec 50000.00 LINES 1000000 ELAPSED 20
+lines_per_sec 50000.00 LINES 1100000 ELAPSED 22
+lines_per_sec 50000.00 LINES 1200000 ELAPSED 24
+lines_per_sec 50000.00 LINES 1300000 ELAPSED 26
+lines_per_sec 50000.00 LINES 1400000 ELAPSED 28
+lines_per_sec 50000.00 LINES 1500000 ELAPSED 30
+lines_per_sec 50000.00 LINES 1600000 ELAPSED 32
+lines_per_sec 50000.00 LINES 1700000 ELAPSED 34
+lines_per_sec 50000.00 LINES 1800000 ELAPSED 36
+lines_per_sec 50000.00 LINES 1900000 ELAPSED 38
+lines_per_sec 50000.00 LINES 2000000 ELAPSED 40
+lines_per_sec 50000.00 LINES 2100000 ELAPSED 42
+lines_per_sec 50000.00 LINES 2200000 ELAPSED 44
+lines_per_sec 50000.00 LINES 2300000 ELAPSED 46
+lines_per_sec 50000.00 LINES 2400000 ELAPSED 48
+lines_per_sec 50000.00 LINES 2500000 ELAPSED 50
+lines_per_sec 50000.00 LINES 2600000 ELAPSED 52
+lines_per_sec 50000.00 LINES 2700000 ELAPSED 54
+lines_per_sec 50000.00 LINES 2800000 ELAPSED 56
+lines_per_sec 50000.00 LINES 2900000 ELAPSED 58
+lines_per_sec 50000.00 LINES 3000000 ELAPSED 60
+lines_per_sec 50000.00 LINES 3100000 ELAPSED 62

+ 31 - 0
home/public/bash/tests/pre-patch-test-timing.txt

@@ -0,0 +1,31 @@
+lines_per_sec 20000.00 LINES 100000 ELAPSED 5
+lines_per_sec 13333.33 LINES 200000 ELAPSED 15
+lines_per_sec 10000.00 LINES 300000 ELAPSED 30
+lines_per_sec 7843.13 LINES 400000 ELAPSED 51
+lines_per_sec 6410.25 LINES 500000 ELAPSED 78
+lines_per_sec 5405.40 LINES 600000 ELAPSED 111
+lines_per_sec 4635.76 LINES 700000 ELAPSED 151
+lines_per_sec 4020.10 LINES 800000 ELAPSED 199
+lines_per_sec 3529.41 LINES 900000 ELAPSED 255
+lines_per_sec 3105.59 LINES 1000000 ELAPSED 322
+lines_per_sec 2777.77 LINES 1100000 ELAPSED 396
+lines_per_sec 2510.46 LINES 1200000 ELAPSED 478
+lines_per_sec 2280.70 LINES 1300000 ELAPSED 570
+lines_per_sec 2086.43 LINES 1400000 ELAPSED 671
+lines_per_sec 1923.07 LINES 1500000 ELAPSED 780
+lines_per_sec 1777.77 LINES 1600000 ELAPSED 900
+lines_per_sec 1655.30 LINES 1700000 ELAPSED 1027
+lines_per_sec 1550.38 LINES 1800000 ELAPSED 1161
+lines_per_sec 1457.05 LINES 1900000 ELAPSED 1304
+lines_per_sec 1375.51 LINES 2000000 ELAPSED 1454
+lines_per_sec 1302.72 LINES 2100000 ELAPSED 1612
+lines_per_sec 1238.04 LINES 2200000 ELAPSED 1777
+lines_per_sec 1179.48 LINES 2300000 ELAPSED 1950
+lines_per_sec 1126.23 LINES 2400000 ELAPSED 2131
+lines_per_sec 1078.51 LINES 2500000 ELAPSED 2318
+lines_per_sec 1034.20 LINES 2600000 ELAPSED 2514
+lines_per_sec 993.37 LINES 2700000 ELAPSED 2718
+lines_per_sec 955.95 LINES 2800000 ELAPSED 2929
+lines_per_sec 921.51 LINES 2900000 ELAPSED 3147
+lines_per_sec 889.41 LINES 3000000 ELAPSED 3373
+lines_per_sec 859.43 LINES 3100000 ELAPSED 3607

+ 14 - 0
home/public/bash/traps.sh

@@ -0,0 +1,14 @@
+#! /bin/bash
+# test traps
+#
+# http://hackaday.com/2017/07/21/linux-fu-better-bash-scripting/?utm_source=cronweekly.com
+
+array tmpfiles = ()
+
+tmpfile="foo$$.tmp"
+trap "echo trap removing tmpfile; rm -f "${tmpfile}";  exit" INT TERM EXIT
+
+echo foo > "${tmpfile}" 
+
+exit 1
+trap - INT TERM EXIT

+ 50 - 0
home/public/bash/trim.sh

@@ -0,0 +1,50 @@
+# http://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable
+
+trim() {
+    # trim leading and trailing spaces
+    local var="$*"
+    var="${var#"${var%%[![:space:]]*}"}"   # remove leading whitespace characters
+    var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
+    echo -n "$var"
+}
+
+squash() {
+    # remove all apaces
+    local var="$*" 
+    echo "${var//[[:blank:]]/}"
+}
+
+lc() {
+    # lowercase
+    local var="$*" 
+    echo "$var" |  tr '[:upper:]' '[:lower:]'
+}
+
+
+stringEqual() {
+    # case-insensitive comparison with spaces removed
+    echo one $1
+    onePrime=$(lc $(squash $1))
+    echo two $2
+    twoPrime=$(lc $(squash $2))
+    echo onePrime $onePrime twoPrime $twoPrime
+    [[ "$onePrime" == "$twoPrime" ]] && return 0 || return 1
+}
+
+
+stringTests() {
+    foo=" foo"
+    bar="foo "
+    foobar=" F o b"
+
+    echo "trim /$foo/ /$(trim $foo)/"
+    echo "trim /$bar/ /$(trim $bar)/"
+    echo "squash /$foobar/ /$(squash $foobar)/"
+    echo "lc /$foobar/ /$(lc $foobar)/"
+    echo "lc squash /$foobar/ /$(lc $(squash $foobar))/"
+
+    if stringEqual "$foo" "$bar";then echo same; else echo different;fi
+}
+
+
+

+ 26 - 0
home/public/bash/xargsWithSpaces

@@ -0,0 +1,26 @@
+#! /bin/bash
+# Tests for xargs with spaces in filenames
+#
+# Usage: ./xargsWithSpaces a b "c d"
+#
+# Using xargs with spaces in filenames ("find -print0 ... | xargs -0 ...")
+#   http://stackoverflow.com/questions/143171/how-can-i-use-xargs-to-copy-files-that-have-spaces-and-quotes-in-their-names
+# 
+# Escaping whitespace in bash loops
+#     http://stackoverflow.com/questions/301039/how-can-i-escape-white-space-in-a-bash-loop-list
+
+set -u   # exit on undefined
+set -e   # exit on error
+
+readonly ARGS="$@"
+
+echo num args $#
+echo args $@
+
+#OIFS="$IFS"
+#IFS=$'\n'
+for arg in "$@"; do
+    printf '%s\n' "$arg"
+done
+#IFS="$OIFS"
+

+ 78 - 0
home/public/bashArrays.org

@@ -0,0 +1,78 @@
+* What
+  Functions to perform array operations in bash
+* Why
+  Because the I find the native syntax obtuse &
+  I like readable, understandable code.
+
+* Who
+  George Jones <gmj@pobox.com> 
+
+* When
+  <2015-07-30 Thu>
+
+* Where  
+
+* How
+
+  - Define obviously named functions to do array operations
+  - See http://rosettacode.org/wiki/Arrays#UNIX_Shell
+  - Maybe see http://mywiki.wooledge.org/BashFAQ/006
+
+  #+begin_src sh  :results output :exports both
+  exec 2>&1;set -e; set -u; set +x; echo '#' `date;`
+
+  #
+  # See if varaible is define and is an array
+  #
+
+  function isArray {
+    name=$1
+  }
+
+  #
+  # Declare array
+  #
+
+  function arrayCreate() {
+      name=$1
+      echo $name
+  }
+
+  #
+  # Append to an array
+  #
+
+  #
+  # Prepend to an array
+  #
+
+  #
+  # Remove element form an array
+  #
+
+  #
+  # Split to create an array
+  #
+
+  #
+  # Join array to create string
+  #
+
+  #
+  # Delete an array
+  #
+
+  #
+  # Test
+  #
+
+  arrayCreate "foo"
+
+  echo Done.
+  #+end_src
+
+  #+RESULTS:
+  : # Thu Jul 30 05:24:52 EDT 2015
+  : foo
+  : Done.
+

+ 1 - 0
home/public/description

@@ -0,0 +1 @@
+code snippits in various langages

+ 75 - 0
home/public/elisp/babel

@@ -0,0 +1,75 @@
+#!/USSR/local/bin/emacs --script
+;; 
+;; execute code in files containing emacs org mode babel source blocks
+;;
+;; Usage:
+;;
+;;     $ babel foo.org
+;;
+;;   or, as an interpreter in a file
+;;
+;;     #! babel
+;;
+
+
+
+(dolist (word  '("~/food"))
+  (if (file-exists-p word)    
+    (progn
+      (org-babel-do-load-languages
+       'org-babel-load-languages '((python . t) (sh . t) (lisp . t) (R . t) (ditaa . t)))
+      (setq org-export-babel-evaluate nil)
+      (setq org-confirm-babel-evaluate nil)
+      (setq org-babel-sh-command "bash")
+      (setq elisp-dir word)
+      (message (format "org-bable-load directory: %s"  elisp-dir))
+      (mapc #'org-babel-load-file (directory-files elisp-dir t "\\.org$"))
+   
+      ; Load up everything in the ~/elisp
+  
+       ; http://stackoverflow.com/questions/18706250/emacs-require-all-files-in-a-directory
+  
+       (let ((loaded  (mapcar #'car load-history)))
+         (dolist (file  (directory-files elisp-dir t ".+\\.elc?$"))
+           (unless (catch 'foo
+                     (dolist (done  loaded)
+                       (when (equal file done) (throw 'foo t)))
+                     nil)
+             (load (file-name-sans-extension file))
+             (push file loaded))))
+           )))
+
+
+
+;;;; https://lists.gnu.org/archive/html/emacs-orgmode/2012-08/msg00511.html
+;;
+;;;; The subdirectory ~/.emacs.d is to be added to the top-level elisp
+;;;; file search.
+;;;(progn (cd "~/.emacs.d") (normal-top-level-add-subdirs-to-load-path))
+;;(let ((default-directory "~/.emacs.d"))
+;;  (normal-top-level-add-subdirs-to-load-path))
+;;
+;;;; Org-Mode, Org-Babel, and the tangle library are required, if we are
+;;;; to proceed further.
+;;(require 'org-install)
+;;(require 'org)
+;;(require 'ob-tangle)
+;;
+;;;; Load the main configuration and setup file.
+;;(require 'ob-ruby)
+;;(require 'ob-python)
+;;(require 'ob-emacs-lisp)
+;;(require 'ob-lisp)
+;;
+;;; allow various types of code blocks to execute
+;;(org-babel-do-load-languages
+;;    'org-babel-load-languages '((python . t) (sh . t) (lisp . t) (R . t) (ditaa . t)))
+;;(setq org-export-babel-evaluate nil)
+;;(setq org-confirm-babel-evaluate nil)
+;;
+;;;; Tangle all files given.
+;;(dolist (file command-line-args-left)
+;; (princ file)
+;; (org-babel-tangle-file file))
+;;
+;; (org-babel-tangle-file "/home/george/.emacs.d/foo.org")

+ 26 - 0
home/public/elisp/batch

@@ -0,0 +1,26 @@
+#!/bin/sh
+# -*- mode: shell-script -*-
+#
+# tangle files with org-mode
+#
+DIR=`pwd`
+FILES=""
+     
+# wrap each argument in the code required to call tangle on it
+for i in $@; do
+    FILES="$FILES \"$i\""
+done
+     
+emacs -Q --batch \
+--eval "(progn
+(message "foo bar")
+(add-to-list 'load-path (expand-file-name \"~/src/org/lisp/\"))
+(add-to-list 'load-path (expand-file-name \"~/src/org/contrib/lisp/\" t))
+(require 'org)(require 'org-exp)(require 'ob)(require 'ob-tangle)
+(mapc (lambda (file)
+       (find-file (expand-file-name file \"$DIR\"))
+       (org-babel-tangle)
+       (kill-buffer)) '($FILES)))" 2>&1 |grep tangled
+
+
+

+ 76 - 0
home/public/elisp/gmj-set-property-dates.el

@@ -0,0 +1,76 @@
+(progn
+  (defun gmj-set-property-defaults ()
+    "Set ':date*: FOO' dates in first org mode properties list to today's date
+
+I have an org mode files that has account information in a tree-structued list.
+The top node has property entries like ':dateCreated: <2016-09-03 Sat>' that
+are inherited by lower nodes.   I want to set all of these to today's date
+when I visit the files.  This is a function that will do that via
+local variable eval.  See http://stackoverflow.com/questions/4356472/emacs-per-file-customization
+
+In future versions, it might make sense to use org mode parsing and navigation functions to get
+to the correct block of code rather than simple text search
+"
+    (interactive)
+    (let (start end)
+
+  ; find "* Accounts".  This is special purpose code.  This org header is whre we start or fail
+
+      (goto-char 1)
+      (setq case-fold-search t)
+      (re-search-forward "^* Accounts")
+      (setq accountsStart (point))
+
+  ; find next org header (if any) to use as the upper bound for seraches
+
+      (save-excursion
+	(if (re-search-forward "^* " (point-max) t 1)
+	    (setq accountsEnd (point))
+	  (setq accountsEnd (point-max))))
+
+      (message "accountsStart %d" accountsStart)      
+      (message "accountsEnd %d" accountsEnd)      
+      
+      (if (re-search-forward "^[[:space:]]+:PROPERTIES:")
+	  (progn
+	    (setq propStart (point))
+	    (message "propStart at %d" propStart)))
+
+      (save-excursion      
+	(if (re-search-forward "^[[:space:]]+:END:")  
+	    (progn
+	      (setq propEnd (point))
+	      (message "propEnd at %d" propEnd))))))
+
+  (gmj-set-property-defaults))
+
+- set region to first :PROPERTIES: ... :END: in buffer
+- narrow to region
+- replace ":date*: *" with :date*: TODAY"
+
+▮ )
+
+
+
+foo
+
+
+* AccountS
+  :PROPERTIES:
+  :system:   foo
+  :type_ALL: social email cloud
+  :username: foo
+  :authType_ALL: password google
+  :password: foo
+  :email_ALL:    eludom@gmail.com gmj@pobox.com
+  :securityQuestions:
+  :url:      foo
+  :dateCreated: <2016-09-03 Sat>
+  :dateAccessed: <2016-09-03 Sat>
+  :dateUpdated:
+  :dateExpires:
+  :accountInfo:
+  :comments:
+  :END:
+
+bar

+ 10 - 0
home/public/elisp/hello.el

@@ -0,0 +1,10 @@
+:;exec emacs -batch -l "$0" -f main "$@"
+; http://kitchingroup.cheme.cmu.edu/blog/2014/08/06/Writing-scripts-in-Emacs-lisp/
+
+(defun main ()
+  (print (version))
+  (print (format "I did it. you passed in %s" command-line-args-left)))
+
+;; Local Variables:
+;; mode: emacs-lisp
+;; End:

+ 32 - 0
home/public/elisp/org-agenda-clockreport-parameter-plist-testing.org

@@ -0,0 +1,32 @@
+;; This buffer is for notes you don't want to save, and for Lisp evaluation.
+;; If you want to create a file, visit that file with C-x C-f,
+;; then enter the text in that file's own buffer.
+
+
+(:link t :maxlevel 2)
+
+* From stackexchange
+See http://emacs.stackexchange.com/questions/13793/how-to-add-a-column-in-org-mode-agenda-clockreport-to-show-percentage-of-time-fo
+
+#+begin_src emacs-lisp
+(setq org-agenda-clockreport-parameter-plist
+      (quote (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80 :formula %)))
+#+end_src
+
+* Original value
+#+begin_src emacs-lisp
+(setq org-agenda-clockreport-parameter-plist
+      (quote (:link t :maxlevel 2 )))
+#+end_src
+
+* Testing with different values
+
+#+begin_src emacs-lisp
+(setq org-time-clocksum-format "%d:%02d")
+(setq org-agenda-clockreport-parameter-plist
+      (quote (:link t :maxlevel 2 :fileskip0 t :stepskip0 t :narrow 35 :formula %)))
+#+end_src
+
+#+RESULTS:
+| :link | t | :maxlevel | 2 | :fileskip0 | t | :stepskip0 | t | :narrow | 35 | :formula | % |
+

+ 12 - 0
home/public/elisp/replaceDefaultPropertyTimestampsOnOpen.org

@@ -0,0 +1,12 @@
+;;; Local Variables:
+;;; eval: (progn (message "foo") (message "bar"))
+;;; End:
+
+Replace default timestamp properties on file open
+
+* account
+  :PROPERTIES:
+  :dateUpdated: foo
+  :dateCreated: foo
+  :dateExpires:
+  :END:

+ 44 - 0
home/public/elisp/replaceTimestamps.el

@@ -0,0 +1,44 @@
+(message "%s▮foo" "bar")
+
+(repl
+
+(defun replace-greek-region (start end)
+  "Replace “alpha” to “α” and other greek letters in current region."
+  (interactive "r")
+  (save-restriction
+    (narrow-to-region start end)
+    (goto-char (point-min))
+    (while (search-forward " alpha" nil t) (replace-match " α" nil t))
+    (goto-char (point-min))
+    (while (search-forward " beta" nil t) (replace-match " β" nil t))
+    (goto-char (point-min))
+    (while (search-forward " gamma" nil t) (replace-match " γ" nil t))
+    ))
+
+(
+
+(re-search-forward "REGEXP▮" &optional BOUND 'NOERROR COUNT)
+
+
+(insert "fooo")fooo
+
+(progn
+  (defun foo ()
+    "about the foo"
+    (interactive)
+    (let (where)
+      (goto-char (point-min))
+      (while (re-search-forward ":date[a-zA-Z]+:" nil t) (insert "FOO"))
+      (message "Done")
+    )
+  )
+(foo))
+
+
+
+* account
+  :PROPERTIES:
+  :dateUpdated: foo
+  :dateCreated: foo
+  :dateExpires:
+  :END:

+ 35 - 0
home/public/elisp/run-org.el

@@ -0,0 +1,35 @@
+:;exec emacs -batch -l "$0" -f main "$@"
+; http://kitchingroup.cheme.cmu.edu/blog/2014/08/06/Writing-scripts-in-Emacs-lisp/
+
+(defun main ()
+  ;; run-org.el blockname org-file
+  ;; run a code block in an org file
+  (let ((blockname (pop command-line-args-left))
+        (org-file (pop command-line-args-left))
+        (src))
+    (print (version))    
+    (find-file org-file)
+    (setq src
+          (org-element-map (org-element-parse-buffer) 'src-block
+            (lambda (element)
+              (when (string= blockname (org-element-property :name element))
+                element))
+            nil ;info
+            t )) ; first-match
+    (when src
+      (goto-char (org-element-property :begin src))
+      ;; since we start with a fresh emacs, we have to configure some things.
+      (org-babel-do-load-languages
+       'org-babel-load-languages
+       '((python . t)))
+      (let ((org-confirm-babel-evaluate nil))
+        (org-babel-execute-src-block)))
+    (print (format "Done." ))))
+
+
+
+;; Local Variables:
+;; mode: emacs-lisp
+;; End:
+
+

+ 125 - 0
home/public/elisp/scriptingUsingOrgMode.org

@@ -0,0 +1,125 @@
+#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:nil arch:headline
+#+OPTIONS: author:t broken-links:nil c:nil creator:nil
+#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:2
+#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
+#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
+#+TITLE: scriptingUsingOrgMode
+#+DATE: <2016-07-30 21:25:28 Saturday>
+#+AUTHOR: George M Jones
+#+EMAIL: gmj@pobox.com
+#+LANGUAGE: en
+#+SELECT_TAGS: export
+#+EXCLUDE_TAGS: noexport
+#+CREATOR: Emacs 25.1.50.1 (Org mode 8.3.4)
+
+* Intro
+  - What :: Running org babel code blocks as command line shell scripts. 
+  - Why  :: 1) Because you can. 2) Because, really, its pretty cool to
+       have all your code, data and documentation in one file. 3) No
+       More Bash. 4) Because GNU Emacs is at its core an
+       implementation of Lisp that happens to have played host to an
+       Editor for over 30 years. 5) I had org babel code blocks lying
+       around that do useful thing (suck my gmail down fom Google via
+       offlineimap, apply custom tags and create a full text index)
+       and I wanted to be able to run those from the command line/cron
+       and NOT turn them into bash.`
+  - Who :: George Jones <gmj@pobox.com> based on John Kitchin' blog post
+  - When :: <2016-07-30 Sat>
+  - Where :: In a lisp interpreter near you.
+
+* hello.el
+
+  Put this in a file called =hello.el=
+  #+begin_example
+:;exec emacs -batch -l "$0" -f main "$@"
+; http://kitchingroup.cheme.cmu.edu/blog/2014/08/06/Writing-scripts-in-Emacs-lisp/
+
+(defun main ()
+  (print (version))
+  (print (format "I did it. you passed in %s" command-line-args-left)))
+
+;; Local Variables:
+;; mode: emacs-lisp
+;; End:
+  #+end_example
+
+  And run it thusly
+
+  #+begin_example
+george@octo elisp [master] $ chmod +x hello.el 
+george@octo elisp [master] $ ./hello.el world
+
+"GNU Emacs 25.1.50.1 (x86_64-unknown-linux-gnu, GTK+ Version 2.24.23)
+ of 2016-06-23"
+
+"I did it. you passed in (world)"
+  #+end_example
+* somePython.org
+  Create an =.org= file with a babel code block thusly:
+
+  #+begin_example
+#+name: pythonDate
+#+begin_src python :results output :exports both
+  import time
+  with open('results.dat', 'w') as f:
+      f.write(time.asctime())
+  print "Done."	
+#+end_src
+  #+end_example
+* run-org.el
+   Create the following glue code to find and execute a hunk of python
+   code in an org mode babel code block:
+
+   #+begin_example
+:;exec emacs -batch -l "$0" -f main "$@"
+; http://kitchingroup.cheme.cmu.edu/blog/2014/08/06/Writing-scripts-in-Emacs-lisp/
+
+(defun main ()
+  ;; run-org.el blockname org-file
+  ;; run a code block in an org file
+  (let ((blockname (pop command-line-args-left))
+        (org-file (pop command-line-args-left))
+        (src))
+    (print (version))    
+    (find-file org-file)
+    (setq src
+          (org-element-map (org-element-parse-buffer) 'src-block
+            (lambda (element)
+              (when (string= blockname (org-element-property :name element))
+                element))
+            nil ;info
+            t )) ; first-match
+    (when src
+      (goto-char (org-element-property :begin src))
+      ;; since we start with a fresh emacs, we have to configure some things.
+      (org-babel-do-load-languages
+       'org-babel-load-languages
+       '((python . t)))
+      (let ((org-confirm-babel-evaluate nil))
+        (org-babel-execute-src-block)))
+    (print (format "Done." ))))
+
+
+
+;; Local Variables:
+;; mode: emacs-lisp
+;; End:
+   #+end_example
+
+   Run it thusly:
+
+   #+begin_example
+george@octo elisp [master] $  ./run-org.el pythonDate somePython.org 
+
+
+"GNU Emacs 25.1.50.1 (x86_64-unknown-linux-gnu, GTK+ Version 2.24.23)
+ of 2016-06-23"
+
+executing Python code block (pythonDate)...
+Code block evaluation complete.
+
+"Done."
+george@octo elisp [master] $ george@octo elisp [master] $ cat results.dat 
+Sat Jul 30 21:08:49 2016
+george@octo elisp [master] $    
+   #+end_example

+ 9 - 0
home/public/elisp/somePython.org

@@ -0,0 +1,9 @@
+#+name: pythonDate
+#+begin_src python :results output :exports both
+  import time
+  with open('results.dat', 'w') as f:
+      f.write(time.asctime())
+      f.write("\n")
+  print "Done."	
+#+end_src
+

+ 32 - 0
home/public/elisp/start-shell-with-name-of-host-as-buffer-name.el

@@ -0,0 +1,32 @@
+
+
+(defun gmjShell ()
+  "Start a shell in a buffer named *shell*<hostname>
+
+Start a shell in a buffer named '*shell*<hostname>'
+For now, it assumes the syntax of the filename contains something like
+
+  /ssh:george@domus:...
+
+(e.g. that we're editing a file in tramp).  This should be more general
+(e.g. get the hostname if it's just local).  It should also handle 
+(prompt?) for creating 2nd (3rd...) shells on a host and name the
+buffers something like 
+
+  *shell*<hostname_2>
+
+There is currently no error handling.....
+
+George Jones <gmj@pobox.com> 
+"
+  (interactive)
+(progn
+  (setq file-name (buffer-file-name))
+  (message file-name)
+  (setq hostname (replace-regexp-in-string "/ssh:.*@" "" file-name))
+  (setq hostname2 (replace-regexp-in-string ":.*" "" hostname))  
+  (message (concat "Hostname: " hostname2))
+  (shell (concat "*shell*<" hostname2 ">"))
+))
+
+(global-set-key (kbd "<f5>") 'gmjShell)

+ 8 - 0
home/public/elisp/untabify.el

@@ -0,0 +1,8 @@
+; http://stackoverflow.com/questions/3313210/converting-this-untabify-on-save-hook-for-emacs-to-work-with-espresso-mode-or-a
+
+;; untabify some modes
+(setq alexott/untabify-modes '(python-mode emacs-lisp-mode lisp-mode))
+(defun alexott/untabify-hook ()
+  (when (member major-mode alexott/untabify-modes)
+     (untabify (point-min) (point-max))))
+(add-hook 'before-save-hook 'alexott/untabify-hook)

+ 22 - 0
home/public/elisp/urlExists.org

@@ -0,0 +1,22 @@
+* Testing if a URL exists from elisp
+
+#+begin_src emacs-lisp
+(if (url-http-file-exists-p "http://port111.com/index.html")
+    (message "exists")
+  (message "does not exist"))
+#+end_src
+
+#+RESULTS:
+: exists
+
+
+#+begin_src emacs-lisp                                                                                                                                                                                            
+(if (url-http-file-exists-p "http://port111.com/bogus.html")                                                                                                                                                      
+    (message "exists")                                                                                                                                                                                            
+  (message "does not exist"))                                                                                                                                                                                       
+#+end_src                                                                                                                                                                                                  
+
+#+RESULTS:
+: does not exist
+
+

+ 0 - 0
home/public/git/bar.txt


+ 5 - 0
home/public/git/dir-locals.el

@@ -0,0 +1,5 @@
+((nil . ((indent-tabs-mode . t)
+         (fill-column . 42)
+         (gac-ask-for-summary-p t)
+	 (eval git-auto-commit-mode t))))
+

+ 42 - 0
home/public/git/git-autocommit-mode.txt

@@ -0,0 +1,42 @@
+In Emacs, every file save can now be a git commit+push. Backups are
+now irrelevant (at least for emacs git users).  And you thought VMS
+file version numbers were pretty neat...
+
+https://github.com/ryuslash/git-auto-commit-mode
+
+* Setup
+
+  Install the package (=M-x package-install git-auto-commit-mode=) etc.
+
+  Add to your favorite =init.el= or friend:
+
+  #+begin_example
+  (add-hook 'certain-hook 'git-auto-commit-mode)
+  #+end_example
+
+* Global Configuation
+
+  Decide how daring and/or annoyed you want to be.  To go all-in and
+  always ask for summary and push do the following:
+  
+
+  #+begin_example
+  (setq gac-automatically-push-p t)
+  ;(setq gac-ask-for-summary-p t)  
+  #+end_example
+
+* Per Directory configuration
+
+  To do things on a directory level, put something like this
+
+  #+begin_example
+  ((nil . ((eval git-auto-commit-mode 1))))  
+  #+end_example
+
+  in a file called =.dir-locals.el= in a directory you want to hae
+  pushed.  See http://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html
+
+  You can also specify per file variables
+  http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html#Specifying-File-Variables
+  if you choose.
+

+ 7 - 0
home/public/git/qux.c

@@ -0,0 +1,7 @@
+foo
+bar
+baz
+qux
+
+
+

+ 1 - 0
home/public/git/setup.el

@@ -0,0 +1 @@
+(add-hook 'text-mode-hook 'foo-mode)

+ 2 - 0
home/public/googleMaps/pull.sh

@@ -0,0 +1,2 @@
+curl 'https://www.google.com/maps/dir/AOL+Way,+Sterling,+VA+20166,+USA/7057+Wintergreen+Ct,+Warrenton,+VA+20187,+USA/@38.8769401,-77.7132155,11z/data=!3m1!4b1!4m13!4m12!1m5!1m1!1s0x89b638e7bb7616d9:0xcf3dabe012def0d7!2m2!1d-77.4453065!2d39.0047199!1m5!1m1!1s0x89b6638181ccf59d:0xb3033d68aad34849!2m2!1d-77.696618!2d38.747159'
+wget 'https://www.google.com/maps/dir/AOL+Way,+Sterling,+VA+20166,+USA/7057+Wintergreen+Ct,+Warrenton,+VA+20187,+USA/@38.8769401,-77.7132155,11z/data=!3m1!4b1!4m13!4m12!1m5!1m1!1s0x89b638e7bb7616d9:0xcf3dabe012def0d7!2m2!1d-77.4453065!2d39.0047199!1m5!1m1!1s0x89b6638181ccf59d:0xb3033d68aad34849!2m2!1d-77.696618!2d38.747159?dg=dbrw&amp;newdg=1'

+ 60 - 0
home/public/markdown/markdown-tests.md

@@ -0,0 +1,60 @@
+# Table of Contents
+
+1.  [Target1](#orgae944cd)
+2.  [Target 2](#orgd23c8cd)
+3.  [Target 3](#org37c8242)
+
+This is a place to test markdown features.
+The features are tested by creating the desired
+markup in org-mode and exporting to .md
+
+Here is some text
+
+
+<a id="orgae944cd"></a>
+
+# Target1
+
+Text under Target1
+
+"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+
+<a id="orgd23c8cd"></a>
+
+# Target 2
+
+Text under Target 2
+
+  "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+
+<a id="org37c8242"></a>
+
+# Target 3
+
+Foo Ipsum

+ 59 - 0
home/public/markdown/markdown-tests.org

@@ -0,0 +1,59 @@
+#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:nil arch:headline
+#+OPTIONS: author:t broken-links:nil c:nil creator:nil
+#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:2
+#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
+#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
+#+TITLE: markdown-tests
+#+DATE: <2019-05-29 09:58:51 Wednesday>
+#+AUTHOR: George Jones
+#+EMAIL: eludom@gmail.com
+#+LANGUAGE: en
+#+SELECT_TAGS: export
+#+EXCLUDE_TAGS: noexport
+#+CREATOR: Emacs 27.0.50 (Org mode 9.1.14)
+
+This is a place to test markdown features.
+The features are tested by creating the desired
+markup in org-mode and exporting to .md
+
+
+Here is some text
+
+* Target1
+  Text under Target1
+
+  "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+  molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+  fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+  minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+  officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+  tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+  "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+  molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+  fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+  minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+  officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+  tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+
+* Target 2
+  Text under Target 2
+
+    "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+  molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+  fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+  minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+  officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+  tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+  "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas
+  molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum
+  fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo
+  minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut
+  officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic
+  tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
+
+* Target 3
+
+  Foo Ipsum

+ 59 - 0
home/public/matplotlib/plot.org

@@ -0,0 +1,59 @@
+Experiments with matplotlib
+
+#+BEGIN_SRC ipython :session tests :exports both :file plot.png
+  %matplotlib inline
+  import matplotlib.pyplot as plt
+  import numpy as np
+  import pandas as pd
+
+
+  # Plot some points
+
+  x1 = np.array([20, 21, 22, 23, 24, 25, 26])
+  y1 = np.array([6, 7, 8, 9, 10, 11, 12])
+
+  plt.plot(x1,y1,"-o",label='right of center')
+
+  # Plot some random points
+
+  x2 = np.array([6,7,8,9,10,11,12])
+  y2 = np.array([13, 14, 15, 16, 17, 18, 19])
+  y2random=np.random.uniform(13, 19,7)
+  plt.plot(x2,y2random,"-o",label='random, left')
+
+  # Smoth out the line for the random points
+
+  T=x2
+  power=y2random
+
+  xnew = np.linspace(T.min(),T.max(),14) #300 represents number of points to make between T.min and T.max
+
+  power_smooth = spline(T,power,xnew)
+
+  plt.plot(xnew,power_smooth,"-",label='random, left, smooth')
+
+
+  plt.legend()
+  # ax = plt.gca()
+
+  # ax.set_xlabel('Date')
+  # ax.set_ylabel('Units')
+  # ax.set_title('Exponential vs. Linear performance')
+
+  plt.xlabel('The number of times the child kicked a ball')
+  # add a label to the y axis
+  plt.ylabel('The grade of the student')
+  # add a title
+  plt.title('Relationship between ball kicking and grades')
+
+
+
+#+END_SRC
+
+#+RESULTS:
+[[file:plot.png]]
+
+
+
+*
+*

BIN
home/public/matplotlib/plot.png


+ 33 - 0
home/public/matplotlib/spline.org

@@ -0,0 +1,33 @@
+https://stackoverflow.com/questions/5283649/plot-smooth-line-with-pyplot
+
+#+BEGIN_SRC ipython :session tests :file spline.png :exports both
+  %matplotlib inline
+  import matplotlib.pyplot as plt
+  import numpy as np
+  import pandas as pd
+  T = np.array([6, 7, 8, 9, 10, 11, 12])
+  power = np.array([1.53E+03, 5.92E+02, 2.04E+02, 7.24E+01, 2.72E+01, 1.10E+01, 4.70E+00])
+
+  plt.plot(T,power)
+  plt.show()
+#+END_SRC
+
+#+RESULTS:
+[[file:spline.png]]
+
+#+BEGIN_SRC ipython :session tests :file spline2.png  :exports both
+from scipy.interpolate import spline
+
+xnew = np.linspace(T.min(),T.max(),300) #300 represents number of points to make between T.min and T.max
+
+power_smooth = spline(T,power,xnew)
+
+plt.plot(xnew,power_smooth)
+plt.show()
+
+
+
+#+end_src
+
+#+RESULTS:
+[[file:spline2.png]]

BIN
home/public/matplotlib/spline.png


BIN
home/public/matplotlib/spline2.png


+ 54 - 0
home/public/org/.bashrc.org

@@ -0,0 +1,54 @@
+* Bashrc export
+  Experiments with after-save-hook to allow me to use org mode with my .bashrc
+
+#+begin_src emacs-lisp
+(defvar backup-repo (directory-file-name "/private/tmp")
+"NOTE:  `directory-file-name` makes it so that the user may either omit, or
+include the forward trailing slash at the end of the `backkup-repo` path.")
+
+(defun after-save-hook-fn ()
+  (let
+      (bashrc-filename
+       shell-command
+       shell output)
+    (if (string-match-p ".*.bashrc.org" buffer-file-name)
+        (progn
+          (message "MATCH")
+          (setq bashrc-filename
+                (replace-regexp-in-string ".org$" "" buffer-file-name))
+
+          ;; Really, I did play with org mode hooks first to try to get this work
+
+          (setq shell-command
+                (concat
+                 "cat "
+                 buffer-file-name
+                 "| sed 's/^/# /'"
+                 ;; "| sed 's/^/# /' | sed 's/#   .//' | sed 's/^---.*//'"
+                 "> "
+                 bashrc-filename
+                 ))
+
+          ;;(message (concat "COMMAND " shell-command)
+          (setq
+           shell-output
+           (shell-command-to-string shell-command))
+          (message (concat "shell-output" shell-output)
+          ))
+
+       (message "NO MATCH"))))
+
+  ;; (let* (
+  ;;     (backup-repo-filename
+  ;;       (when buffer-file-name (concat backup-repo buffer-file-name)))
+  ;;     (dir (when backup-repo-filename (file-name-directory backup-repo-filename))) )
+  ;;   (when buffer-file-name
+  ;;     (when (not (file-exists-p dir))
+  ;;        (make-directory dir t))
+  ;;     (write-region (point-min) (point-max) backup-repo-filename))))
+
+(add-hook 'after-save-hook 'after-save-hook-fn)
+#+end_src
+
+#+RESULTS:
+| after-save-hook-fn | rmail-after-save-hook |

+ 109 - 0
home/public/org/babel-ipython.org

@@ -0,0 +1,109 @@
+ * ipython org mod examples
+
+  See https://github.com/gregsexton/ob-ipython
+
+#+BEGIN_SRC ipython :session
+  %matplotlib inline
+  import matplotlib.pyplot as plt
+  import numpy as np
+#+END_SRC
+
+
+
+Here we evaluate some code with a function definition using a named session.
+
+#+BEGIN_SRC ipython :session mysession :exports both
+  def foo(x):
+      return x + 9
+
+  [foo(x) + 7 for x in range(7)]
+#+END_SRC
+
+#+RESULTS:
+| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
+
+
+
+#+BEGIN_SRC ipython :session :file /tmp/image.png :exports both
+  plt.hist(np.random.randn(20000), bins=200)
+#+END_SRC
+
+#+RESULTS:
+[[file:/tmp/image.png]]
+
+[[file:/tmp/image.png]]
+
+
+
+
+#+BEGIN_SRC ipython :session :file /tmp/image2.svg :exports both
+  %config InlineBackend.figure_format = 'svg'
+  plt.hist(np.random.randn(2000), bins=20)
+#+END_SRC
+
+#+RESULTS:
+[[file:/tmp/image2.svg]]
+
+
+
+#+BEGIN_SRC ipython :session :kernel clojure
+  (+ 1 2)
+#+END_SRC
+
+ob-ipython supports providing variables and even tables to code.
+
+#+TBLNAME: data_table
+| a | 1 | 2 |
+| b | 2 | 3 |
+| c | 3 | 4 |
+
+#+BEGIN_SRC ipython :session :exports both :var x=2 :var data=data_table
+  (x, data)
+#+END_SRC
+
+#+RESULTS:
+| 2 | ((a 1 2) (b 2 3) (c 3 4)) |
+
+
+
+
+#+BEGIN_SRC ipython :session :file /tmp/image3.svg :exports both :async t
+  %config InlineBackend.figure_format = 'svg'
+  import time
+  time.sleep(3)
+
+  plt.hist(np.random.randn(200), bins=10)
+#+End_SRC
+
+#+RESULTS:
+[[file:/tmp/image3.svg]]
+
+
+
+
+
+#+BEGIN_SRC ipython :session mysession :exports both
+    import sys
+
+    def foo(x):
+	    return x + 9
+
+    sys.stderr.write("This is on stderr\n")
+    sys.stdout.write("This is on stdout\n")
+    [foo(x) + 7 for x in range(7)]
+#+END_SRC
+
+#+RESULTS:
+| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
+
+
+#+BEGIN_SRC ipython :session mysession :exports both
+  import sys
+
+
+  sys.stderr.write("This is on stderr\n")
+  sys.stdout.write("This is on stdout\n")
+
+  42/0  # this should throw  an error
+  return 42
+#+END_SRC

+ 27 - 0
home/public/org/babel-python-versions.org

@@ -0,0 +1,27 @@
+#+begin_src emacs-lisp :results none
+(setq org-babel-python-command "python3")
+#+end_src
+
+#+begin_src python :results output
+import sys
+print(sys.version)
+#+end_src
+
+#+RESULTS:
+: 3.6.1 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:09:58)
+: [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
+
+
+
+#+begin_src emacs-lisp :results none
+(setq org-babel-python-command "python2")
+#+end_src
+
+#+begin_src python :results output
+import sys
+print(sys.version)
+#+end_src
+
+#+RESULTS:
+: 2.7.13 (default, Jan 19 2017, 14:48:08)
+: [GCC 6.3.0 20170118]

+ 15 - 0
home/public/org/bable-cache-test.org

@@ -0,0 +1,15 @@
+      #+NAME: random
+      #+BEGIN_SRC R :cache yes
+      runif(1)
+      #+END_SRC
+
+      #+RESULTS[29ec46ce8d80a7cba243286304453ea40f4dbbca]: random
+      : 0.364576283143833
+
+      #+NAME: caller
+      #+BEGIN_SRC emacs-lisp :var x=random :cache yes
+      x
+      #+END_SRC
+
+      #+RESULTS[2908ff86d53b1b95dcb8b4ad1c5439c72c083af5]: caller
+      : 0.364576283143833

+ 58 - 0
home/public/org/bashrc.org

@@ -0,0 +1,58 @@
+#+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp)
+#+BIND: org-export-filter-strike-through-functions (tmp-f-strike-through)
+#+BIND: org-export-filter-final-output-functions (my-bash-filter-comment-line)
+#+BEGIN_SRC emacs-lisp :exports results :results none
+(defun tmp-f-timestamp (s backend info)
+  (replace-regexp-in-string "&[lg]t;\\|[][]" "" s))
+(defun tmp-f-strike-through (s backend info) "")
+(defun my-bash-filter-comment-line (text backend info)
+  "Make each line of text a bash comment"
+  (progn
+    (replace-regexp-in-string "^" "FOO " text))
+    (message "FUBAR")
+    )
+#+END_SRC
+
+
+* Intro                                                            :noexport:
+This is a test to see if I can use org mode to format my .bashrc and
+export the actual .bashrc file.
+
+Because, editing things that are not org files is just wrong.
+
+* So, here's how I started  - export and sed
+
+  - I exported this file to text and ran
+
+    #+begin_example
+    cat bashrc.txt  | sed 's/^/# /' | sed 's/#   .//' | sed 's/^---.*//'
+    #+end_example
+
+    on the result, which left the bash code as bash and everything
+    else as bash comments
+
+* Doing it the org-export way - per file export hooks
+
+  But it looks like there is a better way.  Per-file org export hooks:
+
+  https://orgmode.org/manual/Advanced-Export-Configuration.html#Advanced-Export-Configuration
+
+
+
+* The helper functions
+
+  #+begin_src bash :exports code
+
+# Helper functions
+#PROG=`basename "$0" | tr -d '\n'`
+PROG="bashrc"
+
+function info()  { echo ${PROG}\: info: "$@" 1>&2; }
+function warn()  { echo ${PROG}\: warning: "$@" 1>&2; }
+function error() { echo ${PROG}\: error: "$@" 1>&2; }
+function debug() { [[ -v DEBUG ]] && echo ${PROG}\: debug: "$@" 1>&2 || true ; }
+function die()   { echo ${PROG}\: fatal: "$@" 1>&2 && exit 1; }
+
+#+end_src
+
+#+RESULTS:

+ 45 - 0
home/public/org/export-bashrc.org

@@ -0,0 +1,45 @@
+* TODO Define functions to export bash scripts
+
+  Here is
+
+  Some text
+
+  #+begin_src emacs-lisp
+;;  Make sure we're starting with an ampty list
+(setq org-export-filter-final-output-functions ())
+
+
+;; Add filter to Add bash comment to the start of every line
+;;
+(defun my-final-output-filter (text backend info)
+  "Addd bash comment to start of every line"
+  (replace-regexp-in-string "^" "## " text))
+
+; add it to the export filters
+(add-to-list 'org-export-filter-final-output-functions
+                  'my-final-output-filter)
+
+
+Add filter to uncomment actual bash code in export
+
+(defun my-final-output-filter2 (text backend info)
+  "Uncomment actual bash code"
+  (if (string-match-p "|   " text)
+      (replace-regexp-in-string "[ ]+|" "" text)
+    (replace-regexp-in-string "^" "X" text)))
+
+
+;; ; add it to the export fileters
+;; (add-to-list 'org-export-filter-final-output-functions
+;;                   'my-final-output-filter2)
+  #+end_src
+
+  #+RESULTS:
+  | my-final-output-filter |
+
+
+
+  * foo
+    bar
+
+  more text

+ 18 - 0
home/public/org/exportTest.org

@@ -0,0 +1,18 @@
+Testing export of results and not code:
+
+From: https://emacs.stackexchange.com/questions/7442/export-results-of-codeblock-then-later-export-the-source-block-e-g-as-for-a-c
+
+
+* Results  
+   #+NAME: tab:mytable  
+   #+RESULTS: src:foo  
+   | Mon | Jun | 5 | 13:24:07 | EDT | 2017 |
+   | foo |     |   |          |     |      |
+     
+     
+* Code  
+   #+NAME: src:foo  
+   #+BEGIN_SRC shell :exports results
+   date
+   echo foo
+   #+END_SRC  

+ 14 - 0
home/public/org/exportTestPython.org

@@ -0,0 +1,14 @@
+Testing export of results and not code from python:
+
+# From: https://emacs.stackexchange.com/questions/7442/export-results-of-codeblock-then-later-export-the-source-block-e-g-as-for-a-c
+
+
+* Code  
+   #+NAME: src:foo
+   #+BEGIN_SRC python :exports none :results output
+   print "bar"
+   #+END_SRC  
+
+   #+RESULTS: src:foo
+   : bar
+

+ 152 - 0
home/public/org/exports-test.org

@@ -0,0 +1,152 @@
+#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
+#+OPTIONS: author:t broken-links:nil c:nil creator:nil
+#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
+#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
+#+OPTIONS: timestamp:t title:t toc:nil todo:t |:t
+#+TITLE: exports-test
+#+DATE: <2017-08-21 10:00:04 Monday>
+#+AUTHOR: George Jones
+#+EMAIL: gmj@duox
+#+LANGUAGE: en
+#+SELECT_TAGS: export
+#+EXCLUDE_TAGS: noexport
+#+CREATOR: Emacs 25.1.1 (Org mode 9.0.9)
+
+* org-mode post of 2017-08-15
+** interaction of =org-export-babel-evaluate= and =results output= counter-intuitive
+   I want to define code blocks that export only results, and are not
+   automatically executed on export. To get this behavior, I have to
+
+   - =setq org-export-babel-evaluate t)=
+
+   and use both
+
+   #+begin_example
+  :eval never-export
+  :results output
+   #+end_example
+
+   Which seems a little counter-intuitive.   The problem is that
+   headers (includiing  =:results output=) are ignored when
+   =org-export-babel-evaluate= is set.
+
+   Perhaps this headers (at least) should be honored when
+   =org-export-babel-evaluate= is set?
+
+   Is there a way to make =eval never-export= the default?
+
+* show environment
+** org-version
+  #+BEGIN_SRC elisp :exports results
+  (format "This should only export the results\nemacs %s\norg %s" emacs-version org-version)
+  #+END_SRC
+
+  #+RESULTS:
+  : This should only export the results
+  : emacs 25.1.1
+  : org 9.0.9
+
+** emacs-version
+  #+begin_src elisp
+  (emacs-version)
+  #+end_src
+
+  #+RESULTS:
+  : GNU Emacs 25.1.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
+  :  of 2017-03-29, modified by Debian
+
+* Testing
+** eval never-export, exports results, setq org-export-babel-evaluate t
+
+   Setting
+
+   #+begin_example
+  setq org-export-babel-evaluate t)
+  :eval never-export
+  :results output
+   #+end_example
+
+   results in no code execution (expected, desired), and output of only
+   results (desired, expected)
+
+   #+begin_src shell  :results output :exports results :eval never-export
+    exec 2>&1;date;set -e; set -u; # set -x
+    # THIS IS CODE, I ONLY WANT TO SEE RESULTS
+    echo hello world
+   #+end_src
+
+   #+RESULTS:
+   : Tue Aug 15 08:08:11 EDT 2017
+
+   : hello world
+
+** Tests
+** Set /org-export-babel-evaluate nil/                             :noexport:
+   #+BEGIN_SRC emacs-lisp :exports code
+  (setq org-export-babel-evaluate nil)
+   #+end_src
+
+   #+RESULTS:
+
+** exports results, setq org-export-babel-evaluate nil
+
+   Setting
+
+   #+begin_example
+  setq org-export-babel-evaluate nil)
+  results output
+   #+end_example
+
+   results in no code execution (good, expected), but the /:results
+   output/ header is apperently ignored and aboth code (bad, not
+   expected) and results are output.
+
+   #+begin_src shell  :results output :exports results
+    exec 2>&1;date;set -e; set -u; # set -x
+    # THIS IS CODE, I ONLY WANT TO SEE RESULTS
+    echo hello world
+   #+end_src
+
+   #+RESULTS:
+   : Tue Aug 15 07:51:54 EDT 2017
+   : hello world
+
+** Set /org-export-babel-evaluate nil/                             :noexport:
+   #+BEGIN_SRC emacs-lisp :exports code
+  (setq org-export-babel-evaluate t)
+   #+end_src
+
+   #+RESULTS:
+   : t
+
+
+
+** exports results, setq org-export-babel-evaluate t
+
+   Setting
+
+   #+begin_example
+  setq org-export-babel-evaluate t)
+  results output
+   #+end_example
+
+   results in no code execution (expected, not what I want), but the /:results
+   output/ header is respected.
+
+   #+begin_src shell  :results output :exports results
+    exec 2>&1;date;set -e; set -u; # set -x
+    # THIS IS CODE, I ONLY WANT TO SEE RESULTS
+    echo hello world
+   #+end_src
+
+   #+RESULTS:
+   : Tue Aug 15 07:55:47 EDT 2017
+   : hello world
+
+* See
+  - Discussion of the same problem from https://www.miskatonic.org/2016/10/03/orgexportbabelevaluate/
+    Answer was
+
+    #+begin_src
+    #+PROPERTY: header-args :eval never-export
+    #+end_src

+ 21 - 0
home/public/org/hist.py

@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+import numpy as np
+import matplotlib.mlab as mlab
+import matplotlib.pyplot as plt
+
+mu, sigma = 100, 15
+x = mu + sigma*np.random.randn(10000)
+
+# the histogram of the data
+n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75)
+
+# add a 'best fit' line
+y = mlab.normpdf( bins, mu, sigma)
+l = plt.plot(bins, y, 'r--', linewidth=1)
+
+plt.xlabel('Smarts')
+plt.ylabel('Probability')
+plt.title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$')
+plt.axis([40, 160, 0, 0.03])
+plt.grid(True)
+plt.show()

+ 73 - 0
home/public/org/ipython-hist.org

@@ -0,0 +1,73 @@
+* Playing with histograms in ob-ipython
+
+  See https://github.com/gregsexton/ob-ipython
+
+#+BEGIN_SRC ipython :session
+  %matplotlib inline
+  import matplotlib.pyplot as plt
+  import numpy as np
+#+END_SRC
+
+
+
+#+BEGIN_SRC ipython :session :file /tmp/hist.svg :exports both
+
+  points=np.random.randn(1000)
+
+  print("min", points.min())
+  min_x=int(points.min() - 1)
+  print("min_x", min_x)
+
+  print("max", points.max())
+  max_x=int(points.max() + 1)
+  print("max_x", max_x)
+
+
+  #print("points", points)
+
+#+End_SRC
+
+
+
+#+BEGIN_SRC ipython :session :file /tmp/hist.svg :exports both
+    %config InlineBackend.figure_format = 'svg'
+
+    plt.hist(points, bins=10)
+    plt.axis([min_x, max_x,0,20])
+    plt.xlabel('X things')
+    plt.ylabel('Y things')
+    plt.title("Title Thing")
+    plt.grid(True)
+#+End_SRC
+
+
+
+* Example histogram
+   From https://matplotlib.org/1.2.1/examples/pylab_examples/histogram_demo.html
+
+  #+BEGIN_SRC ipython :session :file /tmp/hist2.svg :exports both
+    %config InlineBackend.figure_format = 'svg'
+
+    import numpy as np
+    import matplotlib.mlab as mlab
+    import matplotlib.pyplot as plt
+
+    mu, sigma = 100, 15
+    x = mu + sigma*np.random.randn(10000)
+
+    # the histogram of the data
+    n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75)
+
+    # add a 'best fit' line
+    y = mlab.normpdf( bins, mu, sigma)
+    l = plt.plot(bins, y, 'r--', linewidth=1)
+
+    plt.xlabel('Smarts')
+    plt.ylabel('Probability')
+    plt.title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$')
+    plt.axis([40, 160, 0, 0.03])
+    plt.grid(True)
+    #+END_SRC
+
+    #+RESULTS:
+    [[file:/tmp/hist2.svg]]

+ 49 - 0
home/public/org/ob-cache.org

@@ -0,0 +1,49 @@
+Test results of reading cached results in OB blocks w/o re-exeuction
+
+Caveat: results have to be left justified if caching us used or
+results are not picked up
+
+* Output cached tables
+** Left Justified
+#+name: STUFF1
+#+begin_src shell  :results output table :exports results :cache yes
+echo a b c time
+echo 1 2 3 `date +%s`
+echo 4 5 6 0
+#+end_src
+
+#+RESULTS[ab9d0568e51adca45cdf65701d481a475d07b0e3]: STUFF1
+| a | b | c |       time |
+| 1 | 2 | 3 | 1503328650 |
+| 4 | 5 | 6 |          0 |
+
+** Not Left Justified
+  #+name: STUFF2
+  #+begin_src shell  :results output table :exports results :cache yes
+  echo d e f time
+  echo 1 2 3 `date +%s`
+  echo 4 5 6 0
+  #+end_src
+
+  #+RESULTS[395dcd437c9eb11f42e463c5333797c0007f0b9a]: STUFF2
+  | d | e | f |       time |
+  | 1 | 2 | 3 | 1503328653 |
+  | 4 | 5 | 6 |          0 |
+
+
+     #+BEGIN_SRC ipython :session foo  :var stuff1=STUFF1 :exports results
+stuff1
+     #+END_SRC
+
+     #+RESULTS:
+     | a | b | c |       time |
+     | 1 | 2 | 3 | 1503328650 |
+     | 4 | 5 | 6 |          0 |
+
+
+     #+BEGIN_SRC ipython :session foo  :var stuff2=STUFF2 :exports results
+stuff2
+     #+END_SRC
+
+     #+RESULTS:
+     : nil

+ 6 - 0
home/public/org/org-latex.org

@@ -0,0 +1,6 @@
+* Famous mashups
+
+  #+begin_quote
+  Once upon a midnight dreary, our forefathers founded a place where
+  no man has gone before...
+  #+end_quote

+ 50 - 0
home/public/org/orgShellArrays.org

@@ -0,0 +1,50 @@
+#+NAME: my_list
+| one   |
+| two   |
+| three |
+
+#+NAME: experiment
+| name | first_attempt    |
+| date | [2014-03-27 Thu] |
+| user | fleury           |
+
+#+BEGIN_SRC sh :var scalar="some value" :var array=my_list :var table=experiment
+echo ${scalar}  # -> prints 'some value'
+echo ${array}   # -> prints 'one two three'
+echo ${table}   # -> prints 'first attempt [2014-03-27 Thu] fleury'
+#+END_SRC
+
+#+RESULTS:
+| some | value         |       |             |      |      |        |
+| one  | two           | three |             |      |      |        |
+| name | first_attempt | date  | [2014-03-27 | Thu] | user | fleury |
+
+
+#+BEGIN_SRC sh :var scalar="some value" :var array=my_list :var table=experiment
+echo ${scalar}
+#echo ${array[1]} # -> prints "two"
+#echo ${table[user]} # -> prints "fleury"
+#+END_SRC
+
+#+RESULTS:
+: some value
+
+
+#+name: list-o-numbers
+| 1 one | 2 | 3 |
+|     4 | 5 | 6 |
+|     7 | 8 | 9 |
+
+#+begin_src sh :var column=list-o-numbers[,0]
+  echo $column
+
+
+  foo=(1 22 33)
+  echo second ${foo[1]}
+
+  for i in $column; do 
+    echo $i
+  done
+#+end_src
+
+#+RESULTS:

+ 18 - 0
home/public/org/orgTables.org

@@ -0,0 +1,18 @@
+  * Fun with name fields and recalculation in org tables
+   See http://orgmode.org/org.html#Advanced-features
+  
+     |---+---------+--------+--------+--------+-------+------|
+     |   | Student | Prob 1 | Prob 2 | Prob 3 | Total | Note |
+     |---+---------+--------+--------+--------+-------+------|
+     | ! |         |     P1 |     P2 |     P3 |   Tot |      |
+     | # | Maximum |     11 |     15 |     25 |    51 | 10.2 |
+     | ^ |         |     m1 |     m2 |     m3 |    mt |      |
+     |---+---------+--------+--------+--------+-------+------|
+     | # | Peter   |     10 |      8 |     23 |    41 |  8.2 |
+     | # | Sam     |      2 |      4 |      3 |     9 |  1.8 |
+     |---+---------+--------+--------+--------+-------+------|
+     |   | Average |        |        |        |  25.0 |      |
+     | ^ |         |        |        |        |    at |      |
+     | $ | max=50  |        |        |        |       |      |
+     |---+---------+--------+--------+--------+-------+------|
+     #+TBLFM: $6=vsum($P1..$P3)::$7=10*$Tot/$max;%.1f::$at=vmean(@-II..@-I);%.1f

+ 12 - 0
home/public/org/orgTablesWithNamedTotals.org

@@ -0,0 +1,12 @@
+* Org mode table example summing columns by nane
+
+| WHAT  | Thing1 Name | Thing1 Name | Thing3 Name |
+|-------+-------------+-------------+-------------|
+| Foo   |           1 |           2 |           3 |
+| Bar   |           4 |           5 |           6 |
+| Baz   |           7 |           8 |          42 |
+|-------+-------------+-------------+-------------|
+| Total |          12 |          15 |          51 |
+| ^     |      Thing1 |      Thing2 |      Thing3 |
+#+TBLFM: $Thing1=vsum(@2..@-1)
+#+TBLFM: $Thing2=vsum(@2..@-1)::$Thing3=vsum(@2..@-1)::

+ 34 - 0
home/public/org/tableOutput.org

@@ -0,0 +1,34 @@
+* Can I output a table that is auto expanded?
+  e.g. output
+
+| foo | bar |
+|-
+| baz
+
+and get this
+
+| foo | bar |
+|-----+-----|
+| baz |     |
+
+without a manual org cyle
+
+#+begin_src shell  :results raw replace :wrap :cache no :exports results
+  exec 2>&1;set -e; set -u; set +x; echo '#' `date;`
+  echo '|foo|bar|' '
+' '|baz'
+
+
+
+#+end_src
+
+#+RESULTS:
+#+BEGIN_RESULTS
+# Sun Nov 27 07:50:50 EST 2016
+| foo | bar |
+|-----+-----|
+| baz |     |
+#+END_RESULTS
+
+
+

+ 74 - 0
home/public/pandas/convert_rows_to_integer.org

@@ -0,0 +1,74 @@
+Convert all fields in a column to integer or NaN
+
+#+begin_src ipython :session Assignment4  :exports both  :results output
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import math
+
+purchase_1 = pd.Series({'Name': 'Fred',
+                        'Item Purchased': 'Piston Engine',
+                        'Cost': 22.50})
+purchase_2 = pd.Series({'Name': 'Wilbur',
+                        'Item Purchased': 'Woes',
+                        'Cost': 2})
+purchase_3 = pd.Series({'Name': 42,
+                        'Item Purchased': 'The Wrong Thing',
+                        'Cost': "An arm and a leg"})
+
+#
+# "Cost" has float, int and str values
+#
+df = pd.DataFrame([purchase_1, purchase_2, purchase_3], index=['Store 1', 'Store 1', 'Store 2'])
+print("Data")
+print(df.head())
+print("")
+
+#
+# Print the types in each column
+#
+
+#print("Types")
+
+# All at once
+#dtypeCount =[df3.iloc[:,i].apply(type).value_counts() for i in range(df3.shape[1])]
+
+
+# One at a time
+# for i in range(df.shape[1]):
+#     print("i=", i)
+#     print(df.iloc[:,i].apply(type).value_counts())
+
+
+#
+# Apply funtion to convert everyhing
+# in 'Cost' column to integer or NaN
+#
+
+def cost2int(row):
+    try:
+        row['Cost']=int(row['Cost'])
+    except:
+        row['Cost']=math.nan
+
+    return row
+
+#
+# Print the results
+#
+print(df.apply(cost2int, axis=1))
+#+end_src
+
+#+RESULTS:
+#+begin_example
+Data
+                     Cost   Item Purchased    Name
+Store 1              22.5    Piston Engine    Fred
+Store 1                 2             Woes  Wilbur
+Store 2  An arm and a leg  The Wrong Thing      42
+
+         Cost   Item Purchased    Name
+Store 1  22.0    Piston Engine    Fred
+Store 1   2.0             Woes  Wilbur
+Store 2   NaN  The Wrong Thing      42
+#+end_example

+ 75 - 0
home/public/pandas/data_types_in_df.org

@@ -0,0 +1,75 @@
+Count the number of different data types in pandas column
+https://stackoverflow.com/questions/41262370/determining-pandas-column-datatype
+
+#+begin_src ipython :session Assignment4  :exports both  :results output
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+
+purchase_1 = pd.Series({'Name': 'Fred',
+                        'Item Purchased': 'Piston Engine',
+                        'Cost': 22.50})
+purchase_2 = pd.Series({'Name': 'Wilbur',
+                        'Item Purchased': 'Woes',
+                        'Cost': 2.50})
+
+# Data with only expected types in frame
+df = pd.DataFrame([purchase_1, purchase_2], index=['Store 1', 'Store 1'])
+print("Data")
+print(df.head())
+print("")
+
+dtypeCount =[df.iloc[:,i].apply(type).value_counts() for i in range(df.shape[1])]
+print("Types")
+print(dtypeCount)
+
+
+# Data with unexpected types
+purchase_3 = pd.Series({'Name': 42,
+                        'Item Purchased': 'The Wrong Thing',
+                        'Cost': "An arm and a leg"})
+df2 = pd.DataFrame([purchase_1, purchase_2, purchase_3], index=['Store 1', 'Store 1', 'Store 2'])
+print("Data")
+print(df2.head())
+print("")
+
+#dtypeCount =[df2.iloc[:,i].apply(type).value_counts() for i in range(df2.shape[1])]
+print("Types")
+for i in range(df2.shape[1]):
+    print("i=", i)
+    print(df2.iloc[:,i].apply(type).value_counts())
+
+
+#+end_src
+
+#+RESULTS:
+#+begin_example
+Data
+         Cost Item Purchased    Name
+Store 1  22.5  Piston Engine    Fred
+Store 1   2.5           Woes  Wilbur
+
+Types
+[<class 'float'>    2
+Name: Cost, dtype: int64, <class 'str'>    2
+Name: Item Purchased, dtype: int64, <class 'str'>    2
+Name: Name, dtype: int64]
+Data
+                     Cost   Item Purchased    Name
+Store 1              22.5    Piston Engine    Fred
+Store 1               2.5             Woes  Wilbur
+Store 2  An arm and a leg  The Wrong Thing      42
+
+Types
+i= 0
+<class 'float'>    2
+<class 'str'>      1
+Name: Cost, dtype: int64
+i= 1
+<class 'str'>    3
+Name: Item Purchased, dtype: int64
+i= 2
+<class 'str'>    2
+<class 'int'>    1
+Name: Name, dtype: int64
+#+end_example

+ 48 - 0
home/public/pandas/sample_null_rows.org

@@ -0,0 +1,48 @@
+Sample null rows form a pandas data frame
+https://stackoverflow.com/questions/21202652/getting-all-rows-with-nan-value
+#+begin_src python :results output
+
+import pandas as pd
+import numpy as np
+
+# create a frame with some nulls
+ndf =pd.DataFrame({'a':[1,2,3,44],'b':[3,np.nan,5,55],'c':[np.nan, 4,5,np.nan]})
+
+# print the frame
+print(ndf)
+
+# define a function to sample rows with mulls
+
+def sample_nulls(df):
+    """Print a few rows from a dataframe for each columm with null fields"""
+    max_rows_to_print = 5
+    for col in df.columns:
+        nulls=df[pd.isnull(df[col])]
+        how_many = len(nulls)
+        if how_many > 0:
+            num_to_print=min(max_rows_to_print,how_many)
+            print("Column ", col, " has ", how_many, " rows with nulls.  Printing ", num_to_print)
+            print(nulls.iloc[0:num_to_print])
+            #ndf[pd.isnull(ndf['c'])].iloc[0:2]
+
+
+# use the function
+sample_nulls(ndf)
+
+#+end_src
+
+#+RESULTS:
+#+begin_example
+    a     b    c
+0   1   3.0  NaN
+1   2   NaN  4.0
+2   3   5.0  5.0
+3  44  55.0  NaN
+Column  b  has  1  rows with nulls.  Printing  1
+   a   b    c
+1  2 NaN  4.0
+Column  c  has  2  rows with nulls.  Printing  2
+    a     b   c
+0   1   3.0 NaN
+3  44  55.0 NaN
+#+end_example

+ 31 - 0
home/public/pandas/series.org

@@ -0,0 +1,31 @@
+Experiments with pandas series objects
+
+#+BEGIN_SRC ipython :session tests
+  %matplotlib inline
+  import matplotlib.pyplot as plt
+  import numpy as np
+  import pandas as pd
+#+END_SRC
+
+#+RESULTS:
+
+
+
+
+
+ #+begin_src ipython :session tests
+sports = {99: 'Bhutan',
+          100: 'Scotland',
+          101: 'Japan',
+          102: 'South Korea'}
+s = pd.Series(sports)
+
+scores = {'Reds': 5,
+          'Dodgers': 3,
+          'Dodgers': 2
+          }
+sc = pd.Series(scores)
+ #+end_src
+
+ #+RESULTS:
+ : 2

BIN
home/public/python/__pycache__/logging.cpython-36.pyc


+ 35 - 0
home/public/python/catsortuniq.py

@@ -0,0 +1,35 @@
+#! /usr/bin/env python
+# 
+# Write the equivalent of 
+#
+#   cat FOO | sort | uniq 
+# 
+# or simply
+#
+#   sort -u FOO
+#
+# in python
+
+import fileinput  
+import sys
+
+lines={}
+
+
+for line in fileinput.input(sys.argv[1:]):
+    line = line.rstrip()
+
+    if len(line) < 1:
+        pass
+    else:
+        lines[line] = line
+
+print ">>>"
+for line in lines.keys():
+    print line
+print "<<<"    
+
+
+
+
+

+ 15 - 0
home/public/python/dicts.py

@@ -0,0 +1,15 @@
+#! /usr/bin/env python
+"""
+Simple tests of dictionaries in python
+"""
+
+foo = {}
+foo["foo"]="fooo"
+foo["bar"]="baaar"
+foo["baz"]="baaaz"
+
+for k in foo.keys():
+    print "key", k, "value", foo[k]
+    
+
+    

+ 44 - 0
home/public/python/exercises/python/InsertionSort.py

@@ -0,0 +1,44 @@
+"""
+This classs implements insertion sort on an unsorted array.
+
+
+Operations:
+  - sortedArray = (unsortedArray)
+"""
+
+class InsertionSort(object):
+    """My Hash Library"""
+
+    def __init__(self, unsortedArray):
+        """Sort an unsorted array"""
+        self.array = unsortedArray
+        print "starting array is", self.print_array()
+        return None
+
+    def print_array(self):
+        """Print the array"""
+        print self.array
+
+    def sort_array(self):
+        """Sort the array"""
+        array_range = range(1, len(self.array))
+        for i in array_range:
+            j = i
+            while j > 0 and self.array[j-1] > self.array[j]:
+                # swap
+                save = self.array[j]
+                self.array[j] = self.array[j-1]
+                self.array[j-1] = save
+                j = j - 1
+
+# Pseudo-Code
+# for i = 1 to length(A)
+#     j = i
+#     while j > 0 and A[j-1] > A[j]
+#         swap A[j] and A[j-1]
+#         j = j - 1
+#     end while
+# end for
+
+        return self.array
+

BIN
home/public/python/exercises/python/InsertionSort.pyc


+ 81 - 0
home/public/python/exercises/python/QuickSort.py

@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+"""
+This class implements qucksort on arrays.
+
+See https://en.wikipedia.org/wiki/Quicksort
+
+#    algorithm quicksort(A, lo, hi) is#
+#        if lo < hi then
+#            p := partition(A, lo, hi)
+#            quicksort(A, lo, p – 1)
+#            quicksort(A, p + 1, hi)
+#    
+#    algorithm partition(A, lo, hi) is
+#        pivot := A[hi]
+#        i := lo - 1    
+#        for j := lo to hi - 1 do
+#            if A[j] ≤ pivot then
+#                i := i + 1
+#                swap A[i] with A[j]
+#        swap A[i+1] with A[hi]
+#        return i + 1
+#    
+"""
+
+class QuickSort(object):
+    """Quicksort implementaton"""
+
+    def __init__(self, unsorted_array):
+        """Initialize an array for quicksort"""
+        self.array_to_sort = unsorted_array
+        self.is_sorted = False
+        print "starting array is", self.print_array()
+        return None
+
+    def print_array(self):
+        """Print the [un]sorted array"""
+        print self.array_to_sort
+
+    def swap(self, swap_x, swap_y):
+        """swap two elements of an array"""
+        tmp = self.array_to_sort[swap_x]
+        self.array_to_sort[swap_x] = self.array_to_sort[swap_y]
+        self.array_to_sort[swap_y] = tmp
+
+    def partition(self, lo_index, hi_index):
+        """Parttiton the array"""        
+        print "partition(%d,%d)" % (lo_index, hi_index)
+        print "  array: ", self.array_to_sort
+
+        # pivot on this value
+        pivot = self.array_to_sort[hi_index]
+        print "  pivot on hi_index ", hi_index, " pivot is ", pivot
+        print
+
+        # next place to put values less than pivot
+        insert_here = lo_index - 1 
+
+        for from_here in range(lo_index, hi_index):
+            if self.array_to_sort[from_here] <= pivot:
+                # move where to insert right one
+                insert_here = insert_here + 1
+
+                # put value less than pivot left of pivot value
+                self.swap(insert_here, from_here)
+
+        # finally, swap the pivot value itself to the end of the lis
+        self.swap(insert_here+1, hi_index)
+
+        # and report where we partitioned
+        return insert_here + 1
+
+    def quicksort(self, lo_index, hi_index):
+        """Quicksort a slice of the array"""
+        print "quicksort(%d,%d)" % (lo_index, hi_index)
+        print "  array: ", self.array_to_sort
+        print
+        if lo_index < hi_index:
+            partition_index = self.partition(lo_index, hi_index)
+            self.quicksort(lo_index, partition_index - 1)
+            self.quicksort(partition_index + 1, hi_index)
+        self.is_sorted = True

+ 6 - 0
home/public/python/exercises/python/input.txt

@@ -0,0 +1,6 @@
+7
+1
+0
+7
+9
+1

+ 68 - 0
home/public/python/exercises/python/merge_sort.py

@@ -0,0 +1,68 @@
+"""
+This function implements merge sort on an unsorted array
+
+Operations:
+  - sortArray
+"""
+
+def merge_sort(sort_this):
+    """Implement merge sort for an array"""
+
+    # if array is empty or one elelemnt, just return it
+
+    if len(sort_this) <= 1:
+        # print "EMPTY OR ONE, returning:", sort_this
+        return sort_this
+
+    if len(sort_this) == 2:
+
+        if sort_this[0] < sort_this[1]:
+            # print "TWO ELEMENTS, return sort_this:", sort_this            
+            return_this = list(sort_this)
+            # print "TWO ELEMENTS, return_this:", return_this            
+        else:
+            # print "TWO ELEMENTS, return reverse sort_this:", sort_this                        
+            return_this = list(sort_this)
+            return_this.reverse()
+            # print "TWO ELEMENTS, return sort_this.reverse:", return_this
+            
+
+        # print "TWO ELEMENTS, sort_this:", sort_this
+        # print "TWO ELEMENTS, returning:", return_this
+        return return_this
+
+    # halve the unsorted arrays
+
+    middle = len(sort_this)/2
+    left_half = sort_this[:middle]
+    right_half = sort_this[middle:]
+
+    # print
+    # print "LEFT_HALF", left_half
+    # print "RIGHT_HALF", right_half
+
+    # sort halves
+
+    left_half_sorted = merge_sort(left_half)
+    right_half_sorted = merge_sort(right_half)
+
+    # print "LEFT_HALF_SORTED", left_half_sorted
+    # print "RIGHT_HALF_SORTED", right_half_sorted
+
+    # merge sorted halves
+    merged = []
+    while len(merged) < len(sort_this):
+        # deal with exhaustion of either half
+        if left_half_sorted and not right_half_sorted:
+            merged += left_half_sorted
+        elif right_half_sorted and not left_half_sorted:
+            merged += right_half_sorted
+        else:
+            if left_half_sorted[0] < right_half_sorted[0]:
+                merged.append(left_half_sorted.pop(0))
+            else:
+                merged.append(right_half_sorted.pop(0))
+
+    # print "MERGED, returning:", merged
+    return merged
+

+ 92 - 0
home/public/python/exercises/python/myhash.py

@@ -0,0 +1,92 @@
+"""
+This classs implements a set of functions for implementing a hash
+
+Operations:
+  - set(hash, value)
+  - value = get(hash)
+"""
+
+class MyHash(object):
+    """Provide functions to set and get a hashed key/vlue pairs
+    """
+
+    def __init__(self, name):
+        """For now, use positionally corresponding arrays to store hash keys and values"""
+        self.hash_keys = []    # array of hash values (strings)
+        self.hash_values = []  # array of hash values
+        self.hash_name = name
+
+    def set(self, hash_key, hash_value):
+        """Set hash value
+
+        Return True if value was already present
+        Return False if value was not present
+        """
+        found = False
+
+        # Linear search, update existing if found
+        for i in range(len(self.hash_keys)):
+            if self.hash_keys[i] == hash_key:
+                self.hash_values[i] = hash_value
+                found = True
+                return True
+
+        # Append to end, no ordering
+        if not found:
+            self.hash_keys.append(hash_key)
+            self.hash_values.append(hash_value)
+
+        return False
+
+    def get(self, hash_key):
+        """Get hash value for key
+
+        Return value if found or None
+        """
+
+        # Linear search for matching element
+        for i in range(len(self.hash_keys)):
+            if self.hash_keys[i] == hash_key:
+                return self.hash_values[i]
+
+        return None
+
+    def binary_search(self, find_this_key, low_index, high_index):
+        """Binary search for the value of a particulary hash key"""
+
+        print "binary_search ", find_this_key, low_index, high_index
+
+        if (high_index < low_index):
+            print "return None"
+            return None
+        if high_index - low_index < 0:
+            print "return None 2"           
+            return None
+        elif high_index - low_index == 0 and self.hash_keys[low_index] == find_this_key:
+            print "Returning ", self.hash_values[low_index]
+            return self.hash_values[low_index]
+            
+        else:
+            middle_index = (high_index - low_index)/2
+
+            value_found_in_left_half = self.binary_search(find_this_key, low_index, middle_index-1)
+
+            if value_found_in_left_half != None:
+                print "RETURNING LEFT HALF VALUE", value_found_in_left_half
+                return value_found_in_left_half
+
+            print "SEARCHING RIGHT HALF, MIDDLE ", middle_index, " HIGH ", high_index
+
+
+            return self.binary_search(find_this_key, middle_index+1, high_index)
+
+        print "return None 3"                   
+        return None
+
+
+    def get_fast(self, find_this_key):
+        """Get hash value for key.  Faster than 'get'"""
+
+        return self.binary_search(find_this_key, 0, len(self.hash_keys) - 1)
+
+

+ 16 - 0
home/public/python/exercises/python/qs.pseudocode

@@ -0,0 +1,16 @@
+algorithm quicksort(A, lo, hi) is
+    if lo < hi then
+        p := partition(A, lo, hi)
+        quicksort(A, lo, p – 1)
+        quicksort(A, p + 1, hi)
+
+algorithm partition(A, lo, hi) is
+    pivot := A[hi]
+    i := lo - 1    
+    for j := lo to hi - 1 do
+        if A[j] ≤ pivot then
+            i := i + 1
+            swap A[i] with A[j]
+    swap A[i+1] with A[hi]
+    return i + 1
+Sorting the entire array is accomplished by quicksort(A, 1, length(A)).

+ 19 - 0
home/public/python/exercises/python/test_hash.py

@@ -0,0 +1,19 @@
+#! /usr/bin/env python
+
+import myhash
+
+
+animals = myhash.MyHash("dogs")
+animals.set("foo","bar")
+animals.set("bar","bark")
+animals.set("zzz","zzzzz")
+animals.set("baaz","baaazzz")
+
+print "animal foo is ", animals.get("foo")
+print "animal bar is ", animals.get("bar")
+print "animal bar is ", animals.get_fast("bar")
+print "animal bar is ", animals.get("zzz")
+print "animal bar is ", animals.get_fast("zzz")
+
+
+

+ 23 - 0
home/public/python/exercises/python/test_insert.py

@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+"""Test sort functions"""
+
+from InsertionSort import InsertionSort
+
+# Read lines from a file
+
+def main():
+    """main function for testing"""
+
+    with open("input.txt", "r") as input_file:
+        input_array = []
+        for line in input_file:
+            input_array.append(line.strip())
+
+    print "Insertion Sort:"
+    sort_this = InsertionSort(input_array)
+    print "  unsorted input_array is", sort_this.print_array()
+    print "  sorted lines is", sort_this.sort_array()
+
+if __name__ == '__main__':
+    main()
+

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.