Skip to content

Instantly share code, notes, and snippets.

@ernstki
Last active August 13, 2021 17:16
Show Gist options
  • Save ernstki/1432b3ea843410a4826ce9cb1584d7b5 to your computer and use it in GitHub Desktop.
Save ernstki/1432b3ea843410a4826ce9cb1584d7b5 to your computer and use it in GitHub Desktop.
Replicating Bell Labs 1982 demo of a spell checker and talking calculator - https://youtu.be/XvDZLjaCJuw
#!/bin/bash
#
# Replicating Kernighan's spell checker demo (https://youtu.be/XvDZLjaCJuw?t=315)
# and Lorinda Cherry's talking calculator (https://youtu.be/XvDZLjaCJuw?t=800)
# from the 1982 Bell Labs UNIX video
#
# Tested with Python 2.7 on Mac and Linux; your mileage may vary with Python 3.
# - You will need to 'pip install --user inflect' for the calculator part.
# - On Linux, you will need to install the 'flite' package for your distro.
#
ln -s /usr/share/dict/words dict
alias p='cat'
makewords() {
[ -t 0 ] && local infile=$1
eval "${infile:+cat '$infile' |} tr -cd 'A-Za-z\\n ' | tr ' ' '\\n'"
}
lowercase() {
[ -t 0 ] && local infile=$1
eval "${infile:+cat '$infile' |} tr A-Z a-z"
}
unique() { uniq "$@"; }
mismatch() {
diff "${1:--}" "${2:-dict}" | sed -n 's/^< \(.*\)/\1/p'
}
# [sic]
echo "At Bell Labortories
UNIX systems privide
more timesharing ports
than all other systems
combined" > sentence
p sentence
makewords sentence >words
p words
lowercase words >lcwords
p lcwords
sort lcwords >sortedwords
p sortedwords
unique sortedwords >uniquewords
p uniquewords
mismatch uniquewords dict
# Lorinda Cherry's demo of pipes / stream processing
makewords sentence | lowercase | sort | unique | mismatch
# make a script 'check' incorporating the functions above
set +o histexpand
echo "#!/bin/bash
$(declare -f makewords)
$(declare -f lowercase)
$(declare -f unique)
$(declare -f mismatch)
makewords \"\$1\" | lowercase | sort | unique | mismatch" >check
chmod a+x check
./check sentence
# desk calculator; turn numbers into English, then speak
speak() {
if [ $(uname -s) = "Darwin" ]; then
# for different voices on macOS try 'say -v ?'
if test -t 0; then say "$*"; else say; fi
else
# 'flite' wants input on stdin
if test -t 0; then flite <<<"$*"; else flite; fi
fi
}
# source: https://stackoverflow.com/a/25026089/785213
# hat tip: https://stackoverflow.com/q/965210
# hat tip: https://stackoverflow.com/a/30091579/785213
number() {
python -c '
import sys, inflect
i=inflect.engine()
try:
print(
i.number_to_words(
sys.argv[1] if sys.stdin.isatty()
else sys.stdin.readline()
)
)
# catch BrokenPipeError exceptions
except Exception as e:
pass
' "$@"
}
# Bell Labs' Lorinda Cherry - talking calculator demo from 1982
# see: https://youtu.be/XvDZLjaCJuw?t=800
dc | number | speak
8 3-p
q
# make a script 'talkcalc'
set +o histexpand
echo "#!/bin/bash
$(declare -f speak)
$(declare -f number)
dc \"\$@\" | number | speak" >talkcalc
chmod a+x talkcalck
./talkcalc
2 100^p
q
# rm sentence words lcwords sortedwords uniquewords dict check talkcalc
@ernstki
Copy link
Author

ernstki commented May 19, 2020

Since dc reads from standard input, you can send input from a pipe as well:

echo "2 100^p" | dc | number | speak

(dc is an RPN calculator, and p is for "print," in case that wasn't obvious)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment