CS211 Project 3
Due Monday, December 4
Fish are often counted at fish ladders, or for other sorts of ecological research. For this project, create a program that could plausibly be used to track the average weight of a large number of fish to be recorded. Perhaps imagine that this program is running on a laptop, and a biologist is at a boat ramp soliciting people returning from boats to have their fish weighed and recorded.
Fish Object
A fish object represents one type of fish. It needs to track the number of fish of that type recorded, as well as the total weight. The type of fish should be a string, like "sturgeon" or "steelhead" or "bluegill". Assume the user can spell the type of fish consistently!
- Constructor, makes a fish given a string (fish type)
- A default constructor. Use it to create a fish with blank type. A really good question here is "Why do we need a way to create a fish with no type?". Glad you asked! The stl map needs to be able to create a copy of a fish, and one way to do that is to create a blank fish (as in, no type at all), and then copy the properties from an actual fish over to it. In some cases, we'd prefer to use a copy constructor, but for this application a default constructor will be simple and easy.
- add. This takes a double, the weight of a new fish to add. It adds one to the fish count, and the weight of the new fish to the total weight.
- weight. This is an accessor for total weight, should return the total weight of fish recorded so far, takes no parameters, returns a double.
- average_weight. This takes no parameters, and returns a double, the average weight so far. It also can throw an exception. If the count is 0 (no fish recorded thus far), then it throws a runtime error.
- type. Takes no parameters, returns a string, which is the fish's type, set when the object was created (or copied)
- friend insertion operator. This is a friend, so it'll take two parameters, the ostream reference for output, and a const fish references to the fish to print out. Use const reference here. It's not super important with this small object, but you should get into the habbit of using const reference for objects larger than a memory address unless there's a reason not to. "Reason not to" could including needing a copy that you can modify, an object that's designed to have shallow copies made, etc. This function should try to print out all information about the type of fish, including the average weight. Don't check in advance to make sure the fish count is 0, but handle the exception if average throws one by printing the information with the average omitted.
The exact set of properties isn't a project requirement, but my solution had three. A string to hold the fish type, an int to hold the count, and a double to hold the total weight. You don't need a vector of fish, just the count and total weight.
Fish Object Test
There is a test program for your fish object in the examples area, called fish_object_test.cpp. This will only test your fish object to see if it works right. So it doesn't have a main function that satisfies this project. I recomment writing your fish object first, making sure it passes fish_object_test, and then working on the main function for the program only once you have a working fish object. Here's the expected output from fish_object_test. Note that if you're doing the EC, and use a CSV format, you probably won't want the parenthesis that my program prints out, unless you do a special output routing that omits them.
Good job, average_weight threw an exception with no recorded fish
(This one should print) Average walleye weight: 7.9
Walleye Record: (walleye, 3, 23.7, 7.9)
The main function
The program should give the user a recurring prompt to allow new fish to be entered. The user should have to first enter the type of fish, then the weight. If the type of fish is not yet known, ask the user if they want to add it. If the user does not want to add it (as in, they probably just had a typo in the fish type), don't prompt for the weight, and don't change anything in the data structure. If they do, make a new fish object, and add the new fish weight.
Regarding data structures, store the fish in an STL map, similar to the vocabulary tester project. The types for the map template are string (for the key) and fish (for the value). Note that you can totally use objects like fish in an STL map.
Provide some way for the user to print out a list of fish recorded so far, and a way to get out of the program (enter fish type "exit" or something).
Extra Credit Option
For 25% extra credit on this assignment, add a feature so that the fish information can be recorded into a file, and loaded from the file again later. I'd recommend exporting in some format like comma separated values, and importing the same way. That way, a user of the program could also open the data file in Microsoft Excel or some other spreadsheet program.
My suggestion would be to have a default filename (something like fish_info.csv), and look for the file when starting the program. If opening the file fails, start with an empty data structure. When the user exits the program, overwrite the file with the contents of the map. Basically, for each item in the map, write out something like fish_type,count,total_weight,average\n. If you set up your insertion operator to do the right thing, you can put together a loop like this:
// Open the file as fish_file
for(auto f : fish_map)
fish_file << f << "\n";
25% extra on the assignment comes out to 2.5% in the class. Most of the time, when I add EC, only students who are already heading for an A actually have time to do the EC, so perhaps I should mention that learning to work with a CSV file can be a very handy way to enable your program to interact with spreadsheet software. My wife majored in biology, and I used to work in the Natural Sciences and Mathematics division, so I can tell you with a fair bit of certainty that biologists use Microsoft Excel a lot, and would surely appreciate an "export to excel" option for any data recording program.
Example Usage (Non-EC Version)
Enter a fish: steelhead
New fish type steelhead
Add to database? (Y/N) Y
Enter Weight: 24.3
(steelhead, 1, 24.3, 24.3)
Enter a fish: steelhead
Enter Weight: 26.3
(steelhead, 2, 50.6, 25.3)
Enter a fish: steelhead
Enter Weight: 20.3
(steelhead, 3, 70.9, 23.6333)
Enter a fish: channelcatfish
New fish type channelcatfish
Add to database? (Y/N) Y
Enter Weight: 3.4
(channelcatfish, 1, 3.4, 3.4)
Enter a fish: channelcatfish
Enter Weight: 12.1
(channelcatfish, 2, 15.5, 7.75)
Enter a fish: steelhead
Enter Weight: 28.1
(steelhead, 4, 99, 24.75)
Enter a fish: bluegill
New fish type bluegill
Add to database? (Y/N) Y
Enter Weight: 3.4
(bluegill, 1, 3.4, 3.4)
Enter a fish: stelhead
New fish type stelhead
Add to database? (Y/N) N
Enter a fish: steelhead
Enter Weight: 23.5
(steelhead, 5, 122.5, 24.5)
Enter a fish: dumpcontents
(bluegill, 1, 3.4, 3.4)
(channelcatfish, 2, 15.5, 7.75)
(steelhead, 5, 122.5, 24.5)