COMP 2404 A/C – Final Project Due: Wednesday, April 14 at 11:59:00 pm
For this project, you will design and implement a C++ program that generates a set of reports based on data from Statistics Canada’s Other livestock1 census, for the years 2011 and 2016. Your code will be correctly separated into object design categories, it will be designed for easy extensibility to additional categories of data, and it will meet every principle of good software engineering that we have covered in class.
The mandatory minimum criteria for grading this project is that all the requirements must be implemented, the code must meet all the listed constraints, it must execute correctly, and it must print the required reports to the screen. Submissions that are incomplete, or that don’t work correctly, or that don’t meet all the constraints, or that don’t print out resulting reports, will earn a grade of zero.
2. Data Set and Reports
You will use the Statistics Canada census data provided for you in the farms.dat file posted in cuLearn. This file contains data on nine types of animals living on farms in Canada, including the number of farms that host the animals, and the total number of animals living on those farms, for each region (province or territory) and agricultural sub-region in Canada, for the census years 2011 and 2016.
Statistics Canada’s Other livestock census category includes nine types of animals: horses/ponies, goats, llamas/alpacas, rabbits, bison/buffalo, elk/wapiti, domestic deer, wild boars, and mink.
Each record (i.e. each line) in the census data file gives us farm and animal statistics for a given year, region, agricultural sub-region, and type of animal. That record tells us how many farms reported data for that type of animal, in that sub-region, for that year, and it tells us how many animals were reported by those farms.
The records are formatted as follows: <year region subRegion animalType numFarms numAnimals> where year indicates a census year; region indicates either a province, or a territory, or “CAN” for all of Canada, where the farms and animals are located; subRegion specifies the agricultural sub-region for those farms and animals; animalType tells us which type of animal was counted for that record; numFarms tells us the number of farms that reported hosting animals of that type in that sub-region, for that year; and numAnimals indicates the total number of animals of that type reported as living on those farms.
For example, the first record reads: 2011 CAN All Horses-Ponies 47454 392340
and a later record tells us: 2016 ON Eastern-Ontario-Region Llamas-Alpacas 143 944
The first record tells us that, in the census year 2011, there were 47,454 farms that reported they were hosting horses and ponies in Canada overall. Altogether, those farms reported that a total of 392,340 horses and ponies lived on those farms. The second record tells us that, in 2016, in the Ontario sub-region of Eastern Ontario, there were 143 farms that reported having llamas and/or alpacas, and altogether, they reported a total of 944 llamas and/or alpacas living on those farms.
Your program will use the census data provided in order to generate the following three (3) reports, when requested by the user:
2.1. a report listing the regional percentage breakdown of farms that hosted animals of each type in 2016
- 2.1.1. each row will show data for a region (province or territory), excluding Canada
- 2.1.2. each column will represent a type of animal, in addition to one last column showing the region’s percentage over all animals
- 2.1.3. each cell will show the percentage breakdown, for each region, of farms hosting that specific type of animal, over all regions
- 2.1.4. the cells of the last column will show the percentage breakdown, for each region, of farms hosting all types of animals combined, over all regions
- 2.1.5. the report rows will be ordered in descending order by regional percentage of all animal types, as shown in the last column
- 2.1.6. each column will add up to 100%
- 2.1.7. do not include Canada as a region in your calculations
- 2.1.8. do not include individual sub-regions in your calculations; you must use the numbers for the “All” sub-regions only
- 2.1.9. do not assume that the numbers for each region add up to the numbers for Canada; these are real- life statistics, and like most statistics, they contain omissions; to ensure that your columns add up to 100%, you must compute the correct number for the denominator for calculating the percentages
2.2. a report listing the animal type percentage breakdown for Canada, and for each animal type, the per- centage change from 2011 to 2016
2.2.1. each row will show data for an animal type
2.2.2. there will be three columns:
- (a) the percentage of animals of that type in Canada, over all animal types, in 2011
- (b) the percentage of animals of that type in Canada, over all animal types, in 2016
- (c) the change in percentage for each animal type, from 2011 to 2016
- 2.2.3. for example, horses and ponies represented 21.7% of all Other livestock animals in Canada in 2011, and 20.5% in 2016; this indicates a change of -1.2%
- 2.2.4. the first two columns will each add up to 100%
- 2.2.5. the rows will be ordered in ascending order by percentage change, as shown in the last column
- 2.2.6. you must show the positive or negative indicator (+/-) for the percentage change
- 2.2.7. you will use only Canada as a region in your calculations
2.3. a report listing the sub-region, within each region, that hosted the highest number of horses and ponies in 2016
2.3.1. each row will show data for a region (province or territory), excluding Canada
2.3.2. there will be three columns:
- (a) the region
- (b) the sub-region, within that region, that hosted the highest number of horses and ponies in 2016
- (c) the number of horses and ponies in that sub-region in 2016
2.3.3. the rows will be ordered in descending order by number of animals
3. Program Requirements
You will implement a program that reads in the census data from the farms.dat file posted in cuLearn, and you will present the user with a menu of the three possible reports. When the user selects an option, your program will compute the statistics required for the corresponding report, using the census data. It will print the results to the screen, and save them to a text file unique to that report.
Your program will implement the following requirements:
3.1. Design and implementation requirements
3.1.1. The program will be separated into objects that fit into the control, view, entity, and collection object design categories. You will have one view object, many entity objects, one primary control object that is in charge of the program control flow, several additional control objects that are responsible for report generation, and several objects of one collection class.
- 3.1.2. Your design must be fully scalable and extensible. This means that it must support any number and any value of years, regions, and animal types. You must not hard-code any of these values, or even make any assumptions about how many values there could be.
- 3.1.3. You will use the STL vector container in some portions of this program, where indicated in the in- structions. Only some member functions of the vector class will be permitted, again indicated in the instructions. The basic member functions, such as size(), push_back(), at(), and the overloaded subscript operator are always permitted. No other STL containers, and no STL algorithms, are permitted in this program.
- 3.1.4. DO NOT use the STL map container anywhere in this program. We will be implementing our own version of a map, which will be used to generate the reports.
- 3.1.5. You can use the stringstream class and the iomanip library as needed.
- 3.1.6. You will design a class to hold each record read in from the data file. The data members must be
declared with the correct data type. For example, do not use strings to hold numeric values.
- 3.1.7. All entity and control objects must be dynamically allocated, with the exception of the primary control object. All dynamically allocated memory must be explicitly deallocated when no longer in use. This deallocation must be implemented manually, and in the correct portion of the program.
- 3.1.8. Do not use C library functions. You must use their C++ equivalent.
- 3.1.9. Do not use C++11 techniques like shared pointers, for-each loops, or range-based loops.
3.2. User I/O requirements
- 3.2.1. Report results must be computed and generated on demand only, when the end user requests the
report. They must not be computed in advance.
- 3.2.2. A menu will be presented to the end user. The user will select an option, and the program will compute and generate the statistics for the corresponding report. Once the report results have been printed to the screen and saved to a file, the menu will be displayed again, until the user chooses zero (0) to exit.
3.3. Control object requirements
- 3.3.1. The main() function will contain only two lines of code: one to declare a primary control object, and
the other to call that object’s launch function.
- 3.3.2. In addition to the primary control object that manages the program control flow, your program will implement an inheritance hierarchy of control objects that are responsible for report generation. The base class of this hierarchy will be the abstract ReportGenerator class, and there will be one derived, concrete class for each type of report that the user can run, as described in section 2.
- 3.3.3. The primary control object will create one instance of each concrete report generator class. It will store these objects in a STL vector collection of ReportGenerator pointers, as one of its data members. When the user requests a report, the primary control object will invoke a polymorphic function on the correct report object to do the work.
NOTE: Remember that polymorphism only works with base class pointers. If you invoke a function on an object, or on a derived class pointer, there is no dynamic binding, therefore no polymorphism.
3.4. Report generator base class requirements
Your program will implement an inheritance hierarchy of report generator classes, which must include
polymorphic behaviour, as described below.
You will implement the ReportGenerator base class, which will contain, at minimum:
3.4.1. a static data member that stores the collection of all the records read in from the census data file
- (a) it is necessary that this member be static, since ReportGenerator is an abstract class, and we
cannot create any instances of it
- (b) you will need to design a class to contain the information for each individual record
- (c) this data member will be a STL vector of record pointers
- (d) this data member will store the primary collection of all the census data