From 3909483124a95893429c437336d9812596591c79 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Sep 2016 14:13:13 +1200 Subject: Add mean(1df), med(1df), and mode(1df) --- .gitignore | 3 +++ Makefile | 9 ++++++++- README.markdown | 3 +++ bin/mean.awk | 8 ++++++++ bin/med.awk | 19 +++++++++++++++++++ bin/mode.awk | 13 +++++++++++++ man/man1/mean.1df | 19 +++++++++++++++++++ man/man1/med.1df | 21 +++++++++++++++++++++ man/man1/mode.1df | 20 ++++++++++++++++++++ 9 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 bin/mean.awk create mode 100644 bin/med.awk create mode 100644 bin/mode.awk create mode 100644 man/man1/mean.1df create mode 100644 man/man1/med.1df create mode 100644 man/man1/mode.1df 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 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 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 -- cgit v1.2.3