aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile9
-rw-r--r--README.markdown3
-rw-r--r--bin/mean.awk8
-rw-r--r--bin/med.awk19
-rw-r--r--bin/mode.awk13
-rw-r--r--man/man1/mean.1df19
-rw-r--r--man/man1/med.1df21
-rw-r--r--man/man1/mode.1df20
9 files changed, 114 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 2c570bee..6deb9bd6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,7 @@
bin/han
+bin/mean
+bin/med
+bin/mode
bin/rfct
bin/rndi
bin/sd2u
diff --git a/Makefile b/Makefile
index 47bb3891..c1afe191 100644
--- a/Makefile
+++ b/Makefile
@@ -67,6 +67,9 @@ KEY := 0xC14286EA77BB8872
SENDMAIL := /usr/bin/msmtp
all : bin/han \
+ bin/mean \
+ bin/med \
+ bin/mode \
bin/rfct \
bin/rndi \
bin/sd2u \
@@ -81,6 +84,9 @@ all : bin/han \
clean distclean :
rm -f \
bin/han \
+ bin/mean \
+ bin/med \
+ bin/mode \
bin/rfct \
bin/rndi \
bin/sd2u \
@@ -171,7 +177,8 @@ install-bash-completion : install-bash
install -pm 0644 -- bash/bash_completion "$(HOME)"/.config/bash_completion
install -pm 0644 -- bash/bash_completion.d/* "$(HOME)"/.bash_completion.d
-install-bin : bin/han bin/sd2u bin/su2d bin/tot bin/unf check-bin install-bin-man
+install-bin : bin/han bin/sd2u bin/su2d bin/mean bin/med bin/mode \
+ bin/tot bin/unf check-bin install-bin-man
install -m 0755 -d -- "$(HOME)"/.local/bin
for name in bin/* ; do \
[ -x "$$name" ] || continue ; \
diff --git a/README.markdown b/README.markdown
index 6bc5d1f0..9717cae3 100644
--- a/README.markdown
+++ b/README.markdown
@@ -421,6 +421,9 @@ Installed by the `install-bin` target:
* `jfcd(1df)` watches a directory for changes and runs `jfc(1df)` if it sees any.
* `maybe(1df)` is like `true(1)` or `false(1)`; given a probability of success,
it exits with success or failure. Good for quick tests.
+* `mean(1df)` prints the mean of a list of integers.
+* `med(1df)` prints the median of a list of integers.
+* `mode(1df)` prints the first encountered mode of a list of integers.
* `mkcp(1df)` creates a directory and copies preceding arguments into it.
* `mkmv(1df)` creates a directory and moves preceding arguments into it.
* `motd(1df)` shows the system MOTD.
diff --git a/bin/mean.awk b/bin/mean.awk
new file mode 100644
index 00000000..4506b3b0
--- /dev/null
+++ b/bin/mean.awk
@@ -0,0 +1,8 @@
+# Get the mean of a list of integers
+{ tot += $1 }
+END {
+ # Error out if we read no values at all
+ if (!NR)
+ exit(1)
+ printf "%u\n", tot / NR
+}
diff --git a/bin/med.awk b/bin/med.awk
new file mode 100644
index 00000000..b4a899a1
--- /dev/null
+++ b/bin/med.awk
@@ -0,0 +1,19 @@
+# Get the median of a list of integers; if it has to average it, it uses the
+# integer floor of the result
+{ vals[NR] = $1 }
+NR > 1 && vals[NR] < vals[NR-1] && !warn++ {
+ printf "med: Input not sorted!\n" > "/dev/stderr"
+}
+END {
+ # Error out if we read no values at all
+ if (!NR)
+ exit(1)
+ if (NR % 2) {
+ med = vals[(NR+1)/2]
+ } else {
+ med = (vals[NR/2] + vals[NR/2+1]) / 2
+ }
+ printf "%u\n", med
+ if (warn)
+ exit(1)
+}
diff --git a/bin/mode.awk b/bin/mode.awk
new file mode 100644
index 00000000..beced1f4
--- /dev/null
+++ b/bin/mode.awk
@@ -0,0 +1,13 @@
+# Get mode of a list of integers
+# If the distribution is multimodal, the first mode is used
+{ vals[$1]++ }
+END {
+ # Error out if we read no values at all
+ if (!NR)
+ exit(1)
+ mode = vals[0]
+ for (val in vals)
+ if (vals[val] > vals[mode])
+ mode = val
+ printf "%u\n", mode
+}
diff --git a/man/man1/mean.1df b/man/man1/mean.1df
new file mode 100644
index 00000000..21f509f2
--- /dev/null
+++ b/man/man1/mean.1df
@@ -0,0 +1,19 @@
+.TH MEAN 1df "September 2016" "Manual page for mean"
+.SH NAME
+.B mean
+\- print the mean of a list of integers
+.SH SYNOPSIS
+printf '%u\\n' 8 1 58 |
+.B mean
+.br
+.B mean
+file
+.br
+.B mean
+file1 file2
+.SH DESCRIPTION
+.B mean
+collects all the newline-delimited integers given as input, and prints the
+mean.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/med.1df b/man/man1/med.1df
new file mode 100644
index 00000000..0fab7db2
--- /dev/null
+++ b/man/man1/med.1df
@@ -0,0 +1,21 @@
+.TH MED 1df "September 2016" "Manual page for med"
+.SH NAME
+.B med
+\- print the med of a list of integers
+.SH SYNOPSIS
+printf '%u\\n' 14 2 10 |
+.B med
+.br
+.B med
+file
+.br
+.B med
+file1 file2
+.SH DESCRIPTION
+.B med
+collects all the newline-delimited integers given as input, and prints the
+median. It uses the floor of the mean of the two median values if the number of
+records is even. The input must be sorted, and a warning will be issued if it
+isn't.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/mode.1df b/man/man1/mode.1df
new file mode 100644
index 00000000..d4727235
--- /dev/null
+++ b/man/man1/mode.1df
@@ -0,0 +1,20 @@
+.TH MODE 1df "September 2016" "Manual page for mode"
+.SH NAME
+.B mode
+\- print the mode of a list of integers
+.SH SYNOPSIS
+printf '%u\\n' 2 35 3 8 |
+.B mode
+.br
+.B mode
+file
+.br
+.B mode
+file1 file2
+.SH DESCRIPTION
+.B mode
+collects all the newline-delimited integers given as input, and prints the
+mode. If two values have the same frequency (i.e. a multimodal distribution),
+it will print the one that reaches that frequency first in the data set.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>