Project 6

Modify your bird_data struct from Project 5 to make it a class.

Sample solution

/*
 * 
 * **********************************************************
 * 
 * Author: K. Holcomb
 *
 * Class describing some data about bird observations.
 * 
 * Changelog: Modified from old student homework 20170410
 * 
 * 
 * **********************************************************
 * 
 */

#include <cmath>
#include <string>
#include <vector>

class birdData {
	
//Input values.
    std::string commonName;
    std::vector<float> observations;

    public:
    birdData(std::string, std::vector<float>);
    std::string species_name();
    std::vector<float> stats(); 
    std::vector<float> minmax(std::vector<int> years); 
};


/*
 * 
 * **********************************************************
 * 
 * Author: K. Holcomb
 *
 * 
 * Changelog: Modified from old student homework 20170410
 * 
 * **********************************************************
 * 
 */

#include <cmath>
#include <string>
#include <vector>
#include "birdData.h"

using namespace std;

birdData::birdData(string speciesName,vector<float>obs){
    commonName=speciesName;
    int yearsObs=obs.size();
    for (int i=0;i<yearsObs;i++) {
        observations.push_back(obs[i]);
    }
    return;
}

//Accessor
string birdData::species_name(){
    return this->commonName;
}

vector<float> birdData::stats() {
    float sum=0,devSum=0;
    int yearsObs=observations.size();
    for (int i=0;i<yearsObs;i++) {
        sum+=observations[i];
    }

    float mean=sum/yearsObs;
    for (int i=0;i<yearsObs;i++) {
        devSum+=pow((mean-observations[i]),2);
    }

    float stdev=sqrt(devSum/yearsObs);
    vector<float> birdStats={mean,stdev};
    return birdStats;
}

vector<float> birdData::minmax(vector <int> years) {
    int minIndex=0, maxIndex=0;
    float minimum=observations[0];
    float maximum=observations[0];
    int yearsObs=years.size();
    for (int i=1;i<yearsObs;i++) {
    //If multiple occurrences, will return last one.
        if (observations[i]<=minimum) {
            minimum=observations[i];
            minIndex=i;
        }
        if (observations[i]>=maximum) {
            maximum=observations[i];
            maxIndex=i;
        }
    }

    vector<float> minmaxes={minimum,maximum,(float) years[minIndex],(float) years[maxIndex]};
    return minmaxes;
}

/*
 * 
 * **********************************************************
 * 
 * Author: K. Holcomb
 * 
 * Changelog: Modified from old student homework 20170410
 * 
 * 
 * **********************************************************
 * 
 */

#include <iostream>
#include <cmath>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include "birdData.h"

using namespace std;

int main(int argc, char *argv[])
{		
    ifstream inFile;
    string species;
    vector<birdData> birds;
    vector<int> years;
		
    float obs;
    inFile.open(argv[1]);
    if (inFile.is_open()) {		
	string line,header,yearString;
        int year;
	getline(inFile,line);
	stringstream yearStream(line);
	while (getline(yearStream,yearString,',')) {
                stringstream ssyear;
                ssyear<<yearString;
                if (ssyear>>year) {
		    years.push_back(year);
                }
	}
	//Dummy for storing species strings before writing to vector.
	string speciesDatum;
	while ( getline(inFile,line) ){
            stringstream lineStream(line);
            vector<string> obsVals;
            while (getline(lineStream,speciesDatum,',')) {
                obsVals.push_back(speciesDatum);
            }
            //Create a vector of bird instances.
	   string name=obsVals.at(0);
           vector<float> observations;
           for (int index=1;index<obsVals.size();++index){
	       stringstream obsString;
               obsString<<obsVals[index];
               obsString>>obs;
               observations.push_back(obs);
           }
        birds.push_back(birdData(name,observations));
        }
    }
    else {
        cout<<"Unable to open data file\n";
        return 1;
    }

    int numLines=birds.size();
    //Clip off last two lines
    birds.erase(birds.end()-1,birds.end());
    int numSpecies=numLines-2;


    string userInput;
    cout<<"Please enter the name of a bird species: ";
    cin>>userInput;
    int speciesIndex=-1;
    for (int i=0;i<numSpecies;i++) {
	if (birds[i].species_name()==userInput) {
            speciesIndex=i;
            break;
	}
    }
    if (speciesIndex==-1) {
	cout<<endl<<"No such species. Please start over."<<endl<<endl;
    }
    else {		
        float minVal, maxVal;
        int   minYear, maxYear;
	cout<<endl<<"The "<<userInput<<" species was observed an average of ";
        vector<float> birdStats=birds[speciesIndex].stats();
        float mean=birdStats[0]; float stdev=birdStats[1];
        cout<<mean<<" times, ";
	cout<<"with a"<<endl<<"standard deviation of "<<stdev;
        vector<float> yearObs=birds[speciesIndex].minmax(years);
        minVal=yearObs[0]; maxVal=yearObs[1];
        minYear=(int) yearObs[2]; maxYear=(int) yearObs[3];
	cout<<" a maximum of "<<maxVal<<" in year "<<maxYear;;
	cout<<", and a minimum of "<<minVal<<" in year "<<minYear<<".\n";
    }

    vector<float> means(numSpecies);
    for (int i=0;i<numSpecies;i++) {
	means[i]=birds[i].stats()[0];
    }
    int mostCommon=10;
    int tenCommonIndex=numSpecies-mostCommon;				

    vector<int> index(numSpecies);
    for (int i=0;i<numSpecies;++i) {
        index[i]=i;
    }

    sort(index.begin(), index.end(), [&](const int& a, const int& b) {
        return (means[a] < means[b]); });
			
    cout<<"The 10 most common species (in order of decreasing ";
    cout<<"prevalence) are:"<<endl;
    int j;
    for (int i=0;i<mostCommon;i++) {
        j=numSpecies-i-1;
        cout<<birds[index[j]].species_name()<<"    \t"<<means[index[j]]<<endl;
    }
    cout<<endl<<endl;

    return 0;

}

Previous
Next