Простой калькулятор средний класс


Я бы хотела, чтобы этот код должен быть сведен к минимуму, а показывать так же.

В частности, о том, как убрать некоторые повторы, сделанные в коде (например, "если, то если") и т. д. с помощью других высказываний или делает компилятор пройти через это быстрее, как я чувствую, что мне не хватает опыта и знаний, чтобы делать это, не портя все (например, с помощью переключателя и корпус).

Например, когда я тест на "ТФ", я бы хотел, чтобы не быть вынужденными повторять "среднего" в зависимости от того, сможем ли мы добавить "Теза" класс.


#include <iostream>
using namespace std;
int main()

{
    string sub, tf;
    int m1, m2, m3, m4, sum, TEZA;
    double avg, tzm;

    cout << "SIMPLE AVERAGE CALCULATOR";
    cout << "\n" << "\n" << "Subject at hand?: ";
    cin >> sub;
    cout << "\n" << "Input the FOUR marks you'd like verified: " << "\n";
    cout << "\n" << "M1: ";
    cin >> m1;
    cout << "\n" << "M2: ";
    cin >> m2;
    cout << "\n" << "M3: ";
    cin >> m3;
    cout << "\n" << "M4: ";
    cin >> m4;
    cout << "\n" << "Would you like to include the TEZA grade?(Y/N): ";
    cin >> tf;

    sum = m1 + m2 + m3 + m4;
    avg = (double) sum / 4;

    if (tf == "Y" | tf == "y")
    {
        cout << "What is the TEZA grade?: ";
        cin >> TEZA;
        int tzm = ((double) avg * 3 + TEZA) / 4;
        cout << "\n" << "Your average grade at " << sub << " is " << tzm << "\n"
             << "\n";

        cout << "You got the following mark: ";
        if (tzm >= 9 && tzm <= 10)
            cout << "A" << "\n";
        else if (tzm >= 8 && tzm <= 9)
            cout << "B" << "\n";
        else if (tzm >= 7 && tzm <= 8)
            cout << "C" << "\n";
        else if (tzm >= 6 && tzm <= 7)
            cout << "D" << "\n";
        else if (tzm >= 5 && tzm <= 6)
            cout << "E" << "\n";
        else if (tzm < 5)
            cout << "F" << "\n";

        if (tzm >= 5)
        {
            cout << "DO YOU PASS: " << "\n";
            cout << "Yes." << "\n";
        }
        else
            cout << "No." << "\n";
    }

    else

    {
        cout << "\n" << "Average at " << sub << " is " << avg << "\n" << "\n";

        cout << "You got the following mark: ";
        if (avg >= 9 && avg <= 10)
            cout << "A" << "\n";
        else if (avg >= 8 && avg <= 9)
            cout << "B" << "\n";
        else if (avg >= 7 && avg <= 8)
            cout << "C" << "\n";
        else if (avg >= 6 && avg <= 7)
            cout << "D" << "\n";
        else if (avg >= 5 && avg <= 6)
            cout << "E" << "\n";
        else if (avg < 5)
            cout << "F" << "\n";

        cout << "\n" << "DO YOU PASS?: " << "\n";

        if (avg >= 5)
            cout << "Yes." << "\n";
        else
            cout << "No." << "\n";

    }
}


Комментарии
2 ответа

Ошибка

Этот расчет выглядит подозрительно багги:


int tzm = ((double) avg * 3 + TEZA) / 4;

Почему ты принимаешь avg, который уже doubleи бросая его в double? Кроме того, зачем вы взяли с правой стороны, которая является doubleи принуждение его к int переменной? Обратите внимание, что вы заявили double tzm ранее в код; это int tzm объявления тени предыдущей декларации. Ваш компилятор должен предупредить вас, что tzm в строке 8 не используется. (Вы компиляции с включенной предупреждения, верно? Это хорошая привычка.)

В любом случае, вы должны написать комментарий, объясняющий, почему tzm формула так оно и есть. Я не понимаю расчета.

Кстати, вы можете сделать деление с плавающей запятой без явного кастинга, просто написав / 4.0.

Используя побитовое | оператор tf == "Y" | tf == "y" не совсем уместно; оно должно быть логичным || оператора.

Оптимизация

Нет абсолютно никакого смысла в оптимизации этого кода на производительности. Почти все время будет потрачено на ожидание ввода; расчеты тривиальны.

Что вы должны сделать, это оптимизировать его для красоты и удобочитаемости.

Ключ должен определить функциональность main() которые могут быть извлечены в функции, так что main() не имеет каких-либо трудоемких деталей. Например, общий шаблон печати вопрос, и ждет ответа от пользователя. Я бы определила три функции, чтобы запрашивать у пользователя строку, целое число, и да/нет ответов.

Я бы также определить letterGrade() функцию, так что все результаты могут быть представлены лишь одним заявлением.

Избежать загромождения кода с переменными, которые не много значат. Я бы избавиться от sum и tfк примеру. В tzm переменная-это просто перерасчет среднего рода, так что я бы избавиться от него.

Предлагаемое решение

#include <iostream>
#include <string>

std::string ask(const std::string& prompt) {
std::string answer;
std::cout << prompt;
std::cin >> answer;
return answer;
}

int askInt(const std::string& prompt) {
int answer;
std::cout << prompt;
std::cin >> answer;
return answer;
}

bool askYN(const std::string& prompt) {
std::string answer = ask(prompt);
return answer == "Y" || answer == "y";
}

std::string letterGrade(double grade) {
return (grade > 10) ? "" :
(grade >= 9) ? "A" :
(grade >= 8) ? "B" :
(grade >= 7) ? "C" :
(grade >= 6) ? "D" :
(grade >= 5) ? "E" : "F";
}

int main() {
std::cout << "SIMPLE AVERAGE CALCULATOR\n\n";
std::string subject = ask("Subject at hand?: ");

std::cout << "\nInput the FOUR marks you'd like verified:\n";
int m1 = askInt("\nM1: "),
m2 = askInt("\nM2: "),
m3 = askInt("\nM3: "),
m4 = askInt("\nM4: ");
double avg = (m1 + m2 + m3 + m4) / 4.0;

if (askYN("\nWould you like to include the TEZA grade?(Y/N): ")) {
int teza = askInt("What is the TEZA grade?: ");
avg = (3 * avg + teza) / 4.0;
}

std::cout << "\nYour average grade at " << subject << " is " << avg << "\n\n"
"You got the following mark:" << letterGrade(avg) << "\n"
"DO YOU PASS: " << (avg >= 5 ? "Yes." : "No.") << "\n";
}

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

Переменные инициализировать

Оба sum и avg может быть объявлен и инициализирован позже:

const int sum = m1 + m2 + m3 + m4;
const double avg = sum / 4.0;

Проверить границы if-else условия

У вас есть перекрывающиеся условия, напр.

 tzm >= 9 && <= 10

tzm >= 8 && <= 9

Последнее эффективно только tzm >= 8 && tzm < 9С tzm == 9 уже обрабатывается tzm >= 9 в первом состоянии.

Распределить

Если я дам вам int от 0 для 10вы можете распечатать класс. Это то, что мы можем положить в свою собственную функцию:

void print_grade(int mark) {
if(mark < 0 || mark > 10) {
std::cout << "Invalid score!\n";
return;
}

std::cout << "You got the following mark: ";

if(mark >= 9 ){
std::cout << "A";
} else if(mark >= 8 ){
std::cout << "B";
} else if(mark >= 7 ){
std::cout << "C";
} else if(mark >= 6 ){
std::cout << "D";
} else if(mark >= 5 ){
std::cout << "E";
} else {
std::cout << "F";
}
std::cout << "\nDO YOU PASS: \n";

if(mark >= 5) {
std::cout << "Yes.\n";
} else {
std::cout << "No.\n";
}
}

Теперь мы можем использовать

if (tf == "Y" || tf == "y")
{
std::cout << "What is the TEZA grade?: ";
std::cin >> TEZA;
int tzm = (avg * 3.0 + TEZA) / 4.0;
std::cout << "\n" << "Your average grade at " << sub << " is " << tzm << "\n"
<< "\n";
print_grade(tzm);
}
else
{
std::cout << "\n" << "Average at " << sub << " is " << avg << "\n" << "\n";

print_grade(avg);
}

Однако, вы можете также переписать print_grade как

void print_grade(int mark) {
static char const * const marks = "FFFFFEDCBAA";
if(mark < 0 || mark > 10) {
std::cout << "Invalid score!\n";
return;
}

std::cout << "You got the following mark: " << marks[mark] << "\n";
<< "DO YOU PASS: \n";

if(mark >= 5) {
std::cout << "Yes.\n";
} else {
std::cout << "No.\n";
}
}

Или вы можете использовать switch (упражнения). В любом случае, в итоге вам только нужно изменить один функция, а не две отдельных местах в коде. Вот урок, который вы должны держать в уме от этого небольшого упражнения.

Лучше использовать имена

Нет никаких причин сокращать subject для sub. Кроме того, я понятия не имею, что tf стенды для.

Использовать char вместо std::string для одиночных персонажей

Мы могли бы написать

char get_grade(int mark) {
static char const * const marks = "FFFFFEDCBAA";
if(mark < 0 || mark > 10) {
// Think of an "error" character.
return '\0';
}
returns marks[mark];
}

То же справедливо и для вашего tf.

Предпочитаю static_cast<type> в стиле c (type)забросы

Вместо (double) avg использовать static_cast<double>(avg). Или использовать с плавающей точкой литералы. Кстати, Ваш avg уже double, так что гипс не нужен.

Используя namespace std

Только использовать using namespace std; в игрушечных программ, и не в заголовках.

10
ответ дан 14 марта 2018 в 07:03 Источник Поделиться