Agreed about debugging. Dijkstra said something like, “Debugging is the process of taking bugs out; therefore programming is the process of putting them in.” Or consider the revelation of Maurice Wilkes:
As soon as we started programming, we found to our surprise that it wasn’t as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.
One of the biggest misconceptions I notice in non-programmers is that they think it’s mostly typing: “telling the computer what to do.” Depending on the task, it’s a lot of reading, or researching with Google, or staring intently at text on the screen for long minutes until you figure out what you’re doing wrong.
Knowing how to program can often be secret sauce for semi-skilled labor. This resourceful individual claims to have tripled their salary by writing a program to mostly-automate their work, thereby collecting the lion’s share of bonuses. At my company, I’ve saved whole person-weeks of others’ time with really simple stuff.
My first software job was working for a guy who saw a need, wrote one program, and he’s been supporting his family & lifestyle business for 7+ years by selling licenses for $1K-$10K per seat-year to corporate clients who are absolutely thrilled to buy them. Opportunities like this are everywhere, once you start to notice them.
the second most common letter for an English word to end in
It’s actually quite straightforward. It’s just written in a language that most coders don’t use, and moreover it uses data types that most “coderly” languages don’t have. It would be pretty obvious to many experienced Unix sysadmins, though; there’s nothing here that a sysadmin wouldn’t use in doing log analysis or the like.
The most accessible data types in Unix shellscript are strings, semi-lazy streams of strings, and processes. A shell pipeline, such as the above, is a sequence of processes connected by streams; each process’s output is the next one’s input.
cat /usr/share/dict/words | \Create a stream of strings from a single file, namely a standard list of English words.
sed -e 's/.*\(.\)/\1/' | \For each word, extract the last letter.
tr A-Z a-z | \Change any uppercase letters to lowercase.
sort | \Sort the stream, so that all identical letters are adjacent to one another.
uniq -c | \Count identical adjacent letters.
sort -rnSort numerically so that the letters with the highest counts come first.
It is not really clear to me that this is particularly less expressive than the straightforward way to do an equivalent operation in modern Python, as follows:
import collections
c = collections.Counter()
for line in file("/usr/share/dict/words"):
line = line.strip().lower()
if not line:
continue
c[line[-1]] += 1
for (ltr, count) in c.most_common():
print ltr, count
Ways in which it might be less expressive: using the small, efficient pieces of Unix takes a while to be conceptually similar to using the different functions of a programming language. Using a regex.
(Inferential distance is hard to estimate; I know I like to hear where I’m incorrectly assuming short distances; I hope you do too).
Agreed about debugging. Dijkstra said something like, “Debugging is the process of taking bugs out; therefore programming is the process of putting them in.” Or consider the revelation of Maurice Wilkes:
One of the biggest misconceptions I notice in non-programmers is that they think it’s mostly typing: “telling the computer what to do.” Depending on the task, it’s a lot of reading, or researching with Google, or staring intently at text on the screen for long minutes until you figure out what you’re doing wrong.
Knowing how to program can often be secret sauce for semi-skilled labor. This resourceful individual claims to have tripled their salary by writing a program to mostly-automate their work, thereby collecting the lion’s share of bonuses. At my company, I’ve saved whole person-weeks of others’ time with really simple stuff.
My first software job was working for a guy who saw a need, wrote one program, and he’s been supporting his family & lifestyle business for 7+ years by selling licenses for $1K-$10K per seat-year to corporate clients who are absolutely thrilled to buy them. Opportunities like this are everywhere, once you start to notice them.
Cribbing a bit from Doug McIlroy:
Edit: whoops, John_Maxwell_IV is right about the above program. It’s 50% humor, 50% code golf.
Just for the benefit of bystanders, most computer programs to do what I described are far easier to understand than the one wmorgan wrote.
It’s actually quite straightforward. It’s just written in a language that most coders don’t use, and moreover it uses data types that most “coderly” languages don’t have. It would be pretty obvious to many experienced Unix sysadmins, though; there’s nothing here that a sysadmin wouldn’t use in doing log analysis or the like.
The most accessible data types in Unix shellscript are strings, semi-lazy streams of strings, and processes. A shell pipeline, such as the above, is a sequence of processes connected by streams; each process’s output is the next one’s input.
cat /usr/share/dict/words | \
Create a stream of strings from a single file, namely a standard list of English words.sed -e 's/.*\(.\)/\1/' | \
For each word, extract the last letter.tr A-Z a-z | \
Change any uppercase letters to lowercase.sort | \
Sort the stream, so that all identical letters are adjacent to one another.uniq -c | \
Count identical adjacent letters.sort -rn
Sort numerically so that the letters with the highest counts come first.It is not really clear to me that this is particularly less expressive than the straightforward way to do an equivalent operation in modern Python, as follows:
Ways in which it might be less expressive: using the small, efficient pieces of Unix takes a while to be conceptually similar to using the different functions of a programming language. Using a regex.
(Inferential distance is hard to estimate; I know I like to hear where I’m incorrectly assuming short distances; I hope you do too).
Unnecessary use of cat! (And backslashes!)
:-)
The pleonastic cat was intentional (I like the expressiveness), but I didn’t know that about pipes. Very cool!
It works with
&&
and||
too: