[97 home > assignments]
Do this assignment on the SEASnet GNU/Linux servers lnxsrv06, lnxsrv07, lnxsrv09, or lnxsrv10, with /usr/local/cs/bin prepended to your PATH.
If you need a hint, ask a TA (or an LA if we have one). This assignment is not intended to be done without any hints.
Instructions: Do the lab part of this assignment (including all shell commands and editing) under Emacs, and start your Emacs session by running M-x open-dribble-file command to create a dribble file lab1.drib in your home directory that records everything you type. (If you do multiple Emacs sessions, name your dribble files lab2.drib, lab3.drib, etc.)
For the editing exercises, use intelligent ways of answering the questions. For example, if asked to move to the first occurrence of the word "scrumptious", do not merely use cursor keys to move the cursor by hand; instead, use the builtin search capabilities to find "scrumptious" quickly.
To start, download a copy of the web page you're looking at into a file named assign1.html. You can do this with Wget or curl. Use cp to make three copies of this file. Call the copies exer1.html, exer2.html, and exer3.html.
Once again, try to accomplish the tasks using a small number of keystrokes. When you are done, save the file and exit back to the command line. You can check your work by using a browser to view exer2.html. Also, check that you haven't deleted something that you want to keep, by using the following command:
diff -u exer1.html exer2.html >exer2.diff
The output file exer2.diff should describe only text that you wanted to remove. Don't remove exer2.diff; you'll need it later.
In addition to inserting and deleting text, there are other common tasks that you should know, like copy and paste, search and replace, and undo.
Use the commands that you learned in class to find answers to the following questions. Don't use a search engine like Google, and don't ask your neighbor, don't use GitHub, etc. When you find a new command, run it so you can see exactly how it works.
Do these tasks all within Emacs. Don't use a shell subcommand if you can avoid it.
#include <stdio.h> int main (void) { int c = getchar (); if (c < 0) { if (ferror (stdin)) perror ("stdin"); else fprintf (stderr, "EOF on input\n"); return 1; } if (putchar (c) < 0 || fclose (stdout) != 0) { perror ("stdout"); return 1; } return 0; }
Use the Emacs command M-x what-line and see what it does.
M-x what-line uses origin-1 numbering; that is, it displays line numbers that assume that the start of your buffer is line 1. Design and implement a command M-x which-line that acts like M-x what-line except that it uses origin-0 numbering. Do this by using C-h f to get help about what-line, navigating through that help to find its source code, putting a copy of the source code into a new file which-line.el, editing that file, loading it into Emacs, and then executing your new command.
For the homework assume you’re in the standard C or POSIX locale. The shell command locale should output LC_CTYPE="C" or LC_CTYPE="POSIX". If it doesn’t, use the following shell command:
export LC_ALL='C'
and make sure locale outputs the right thing afterwards.
Examine the file /usr/share/dict/linux.words, which contains a list of English words, one per line. Each word consists of one or more ASCII characters.
Sort this file and put the sorted output into a file sorted.words.
Then, take a text file containing the HTML in this assignment’s web page, and run the following commands with that text file being standard input. Look generally at what each command outputs (in particular, how its output differs from that of the previous command), and why.
tr -c 'A-Za-z' '[\n*]' tr -cs 'A-Za-z' '[\n*]' tr -cs 'A-Za-z' '[\n*]' | sort tr -cs 'A-Za-z' '[\n*]' | sort -u tr -cs 'A-Za-z' '[\n*]' | sort -u | comm - sorted.words tr -cs 'A-Za-z' '[\n*]' | sort -u | comm -23 - sorted.words
Let’s take the last command as the crude implementation of an English spelling checker. This implementation mishandles the input file sorted.words! Write a shell script named myspell that fixes this problem. Your script should read from standard input and output misspelled words to standard output, for a suitable definition of "words". The shell command:
myspell /usr/share/dict/linux.words
should output nothing, because the dictionary by definition contains only correctly-spelled words.
Consider the old-fashioned Python 2 script
randline.py
.
What happens when this script is invoked on an empty file like
/dev/null
, and why?
What happens when this script is invoked with Python 3 rather
than Python 2, and why? (You can run Python 3 on the SEASnet hosts by
using the command python3
instead
of python
.)
Use Emacs to write a new script shuf.py
in the style
of randline.py
but using Python 3 instead.
Your script should implement the GNU
shuf
command that is part of GNU Coreutils.
GNU shuf
is written in C, whereas
you want a Python implementation so that you can more easily add
new features to it.
Your program should support the following shuf
options, with the same behavior as GNU shuf
:
--echo
(-e
),
--head-count
(-n
),
--repeat
(-r
),
and --help
.
As with GNU shuf
, if --repeat
(-r
)
is used without --head-count
(-n
),
your program should run forever.
Your program should also support
zero non-option arguments or
a single non-option argument "-
"
(either of which means read from standard input),
or a single non-option argument other than "-
"
(which specifies the input file name).
Your program need not support the other options of GNU shuf
.
As with GNU shuf
, your program
should report an error if given invalid arguments.
If you have trouble with optparse
under Python 3, you
can use the argparse
module instead.
Your shuf.py
program should not import any
modules other than argparse
,
string
and the modules that randline.py
already imports.
Don't forget to change its usage message to
accurately describe the modified behavior.
What happens when your shuf.py script is invoked with Python 2 rather than Python 3, and why?
For part (a) of this assignment, submit the following files within a compressed tarball named assign1a.tgz.
For part (b) of this assignment, submit the following files within a compressed tarball named assign1b.tgz.
All files other than the .drib files should use GNU/Linux style, i.e., UTF-8 encoding with LF-terminated lines.
The shell command:
tar -tvf assign1.tgz
should output a list of file names that contains shuf.py etc., with sizes and other metainformation about the files.