Last active
August 13, 2021 17:16
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Since
dc
reads from standard input, you can send input from a pipe as well:(
dc
is an RPN calculator, andp
is for "print," in case that wasn't obvious)