GPA calculator/ adding outside a loop - c++

Greetings,
I'm just looking for a bit of help here. Here's the prompt:
For research purposes the admissions officers of your local university wants to know how well female and male students perform in certain courses. The user enters the number of courses to be considered. The student's data for each course is provided as a GPA followed by a letter code representing the gender of the student in this format: each line of input consists of a real number representing the student's GPA followed by the letter code f (for female students); m (for male students).
The number of entries (students) for each course is not known and the number 0.0 followed by the letter O indicates the end of data for specific course.
That being said, this is an introduction to c++ and as such; arrays, strings, and anything else outside of int, floats, doubles, and char is basically not allowed. In the code there needs to be the ability to type in various entries in any order (male entry followed by female and as well as the opposite.)
the issue i'm having is this, at the end of the program it is required to give an output of "General School Averages" which are sorted by female and male. I understand how to get the total in which to divide the problem, i just can't seem to get the sum. Anytime I try to get the sum, the value for the first course (first time through loop) is not kept so I can't figure out for the life of me how to do it. Any hints or assistance would be greatly appreciated. I know the code is long and kinda "brutish" so bear with me on that part. here's the code
//GPA calculator for Ghemri
//dealing with gpa range 0.0-4.0, set cap?
//try a do while loop
#include <iostream>
using namespace std;
int main(void)
{
int size, counter;
//int studentTotal= 0;
char gender;
double studentInfo,total,sum, avg;
double minRange = 0.0, maxRange = 4.0;
double maxGpa=0,gpaAvg,gpaSum;
double femaleSum, femaleAvg, femaleTotal;
double maleSum, maleAvg, maleTotal;
int femaleNumber,maleNumber, gpaNumber;
double sumFemaleAvg;// femaleGeneralAvg;//sumMaleAvg, maleGeneralAvg;
cout << "\nPlease enter the number of courses you want considered: ";
cin >> size;
while(size <=0)
{
cout << "\nInvalid entry, number of course must be greater than zero\n";
cin >> size;
}
//sumFemaleAvg+=femaleAvg;
for(int course =1; course <= size; course++)
{
maleTotal = 0;
femaleTotal=0;
total = 0;
femaleNumber = 0;
maleNumber = 0;
gpaNumber = 0;
maxGpa= 0;
gpaSum = 0;
//double doubleArray[course] = {femaleAvg};
cout << "\nEnter student information(0.0 O to end):\t";
cin >> studentInfo >> gender;
while(studentInfo < minRange || studentInfo > maxRange)
{
cout << "\nInvalid entry, try again...\n";
cout << "Enter student's information(0.0 O to end): \t";
cin >> studentInfo >> gender;
}
if(studentInfo > maxGpa)
{
maxGpa=studentInfo;
}
if(studentInfo > 3.00)
{
gpaSum=studentInfo;
gpaNumber=1;
}
if(gender == 'f' && studentInfo > minRange && studentInfo < maxRange)
{
femaleNumber=1;
femaleSum = studentInfo;
maleSum=0;
}
if(gender == 'm' && studentInfo > minRange && studentInfo < maxRange)
{
maleNumber=1;
maleSum = studentInfo;
femaleSum=0;
}
sum =studentInfo;
counter = 0;
counter++;
while(studentInfo != 0.0 && gender != 'O')
{
cout << "Enter student information(0.0 O to end):\t";
cin >> studentInfo >> gender;
if(studentInfo > maxGpa)
{
maxGpa=studentInfo;
}
if(studentInfo < minRange || studentInfo > maxRange)
{
cout << "\nInvalid entry, try again...\n";
cout << "Enter student's information(0.0 O to end): \t";
cin >> studentInfo >> gender;
}
if(gender != 'm' && gender !='f'&& gender != 'O')
{
cout << "Invalid entry, enter m for male or f for female\n";
cout << "Enter student's information(0.0 O to end): \t";
cin >> studentInfo >> gender;
}
sum +=studentInfo;
total+=counter;
avg = sum/total;
if(studentInfo > 3.00)
{
gpaSum+=studentInfo;
gpaNumber++;
gpaAvg= gpaSum/gpaNumber;
}
if(gender == 'f' || gender =='F')
{
femaleSum+=studentInfo;
femaleNumber++;
//femaleTotal+=femaleNumber;
femaleAvg = femaleSum/femaleNumber;
//sumFemaleAvg = femaleAvg;
}
if(gender == 'm' || gender == 'M')
{
maleSum+=studentInfo;
maleNumber++;
//maleTotal+=maleNumber;
maleAvg = maleSum/maleNumber;
}
if(studentInfo == 0 && gender == 'O')
{
cout << "\nResults for course "<< course<<":\n";
cout << "Female Student Average\t Male Student Average\n";
cout << "\t";
if(femaleNumber==0)
{
cout<< "N/A" << "\t\t\t";
}
else
{
cout<< femaleAvg <<"\t\t\t";//femaleAvg
}
if(maleNumber==0)
{
cout << "N/A\n";
}
else
{
cout<<maleAvg << endl;
//sumMaleAvg = maleAvg;
}
cout << "\nHighest GPA: " << maxGpa<<endl;
cout << "Highest average GPA for course "<< course << ": "<< gpaAvg<< endl;
}
}
sumFemaleAvg = femaleAvg;
}
/*double genAvg[]={femaleAvg};
result+=genAvg[course];*/
sumFemaleAvg+=femaleAvg;
cout<< "this is a test for the value sum " << sumFemaleAvg<<endl;
//cout<< "this is another test " << result <<endl;
//maleGeneralAvg = sumMaleAvg/course;
/*cout << "the sum is " << sumFemaleAvg<<endl;
cout << "the other sum is "<< sumFemaleAvg2<<endl;
cout << "the other other sum is " << femaleAvg;*/
return 0;
}

Try to avoid extreme repetition and factor common operations into functions. I'll "bear with you" for now, but really there's no reason I should. This is the first thing you need to learn as a programmer.
It looks like the variable sumFemaleAvg is supposed to be summed over loop iterations. However the line sumFemaleAvg = femaleAvg; overwrites the variable every time. Do
sumFemaleAvg += femaleAvg;
and likewise for other variables you wish to add up over multiple iterations.

Related

Bookshelf Data Structures Issues

I am making a bookshelf of width size s(1<s<100). Add book id and the book width at the leftmost of the vector. If you add a book which causes the width to be exceeded, then delete the rightmost book until the book to be added can be put on the shelf. In the end, the remaining books on the bookshelf can be added.
The issue I am facing that when var = 'E' the program should display the remaining books on the shelf and then exit that problem and go to a different problem, but when 'E' is entered the remaining books on the shelf will not display, and the program will not exit. I have tried messing with the while loops condition that is nested in the overall while loop.
#include <iostream>
#include <vector>
using namespace std;
struct book{
int id;
int w;
};
int main(){
//std::vector::~vector
//create instance of book
book my_book;
//initialize the placeholders
int s, removed_book, back_width;
char var;
//create the vector
vector<book>shelf;
while(true){
//enter the s value
s = 0;
cout << "enter the s value: " << endl;
cin >> s;
int w_total = 0;
//be able to exit the program
if(s == -1){
return 0;
}
int x = 1;
//while remaining space
while(x!=0){ //need to fix this up
cout << "enter the action(A,R,E): " << endl;
cin >> var >> my_book.id >> my_book.w;
//if A
if(var == 'A'){
//get info about the book
/*
cout << "enter id: " << endl;
cin >> my_book.id;
cout << "width(w): " << endl;
cin >> my_book.w;
*/
w_total += my_book.w;
shelf.insert(shelf.begin(),my_book);
cout << "total width(1): " << w_total << endl;
if(w_total > s){
while(w_total >= s){
//remove the rightmost(back) book
w_total = w_total - shelf.back().w;
cout << "total width(2): " << w_total << endl;
shelf.erase(shelf.end()-1);
}
}
}
//if R
else if(var == 'R'){
//cout << "which book to be removed? : " << endl;
//cin >> removed_book;
removed_book = my_book.id;
for(int i = 0; i < s; i++){
if(shelf[i].id == removed_book){
shelf.erase(shelf.begin()+i);
}
}
}
//if E
else if(var == 'E'){
cout << "remaining books on shelf: " << endl;
for(int i = 0; i < shelf.size(); i++){
if(shelf[i].id!=0){
cout << "id: "<<shelf[i].id << endl;
}
}
//maybe put the display in here?
x = 1;
}
}
//print out the remaining shelf
shelf.clear();
//erase the shelfs(vectors) contents
//increase problem number
}
return 0;
}
Expected output:
10(shelf width)
A 1 3(Add id width)
A 2 5
E
-->PROBLEM 1: 2 1
cin >> var >> my_book.id >> my_book.w is asking the user to enter three things: a character and two integers. You have to enter all three before the action in var will be checked and acted upon.

Looping assignment in C++

My assignment is utilizing loops. The program should accept input for the sales of 3 employees (Mary, Tom, and Chris). The flow should be as follows:
Initial? > number of sales to enter > enter sale amounts > display commission for sale at 17% > adds commission and sales to the respective variables >> continue until 'z' is input for inputSalesPerson >> display information
So I am trying to figure out why my return value for the tempComm variable isn't returning the correct value. If i was to enter 't' for variable inputSalesPerson it puts me into the switch case 't' no problem. Input number of sales and that works. But when I get to entering the salesAmount and then displaying commission it will not calculate correctly.
Also if I enter 'z' or 'Z' as the inputSalesPerson it will not end the program. I have a lot to go on this.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
int salesT = 0, salesC = 0, salesM = 0;
double amountT = 0, amountC = 0, amountM = 0;
double commT = 0, commC = 0, commM = 0;
double commRate = (17/100);
int num_sales;
double salesAmount, totalSales, tempComm;
char inputSalesPerson;
do
{
cout << "Enter the sales person's initial (\"Z\" to quit): ";
cin >> inputSalesPerson;
while(inputSalesPerson != 't' && inputSalesPerson != 'T' && inputSalesPerson != 'm' && inputSalesPerson != 'M' && inputSalesPerson != 'c' && inputSalesPerson != 'C' && inputSalesPerson != 'z' && inputSalesPerson != 'Z')
{
cin.get();
system("cls");
cout << "Invalid input for employee. Please Input (T)om, (C)hris, (M)ary, or (Z) to End : ";
cin >> inputSalesPerson;
}
switch(inputSalesPerson)
{
case 't' :
case 'T' :
system("cls");
cout << "Enter the number of sales : ";
cin >> num_sales;
while(num_sales < 1 || num_sales > 5)
{
system("cls");
cout << "Invalid number of sales. Please enter a value between 1 and 5 : ";
cin >> num_sales;
}
salesT += num_sales;
for(int i = 0; i<num_sales; i++)
{
cin.get();
system("cls");
cout << "Enter the sale amount : ";
cin >> salesAmount;
while(salesAmount < 0)
{
cin.get();
system("cls");
cout << "Invalid sale amount. Please enter a positive amount : ";
cin >> salesAmount;
}
tempComm = salesAmount + (salesAmount * commRate);
cout << fixed << setprecision(2) << "Commission earned by tom on this sale is : " << tempComm << endl;
cin.get();
amountT += salesAmount + tempComm;
commT += tempComm;
totalSales += amountT;
}
break;
}
}while(inputSalesPerson != 'z' || 'Z');
return 0;
}
****EDIT****
Thank you for the information on single-step debugging. Thanks to that comment I was able to learn about using the debugging tool more in depth and that helped me get everything working a bit better.
I've commented your code at the areas that need fixing. Also, there's a problem with using cin.get() all over the place. I assume that you do this to discard the return character after each input. But if the standard input (cin) is empty when you call cin.get() it will block the program until something is input. This is what happens when you enter more than one num_sales:
for (int i = 0; i<num_sales; i++)
{
cin.get();
It handles the first fine, but on the second loop you get:
Enter the sale amount : 20
Commission earned by tom on this sale is : 23.40
// cin.get() blocks here, with no user instructions to enter the next sale amount
I've commented out all the cin.get(). It will still work the same because the cin operator >> discards whitespaces and newlines, so even if there is a \n newline character still in the buffer, the next time you do something like cin >> num_sales it will discard the newline anyway.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
int salesT = 0, salesC = 0, salesM = 0;
double amountT = 0, amountC = 0, amountM = 0;
double commT = 0, commC = 0, commM = 0;
double commRate = (17 / 100.0); // Int divided by int will round to an int.
// commRate is 0.0. Divide by double instead (17 / 100.0)
int num_sales;
double salesAmount, totalSales = 0, tempComm; // totalSales needs to be initialised to
// zero, otherwise it holds a garbage value.
char inputSalesPerson;
do
{
cout << "Enter the sales person's initial (\"Z\" to quit): ";
cin >> inputSalesPerson;
while (inputSalesPerson != 't' && inputSalesPerson != 'T' && inputSalesPerson != 'm' && inputSalesPerson != 'M' && inputSalesPerson != 'c' && inputSalesPerson != 'C' && inputSalesPerson != 'z' && inputSalesPerson != 'Z')
{
//cin.get();
system("cls");
cout << "Invalid input for employee. Please Input (T)om, (C)hris, (M)ary, or (Z) to End : ";
cin >> inputSalesPerson;
}
switch (inputSalesPerson)
{
case 't':
case 'T':
system("cls");
cout << "Enter the number of sales : ";
cin >> num_sales;
while (num_sales < 1 || num_sales > 5)
{
system("cls");
cout << "Invalid number of sales. Please enter a value between 1 and 5 : ";
cin >> num_sales;
}
salesT += num_sales;
for (int i = 0; i<num_sales; i++)
{
//cin.get();
//system("cls");
cout << "Enter the amount for sale number " << i+1 << ": ";
cin >> salesAmount;
system("cls"); // I would put the clear here,
// Otherwise the user can't see the commission made by Tom
while (salesAmount < 0)
{
//cin.get();
system("cls");
cout << "Invalid sale amount. Please enter a positive amount : ";
cin >> salesAmount;
}
tempComm = salesAmount + (salesAmount * commRate);
cout << fixed << setprecision(2) << "Commission earned by tom on this sale is : " << tempComm << endl;
//cin.get();
amountT += salesAmount + tempComm;
commT += tempComm;
totalSales += amountT; // I think you mean to add salesAmount maybe?
}
break;
}
} //while (inputSalesPerson != 'z' || 'Z');
// Even if { this ^^^^} is false, ^^^ this is always
// 'Z' char will convert to bool, any non-zero value is true.
while (inputSalesPerson != 'z' && inputSalesPerson != 'Z');
return 0;
}

Call array storing string type from one while to another

How to fix the code? I can't use vectors. I need to be able to call the names for the courses from the first while to the second one and display them.
cout << "Please enter the number of classes"<< endl;//Number of classes for the while
cin >> nclass;
while (count <= nclass ) // while
{
//Information for the class
{
cout << "Please enter the course name for the class # "<< count << endl;
getline (cin, name);
string name;
string coursename[nclass];
for (int i = 0; i < nclass; i++) {
coursename[i] = name;
}
}
char choose;
cin >> choose;
while ( choose == 'B' || choose == 'b') {//Name the courses
for (int x = 0; x < nclass; x++){
cout << "Here is a list of all the courses: \n" << coursename[i] << endl;
}
return 0 ;
}
you are declaring coursename as local inside loop and then using it outside so you get a compile time error (coursename is undeclared identifier).
one question: what is the role of inner for-loop????!!!
you use a for loop inside while loop through which you are assigning all the elements the same value as the string name has!!!
so every time count increments the inner for loop assigns the new value of name after being assigned, to the all elements of coursename.
count is undefined! so declare it and initialize it to 1 or 0 and take this in mind.
you wrote to the outbounds of coursname: count <= nclss to correct it:
while(count < nclass)...
another important thing: clear the input buffer to make cin ready for the next input. with cin.ignore or sin.sync
cout << "Please enter the number of classes"<< endl;//Number of classes for the while
cin >> nclass;
string coursename[nclass];
int count = 0;
while (count < nclass ) // while
{
//Information for the class
string name;
cout << "Please enter the course name for the class # "<< count << endl;
cin.ignore(1, '\n');
getline (cin, name);
coursename[count] = name;
cin.ignore(1, '\n');
count++;
}
char choose;
cin >> choose;
while ( choose == 'B' || choose == 'b') {//Name the courses
for (int x = 0; x < nclass; x++){
cout << "Here is a list of all the courses: \n" << coursename[x] << endl;
}
This code works!
#include <iostream>
#include <string>
using namespace std;
int main()
{
int nclass = 0, count = 1, countn = 1;
string name[100];
cout << "Please enter the number of classes" << endl;
cin >> nclass;
while (count <= nclass) {
cout << "Please enter the course name for the class # " << count << endl;
cin >> name[count];
count++;
}
cout << "Here is a list of all the courses: " << endl;
while (countn <= nclass) {
cout << name[countn] << endl;
countn++;
}
return 0;
}
Note that gave the array "name" the size of 100. Nobody is going to have 100 classes! There is no need for the for loops. It is a good practice to initialize the count and the new count which is designated by countn. Why is my answer voted down when it works?

Nested loops in C++ and user input

Pretty new here to programming, and I have an assignment where I need to achieve the following:
ask for total amount of people
get each of their names
allow user to enter up to 5 scores for each person
if there are less than 5 scores for a given person, inputting -100 will stop it
So far I have written this:
#include <iostream>
using namespace std;
int main() {
string personName;
int totalPerson, personScoreCounter;
double personGrade, personGradeTotal;
cout << "Input total amount of people: ";
cin >> totalPerson;
for (int person = 1; person <= totalPerson; person++)
{
cout << "Input name for person " << person << ": ";
getline(cin, personName);
cin.ignore();
while ( (personGrade != -100) && (personScoreCounter <= 5) )
{
cout << "Input up to 5 scores for " << personName << " (-100 to end): ";
cin >> personGrade;
if (personGrade >= 0 && personGrade <= 100) // valid range of scores
{
personGradeTotal += personGrade;
personScoreCounter++;
}
else
{
cout << "Input only scores from 0-100" << endl;
}
cout << "Input up to 5 scores for " << personName << " (-100 to end): ";
cin >> personGrade;
}
}
// calculate averages and other stuff in here.
return 0;
}
After getting their name, only the last cout inside the while loop seems to execute first, then it starts from the top and so on until the for loop hits the end depending on totalPerson. I know I'm missing a few things in here, probably in the order of operations and also the way I am executing my loops, but I just can't see it. Could any of you guys with experience in the language please give me any pointers as to what's happening here and how I can fix it? Thank you.
Inside your while group, you only want to use your cout line once (at the beginning looks good).
Your first check should be for ==-100 or similar, since as it is now, you'll get a "Input only scores from 0 to 100" message if you enter -100.
You should keep a cin.ignore(); call after each use of cin >> VARIABLE, since then you will drop the EoL character.
Example code:
#include <iostream>
using namespace std;
int main() {
int totalPerson;
cout << "Input total number of people: ";
cin >> totalPerson;
cin.ignore();
for (int person = 1; person <= totalPerson; person++)
{
int personScoreCounter=0;
double personGrade = -1, personGradeTotal=0;
string personName;
cout << "Input name for person " << person << ": ";
std::getline(cin, personName);
while ( (personGrade != -100) && (personScoreCounter < 5) )
{
cout << "Input up to 5 scores for " << personName << " (-100 to end): ";
cin >> personGrade;
cin.ignore();
if (personGrade == -100) {
break;
} else if (personGrade >= 0 && personGrade <= 100) {
personGradeTotal += personGrade;
personScoreCounter++;
} else {
cout << "Input only scores from 0-100" << endl;
}
}
// calculate averages and other stuff in here.
double avg = personGradeTotal / personScoreCounter;
cout << "Avg = " << avg << endl;
}
return 0;
}
Some of your variables also needed to move inside the for loop.
Additionally I changed the limits on the personScoreCounter to [0:4] rather than [1:5] - this way you can use it for averaging more easily.
You might also try cin.getline() instead of getline(std::cin , ... ):
int max_length = 30;
std::cin.getline(personName, max_length, '\n'); // \n is option termination.
This allows whitespaces in the input also.
http://www.cplusplus.com/reference/istream/istream/getline/

How to differentiate scores between names using functions

I am trying to make a talent show type voting program using functions.
I have the majority of it figured out. The program prompts you to enter a name, followed by five scores, if you type "Done" rather than a name, it will close. I'm using functions for a majority of the code to practice with them.
My big issue is that there could be an infinite amount of names (as many as the user enters) and I am unaware on how to add up all 5 scores per name, I do not know how to differentiate between them. The 5 scores will be averaged and the person with the highest average of (3 scores, dropping 2) will be the winner.
Side Note: I need to drop the highest and lowest score of each person, I believe I could figure it out but an example with a function of this would be helpful to someone who is new to them.
I've researched this a lot but I could not find any examples that are similar enough to mine (having a possibly infinite amount of contestants.)
Here is my code so far, the function at the bottom is me messing around with functions to get a hang of them and see if i can get any sums of scores from a name.
#include <iostream>
#include <string>
using namespace std;
void validCheck();
void calcAvgScore();
void findHigh();
void findLow();
int main(){
int judge = 1;
double score = 0;
string name;
while (name != "done" || name != "Done"){
cout << "Enter Contestant Name, if no more, type 'done': ";
cin >> name;
if (name == "done" || name == "Done"){ break; }
for (judge = 1; judge < 6; judge++){
cout << "Enter score " << judge << " ";
validCheck();
}
}
system("pause");
return 0;
}
void validCheck(){
double score;
cin >> score;
if (score < 1 || score > 10){
cout << "Please Enter a score between 1 and 10: ";
cin >> score;
}
}
void calcAvgCheck(){
double score = 0, value = 0;
static int average;
score += value
}
Declare a string "winner", double "win_avg", double "avg" outside the while loop.
Have your validCheck() return the double value given as input (named score).
Declare a double array before your for loop (double[5] scores). Store each value returned from validCheck() into the array).
Call std::sort(std::begin(scores), std::end(scores)) to sort your scores ascending. Find the average (ignoring the max and min), and hold the max average as well as the names of the person with the max average.
#include <algorithm> // std::sort
...
double validCheck();
...
int main(){
string name;
string winner;
double win_avg;
double avg;
while (name != "done" || name != "Done"){
cout << "Enter Contestant Name, if no more, type 'done': ";
cin >> name;
double scores[5];
if (name == "done" || name == "Done"){ break; }
for (int judge = 0; judge < 5; ++judge){
cout << "Enter score " << judge << " ";
scores[judge] = validCheck();
}
std::sort(std::begin(scores), std::end(scores));
for(int score = 1; score < 4; ++score)
avg += scores[score];
avg /= 3;
if(avg > win_avg) {
winner = name;
win_avg = avg;
}
avg = 0;
}
std::cout << "Winner is: " << winner << "\n";
}
double validCheck(){
double score;
cin >> score;
if (score < 1 || score > 10){
cout << "Please Enter a score between 1 and 10: ";
cin >> score;
}
return score;
}
If you want to find the average in a function and return the value you can do this
double calcAvgCheck(const double& scores[5]) {
double avg = 0.0;
for(int score = 1; score < 4; ++score)
avg += scores[score];
avg /= 3;
return avg;
}