What do you plan to do if a class doesn't grade like this? I've had classes where each assignment, test, and quiz had its own weight. Are you just going to make each its own category? Note that you'll have to calculate the percentages prior to entering the data here. Unfortunately, not every professor will return grades in the form of percentages.
If I had this as a task, I think that I'd just use a spreadsheet for it. A spreadsheet already has the relevant computing capacity and is very flexible in the face of arbitrary rules. It also supports saving, which this program doesn't. You'll have to enter the categories and such every time you use the program. With a spreadsheet, you'd save and would just need to update as grades arrive.
All that said, for learning purposes, I'm going to go over the code that you have.
string categories[10];
int percent[10];
This looks risky. The fact that you are using 10 in two places suggests that it has special significance. If so, you should declare a constant to hold the value:
const int MAX_CATEGORIES = 10;
Another problem is that you apparently want categories and percents to be linked, one percent per category. So the C++ way to handle this is to make a class, but in this case, let's make a struct instead:
struct Category {
public std::string name;
public float percentOfGrade;
We use a struct because I'm not up to explaining classes in an answer. Anyway, now you can just declare one array rather than two (yes, std::vector would be better, but it would bypass some of the things that I want to criticize).
Category categories[MAX_CATEGORIES];
Notice that categories is plural. I use this to tell me that categories refers to a collection of objects. If I were referring to just one category, I'd use a singular name.
Let's continue looking at your code:
int totalPoints[50];
int totalItems[50];
OK, first we have the same problem as before. It looks like 50 has some significance, so we want to make it a constant, say MAX_ITEMS_PER_CATEGORY. However, looking at your code, totalItems is an array showing how many items in a category. That suggests that it should not have MAX_ITEMS_PER_CATEGORY entries. In fact, we should add it to the category struct:
public int numberOfItems;
};
Note that I renamed it. I don't like totalItems
as a name because total is singular but you're defining an array. I would expect something named total to be the sum of the items or something like that.
I'm going to leave off describing what to do with totalPoints, as you haven't written code using it. Again though, I don't like the name.
cout << "How many grade categoies do you have: ";
Note that categories is misspelled there. Also, you probably should have written std::cout`` rather than plain
cout`.
for(int i = 1; i <= a; i++)
{
cout << "Enter the category title: ";
cin >> categories[i];
}
for(int i = 1; i <= a; i++)
{
cout << "Enter the total percentage for " << categories[i] << ": ";
cin >> percent[i];
}
for(int i = 1; i <= a; i++)
{
cout << "How many items are there for " << categories[i] << ": ";
cin >> totalItems[i];
}
First, why do three for
loops when one would do? Avoid things where two or more parts of your program have to synchronize. These lead to bugs as synchronicity is hard to maintain.
Second, C++ arrays are zero-indexed. You're starting with 1 but should be starting with 0. The end changes as well. Note the <
where there was a <=
.
for ( int i = 0; i < numberOfCategories; i++ ) {
std::cout << "Enter the category title: ";
std::cin >> categories[i].name;
std::cout << "Enter the total percentage for " << categories[i].name << ": ";
std::cin >> categories[i].percent;
std::cout << "How many items are there for " << categories[i].name << ": ";
std::cin >> categories[i].numberOfItems;
}
I also changed a
to numberOfCategories
for readability.
And of course, I started using the struct fields that we declared.
return 0;
You don't need to return
from main
at the end of execution. The compiler will handle this for you. Only return
if you need to do so early.
If you do explicitly return
, then do it as follows:
return EXIT_SUCCESS;
or
return EXIT_FAILURE;
This is cross-platform and doesn't rely on the OS understanding 0 the same as you do.
Note: I hinted at this previously, but I'll say it explicitly now. A class would be a better solution in general. I only skipped it because it's too complicated to explain. The struct solution is inferior but closer to how your existing code worked. Similarly, a std::vector would be a better data structure but is less like your current code. I prioritized critiquing your current code over restructuring it.
Another problem that I slid past is that you're doing no validation of your input. If someone enters input that doesn't fit, you should either handle it or abort the program. For example, if numberOfCategories
is greater than MAX_CATEGORIES
, you will get a runtime error when adding the first extra category.
std::vector
. It'll allow you to create an array of any size during runtime, which will also do the deallocation itself. \$\endgroup\$