Profits for Doofenshmirtz Evil Incorporated skyrocketed after renting all those inators. As the minions completed deliveries, Dr. Doofenshmirtz finally had the time to complete his Invisible-inator. Unfortunately, the invisible-inator went off by accident and rendered most of the rental profits1 useless2.
As part of his new lifestyle, he’s made friends with some rich and famous folks. Now he’s invited to all the fanciest parties.
Wining, dining, etc.
The problem is that Dr. Doofenshmirtz is terribly awkward4. He has nothing to talk about. Everyone’s all “Brothers Karamazov” this, “Gravity’s Rainbow” that. It’s all about who’s reading the smart-iest books.
This is where you come in.
Your task is to develop a command line application to help Dr. Doofenshmirtz determine the smartness of various books, so that he can impress his fancy new friends. For this assignment, you are to do the following:
Refer to this assignment’s rubric for further description of point values for completed tasks.
Your application should work something like this:
# If we don't provide any options, it prints the usage. $ ./main Need at least one link to process. Usage: ./main [options] URL [URL ...] This program calculates the smartness of UTF-8 encoded books. It accepts one or more URLs as positional arguments. Each URL should point to a UTF-8 encoded ".txt" file. -workers uint The number of workers to use. (default 1)
# If we list some book URLs, we get the smartness counts for those books ./main http://cpl.mwisely.xyz/hw/7/books/Alices-Adventures-in-Wonderland.txt http://cpl.mwisely.xyz/hw/7/books/Fritiofs-Saga.txt http://cpl.mwisely.xyz/hw/7/books/Metamorphosis.txt http://cpl.mwisely.xyz/hw/7/books/Alices-Adventures-in-Wonderland.txt smartness: 4.4836 http://cpl.mwisely.xyz/hw/7/books/Fritiofs-Saga.txt smartness: 4.9459 http://cpl.mwisely.xyz/hw/7/books/Metamorphosis.txt smartness: 4.4809
# If we specify more than one worker, we may get results in a different order $ ./main -workers 4 http://cpl.mwisely.xyz/hw/7/books/Alices-Adventures-in-Wonderland.txt http://cpl.mwisely.xyz/hw/7/books/Fritiofs-Saga.txt http://cpl.mwisely.xyz/hw/7/books/Metamorphosis.txt http://cpl.mwisely.xyz/hw/7/books/Alices-Adventures-in-Wonderland.txt smartness: 4.4836 http://cpl.mwisely.xyz/hw/7/books/Metamorphosis.txt smartness: 4.4809 http://cpl.mwisely.xyz/hw/7/books/Fritiofs-Saga.txt smartness: 4.9459
If we use more than one worker (goroutine), we will see results as they are available. That order may be different than the order the URLs are listed on the command line. The order may even change between subsequent runs.
# If there's a problem with any of the links, we report the error instead of the smartness. $ ./main http://nope.mwisely.xyz/fake.txt http://cpl.mwisely.xyz/hw/7/books/Metamorphosis.txt http://nope.mwisely.xyz/fake.txt error: Get http://nope.mwisely.xyz/fake.txt: dial tcp: lookup nope.mwisely.xyz on 127.0.1.1:53: no such host http://cpl.mwisely.xyz/hw/7/books/Metamorphosis.txt smartness: 4.4809
You will be finishing the implementation of a Go program.
Make sure your code follows the program documentation.
Be sure to read the “Approaching this Assignment” section of this post for advice.
The user specifies the number of workers using the
Your program should start exactly that many goroutines to calculate the smartness of each provided book.
Your goroutines should be set up as shown in the following diagram:
main() sends URLs to process over a channel of
Meanwhile, each goroutine receives URLs from the channel of strings, calculates smartness, and sends
Results over its result channel.
Every URL results in one
Result pushed on the result channel.
When a goroutine finds that there are no more URLs left in the channel of strings, it ends.
After closing the channel of file paths,
main() begins receiving from the channel of
It then prints each
Result that it receives from the channel.
When there are no more
Results on the channel, the program is over.
Your program needs to do a bit of error handling as described in the program documentation.
Result has a non-nil error value, its count field is irrelevant.
It can just be the zero-value.
To make sure everyone has access to the correct documentation for Go, we will all be using Go version 1.9.2 (the latest and greatest). Since the version on campus machines is behind, you’ll have to get version 1.9.2 yourself. We’ve included a setup script that will download and unpack Go for you. It works for 64-bit Linux machines (which is what the campus boxes are).
# After cloning the starter code $ bash setup.sh ... a bunch of output... # We have to specify the location of our Go installation # with the GOROOT environment variable. # The easiest way to do that is to set it on the same line # as the command we're about to run. $ GOROOT="$(pwd)/go" ./go/bin/go version go version go1.9.2 linux/amd64 # If you're curious what the "$(pwd)/go" is for, try this: $ echo "$(pwd)/go" # You can also add GOROOT to your environment like this $ export GOROOT="$(pwd)/go" # Then you can leave it off when you run the go command $ ./go/bin/go version go version go1.9.2 linux/amd64
You can compile and run your program in one step with
$ GOROOT="$(pwd)/go" ./go/bin/go run main.go http://cpl.mwisely.xyz/hw/7/books/Alices-Adventures-in-Wonderland.txt
Or you can compile your program and run the executable that gets produced.
$ GOROOT="$(pwd)/go" ./go/bin/go build main.go $ ./main http://localhost:4000/hw/7/books/Alices-Adventures-in-Wonderland.txt
There is a limited set of automated tests provided for you in
You can run them as follows.
$ GOROOT="$(pwd)/go" ./go/bin/go test
If everything goes well, you’ll see something like this:
PASS ok _/.../Go-1 0.224s
You should rely on
go fmt to format your code properly.
It will modify your source file in place, so make sure your source files aren’t open in an editor when you run it.
Some editors react badly when an open file is changed by another program.
It’s like having the carpet pulled out from underneath you. Some editors are graceful, others just flail around and leave backup files all over the place.
# Assuming you've saved and closed main.go $ GOROOT="$(pwd)/go" ./go/bin/go fmt main.go
You should tackle this assignment as follows:
setup.shto download, verify, and unpack Go 1.9.2.
calculateSmartness()while referring to examples from class, the program docs, and the Go documentation.
fetchAndCalculate(), which uses
main(), so that it starts goroutines and communicates with them as described.
parseCLI(). It’s done.
This assignment is worth 100 points. It will be graded according to the following rubric:
|Feature||Points Possible||Mostly or completely incorrect (0% of points possible)||Needs improvement (50% of points possible)||Adequate, but still some deficiencies (75% of points possible)||Mostly or completely correct (100% of points possible)|
|Student passes instructor tests||10||-10||-5||-3||0|
|Demonstrates knowledge of channels||5||-5||-3||-2||0|
|Demonstrates knowledge of goroutines||5||-5||-3||-2||0|
|Demonstrates knowledge of for-range loops||5||-5||-3||-2||0|
|Words are scanned using a bufio.Scanner||5||-5||-3||-2||0|
|Goroutines are started and communicate as described||15||-15||-8||-4||0|
|Program compiles successfully (no errors)||5||-5||–||–||0|
|Program runs without runtime errors (no runtime panics)||10||-10||–||–||0|
|Output matches expected output for provided samples||10||-10||-5||-3||0|
|Output matches expected output for additional input samples||10||-10||-5||-3||0|
|Source has been formatted with
|Code Review (well-documented, implementation is straightforward, etc.)||10||-10||-5||-3||0|
Each cell indicates how many points out of the available points will be awarded for that feature (row) and assessment level (column).
-- cannot be achieved.
Refer to the assignment submission page on the course website for details on submitting your code to GitLab.
When we grade your assignment, we will do the following (roughly).
# Using Go version 1.9.2 # Check that `go fmt` makes **no** changes to your style $ go fmt main.go # Compile your code $ go build main.go # Run it with a bunch of inputs (properly formatted and improperly formatted) $ ./main http://nope.mwisely.xyz
response.Bodyto a function that takes an
Why isn’t my word count correct for the Swedish book?
Are you accounting for the fact that the text is UTF-8?
When you run an evil corporation, you tend to distrust banks. “Just keep it under your evil mattress” as they say. ↩
It didn’t take. ↩
A well-established fact at this point. ↩
It’s really difficult to tell a $20 from a $1 when it’s invisible. ↩