Программа САТ результат чтения


Эта программа занимает 10 математика баллы и 10 устных баллы от пользователя, вычисляет стандартное отклонение и средние, а затем отображает их в табличном формате. После этого, он отображает их пользователю и отправляется в текстовый файл. Я не делал входных несоответствие обращения в довольно некоторое время, так что я использовал методы, которые вы видите внизу.

#include <cstdlib>
#include <iostream>
#include <iomanip> 
#include <string>
#include <fstream>
#include <cmath>
#include <cctype>

using namespace std;

/**
 * 
 * @return 0
 */
int main() 
{
    int sat[10][2], mathAvg, verbAvg;
    double mathStd, verbStd;

    void describe_program();
    void read_scores(int sat[10][2]);
    void compute_means(int sat[10][2], int& mathAvg, int& verbAvg);
    void compute_std(int sat[10][2],int mathAvg, int verbAvg, double& mathStd, double& verbStd) ;
    void show_results(int sat[10][2], int mathAvg, int verbAvg, double mathStd,  double verbstd);
    bool again();

    describe_program();

    do
    {
    read_scores(sat);
    compute_means(sat, mathAvg, verbAvg);
    compute_std(sat, mathAvg, verbAvg,  mathStd, verbStd);
    show_results(sat, mathAvg, verbAvg, mathStd, verbStd);
    }while(again());
    return 0;
}

/**
 * 
 */
void describe_program()
{
    cout<<"This program reads SAT scores from 10 students (Math and verbal scores)"
        <<" and allocates the scores as elements inside a two dimensional array."
        <<endl<<"The program will then calculate the mean Math SAT score, the mean "
        <<"Verbal SAT score, and the standard deviation for both subjects."<<endl<<
        "The results will be sent to the user in a tabular format and will then "
        <<"be sent to text file."<<endl; 
}

/**
 * 
 * @param sat
 */
void read_scores(int sat[10][2])
{
    for(int i = 0; i<10;i++)
    {
        for(int j = 0; j<2; j++)
        {
            if(j == 0){
                cout<<"Enter Math score below:"<<endl;
            }

            else{
                cout<<"Enter Verbal Score below:"<<endl;
            }    


            cin>>sat[i][j];  
        }
    }
}

/**
 * 
 * @param sat
 * @param mathAvg
 * @param verbAvg
 */
void compute_means(int sat[10][2], int& mathAvg, int& verbAvg)
{
    int mathScoreSum =0;
    int mathCount = 0;
    int verbScoreSum = 0;
    int verbCount = 0;

    for(int i = 0; i<10; i++)    
    {
        for(int j = 0; j<2; j++)
        {
            if(j==0){
                mathScoreSum += sat[i][j];
                mathCount++;
            }

            else{
                verbScoreSum += sat[i][j];
                verbCount++;
            }
        }
    }
    mathAvg = mathScoreSum / mathCount;
    verbAvg = verbScoreSum / verbCount;
}

/**
 * 
 * @param sat
 * @param mathAvg
 * @param verbAvg
 * @param mathStd
 * @param verbStd
 */
void compute_std(int sat[10][2],int mathAvg, int verbAvg, double& mathStd, double& verbStd) 
{
    double mathVariance = 0;
    double verbVariance = 0;

    for(int i = 0; i<10; i++)    
    {
        for(int j = 0; j<2; j++)
        {
            if(j==0){
                mathVariance += ::pow((sat[i][j] - mathAvg), 2);
            }

            else{
                verbVariance += ::pow((sat[i][j] - mathAvg), 2);
            }

            mathStd = sqrt(mathVariance/9);
            verbStd = sqrt(verbVariance/9);
        }
    }
}

/**
 * 
 * @param sat
 * @param mathAvg
 * @param verbAvg
 * @param mathStd
 * @param verbStd
 */
void show_results(int sat[10][2], int mathAvg, int verbAvg, double mathStd, double verbStd)
{ 
    cout<<fixed<<showpoint<<setprecision(1);
    cout<<setw(13)<<"MATH"<<setw(13)<<"VERBAL"<<endl;
    for(int i = 0; i<10;i++)
    {
        for(int j = 0; j<2;j++)
        {
            if(j==0){
                cout<<setw(13)<<sat[i][j];
            }else{
                cout<<setw(13)<<sat[i][j]<<endl;
            }
        }
    }
    cout<<"MEAN"<<setw(9)<<mathAvg<<setw(13)<<verbAvg<<endl;
    cout<<"STD"<<setw(10)<<mathStd<<setw(13)<<verbStd;

    ofstream outs;
    outs.open("scores.txt",ios::app);

    outs<<fixed<<showpoint<<setprecision(1);
    outs<<setw(13)<<"MATH"<<setw(13)<<"VERBAL"<<endl;
    for(int i = 0; i<10;i++)
    {
        for(int j = 0; j<2;j++)
        {
            if(j==0){
                outs<<setw(13)<<sat[i][j];
            }else{
                outs<<setw(13)<<sat[i][j]<<endl;
            }
        }
    }
    outs<<"MEAN"<<setw(9)<<mathAvg<<setw(13)<<verbAvg<<endl;
    outs<<"STD"<<setw(10)<<mathStd<<setw(13)<<verbStd<<endl;
    outs.close(); 
}

/**
 * 
 * @return Bool variable
 */
bool again()
{
    char response;

    cout<<endl<<"Do you wish to run this program again (Y or N)?"<<endl;
    cin>>response;     

    while((response!= 'N') && (response!= 'Y') && (response!= 'y') &&
          (response!= 'n')){
        cout<<"Please enter a valid response";
        cin>>response;
    }

    response = toupper(response);

    if(response == 'Y')
        return true;
    else
        return false;    
}


175
6
задан 21 февраля 2018 в 10:02 Источник Поделиться
Комментарии
3 ответа

Вот несколько вещей, которые я вижу:

Объявления Функций:

void describe_program();
void read_scores(int sat[10][2]);
void compute_means(int sat[10][2], int& mathAvg, int& verbAvg);
void compute_std(int sat[10][2],int mathAvg, int verbAvg, double& mathStd, double& verbStd) ;
void show_results(int sat[10][2], int mathAvg, int verbAvg, double mathStd, double verbstd);
bool again();

Зачем вам объявлять функции внутри main? Функция protypes обычно держались за пределами mainпоскольку они мешают меньше с логикой кода.


Сырые Многомерные Массивы

Используя сырье многомерные массивы-это плохо, так как они легко распадаются на указатели и не знать свой размер. Рассмотрите возможность реализации собственного матрицы класса, или идти с вложенной std::array/std::vector.

Другое дело у меня вопрос, почему вы даже с помощью многомерного массива. Две серии данных не держит тот же результат, так что я выберу двух разных std::vectorдля каждого набора оценок. Это позволит вам упростить свои функции немного, хотя вам придется звонить два раза.


Использование endl

Я заметил, что вы добавляете endl когда вы хотите новую строку. Остерегайтесь, хотя, это также сбрасывает выходные с ним, которые могли бы негативно сказываться на производительности. Рассмотреть вопрос о переходе к \n.


::pow

Еще одна причина, почему using namespace std; считается плохой практикой.


Рефакторинг show_results()

Глядя на вашу функцию show_results:

void show_results(int sat[10][2], int mathAvg, int verbAvg, double mathStd, double verbStd)
{
cout<<fixed<<showpoint<<setprecision(1);
cout<<setw(13)<<"MATH"<<setw(13)<<"VERBAL"<<endl;
for(int i = 0; i<10;i++)
{
for(int j = 0; j<2;j++)
{
if(j==0){
cout<<setw(13)<<sat[i][j];
}else{
cout<<setw(13)<<sat[i][j]<<endl;
}
}
}
cout<<"MEAN"<<setw(9)<<mathAvg<<setw(13)<<verbAvg<<endl;
cout<<"STD"<<setw(10)<<mathStd<<setw(13)<<verbStd;

// ... Basically the same thing for a file
}

Это сразу заметно, что вы повторяете себя для выхода в консоль и вывод в файл. Вместо этого я изменить функцию так, чтобы она занимала std::ostream в качестве параметра и отправляет весь вывод в этот поток. Затем, в mainвы можете позвонить show_results() дважды, один раз на стандартный вывод, и один раз на дескриптор файла. Вот как мне бы реализовать это изменение:

void show_results(const ostream& out, int sat[10][2], int mathAvg, int verbAvg, double mathStd, double verbStd)
{
out<<fixed<<showpoint<<setprecision(1);
out<<setw(13)<<"MATH"<<setw(13)<<"VERBAL"<<endl;
for(int i = 0; i<10;i++)
{
for(int j = 0; j<2;j++)
{
if(j==0){
out<<setw(13)<<sat[i][j];
}else{
out<<setw(13)<<sat[i][j]<<endl; // Make sure to replace your endls
}
}
}
out<<"MEAN"<<setw(9)<<mathAvg<<setw(13)<<verbAvg<<endl;
out<<"STD"<<setw(10)<<mathStd<<setw(13)<<verbStd;
}


Рефакторинг Условное

if(response == 'Y')
return true;
else
return false;

Можно заменить:

return response == 'Y';

3
ответ дан 21 февраля 2018 в 11:02 Источник Поделиться


  • using namespace std; Это плохая практика

  • Повторов внутри for(int j = 0; j<2; j++) петли нарушать принцип DRY. Ты будешь в лучшей форме, вычислительных средств и средние отдельно для каждого балла (добавить физ СБ вам нужно отредактировать каждую функцию). Рефакторинг вдоль линий

    int compute_mean(int sat[10]);
    double compute_std(int sat[10], int mean);
    ....

    называя их по каждому предмету.


  • mean должно быть double. Округление означает целое число серьезно погрешности отклонения. Вы можете вокруг него при печати.

  • В

    if(response == 'Y')
    return true;
    else
    return false;

    это долгий путь, чтобы сказать

    return response == 'Y';

3
ответ дан 21 февраля 2018 в 11:02 Источник Поделиться

Можно также уменьшить длительность вычислений средних значений, используя лямбда-выражения, как и С ниже вектора:

std::vector<int> v = { 1, 2, 3, 4, 2314, 6, 7, 8, 9, 10 };
auto lambda = [&](double a, double b){return a + b / v.size(); };
double avg = std::accumulate(v.begin(), v.end(), 0.0, lambda);

0
ответ дан 1 марта 2018 в 09:03 Источник Поделиться