Find average using a vector keeps displaying nan

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 1165 Views - Last Post: 12 January 2019 - 02:39 PM Rate Topic: -----

#1 albert003   User is offline

  • D.I.C Addict

Reputation: 22
  • View blog
  • Posts: 614
  • Joined: 15-December 14

Find average using a vector keeps displaying nan

Posted 27 December 2018 - 09:53 PM

Working on the exercises on chapter 3 and I can't figure out why it will only give the average when I do everything in the int main function. But, anytime I try and pass the variables to the average function it gives me the message -nan.

This is the simplified version just using main
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <numeric>
#include <vector>
typedef std::vector<double>grades;
int main()
{
    grades homework;
    std::string name;
    double number,input,avg;
    int x = 0;
    std::cout <<"How many grades do you want to input?." <<std::endl;
    std::cin >> number;
    for(int i = 0; i < number; i++)
    {
        std::cout << i+1 << " grade" << std::endl;
        std::cin >> input;
        homework.push_back(input);
    }
    std::cout << "Your grade average is:" <<std::endl;
    avg = accumulate(homework.begin(),homework.end(),0.0)/homework.size();
    std::cout << avg <<std::endl;
}



This is the actual program. When I run it, I don't get the average. Instead I get nan. I can't figure out why.
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <numeric>

typedef std::vector<double>grades;
void enter(grades homework,double number, double input,int x);
void average(std::string name, grades homework);
int main()
{
    grades homework;
    std::string name;
    double number,input,avg;
    int x = 0;
    std::cout << "What is the students first and last name:" <<std::endl;
    std::getline(std::cin,name);
    enter(homework,number,input,x);
    average(name,homework);
}
void enter(grades homework,double number, double input,int x)
{
    std::cout << "How many grades will you enter?" <<std::endl;
    std::cin >> number;
    //using a for loop
    for(int i = 0; i < number; i++)
    {
        std::cout << "What is the " << i+1 << " grade?." <<std::endl;
        std::cin >> input;
        homework.push_back(input);
    }
    /*//stored grades using while loop as well.
    while(x < number)
    {
        std::cout << "What is the " << x+1 << " grade?." <<std::endl;
        std::cin >> input;
        homework.push_back(input);
        x++;
    } n
    */
}
void average(std::string name, grades homework)
{
    double avg;
    std::cout <<std::endl;
    std::cout << name << "'s grade average is:" <<std::endl;
    avg = accumulate(homework.begin(),homework.end(),0.0)/homework.size();
    std::cout << avg <<std::endl;
}


This post has been edited by albert003: 27 December 2018 - 11:01 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Find average using a vector keeps displaying nan

#2 Salem_c   User is online

  • void main'ers are DOOMED
  • member icon

Reputation: 2279
  • View blog
  • Posts: 4,362
  • Joined: 30-May 10

Re: Find average using a vector keeps displaying nan

Posted 27 December 2018 - 11:01 PM

> But, anytime I try and pass the variables to the average function it gives me the message -nan.
You need to pass grades as a reference if you want any updates to the vector to be visible in main.

You're just updating a local copy; the instance in main is untouched.
Was This Post Helpful? 2
  • +
  • -

#3 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7361
  • View blog
  • Posts: 15,284
  • Joined: 16-October 07

Re: Find average using a vector keeps displaying nan

Posted 28 December 2018 - 04:50 AM

How you pass objects matters...

This:
void enter(grades homework,double number, double input,int x);
void average(std::string name, grades homework);




Should be this:
void enter(grades &homework,double number, double input,int x);
void average(const std::string &name, grades &homework);



Upon further consideration:
// wtf are passing those numbers?!?
// void enter(grades &homework,double number, double input,int x);
void enter(grades &homework);



Right, I'd lay this out like so:
#include <iostream>
#include <string>
#include <numeric>
#include <vector> // don't you need this?!?

typedef std::vector<double> grades;

std::string getName();
grades getHomework();
double getAverage(const grades &);
void showResults(const std::string &name, double average);

int main() {
    std::string name = getName();
    grades homework = getHomework();
    showResults(name, getAverage(homework));

    return 0;
}



Hope this helps.
Was This Post Helpful? 1
  • +
  • -

#4 albert003   User is offline

  • D.I.C Addict

Reputation: 22
  • View blog
  • Posts: 614
  • Joined: 15-December 14

Re: Find average using a vector keeps displaying nan

Posted 03 January 2019 - 05:44 PM

Thanks guys I see what you meant and corrected the mistake.

I forgot to include the #include<vector> when I copied and pasted the program here.

I figured it out, but I couldn't figure out two things in your skeleton example you gave me.

1. I couldn't figure out what I was suppose to do with line 9,14 and 15. I get that you defined the vector grades with homework in the program. I understand the other functions... getName is a string function that would return the students name, double getAverage would be where the student input their grades and it would be stored in the vector. The function getResults would be a void function because it would display the results of the information inputted.

Which leads me to my second question....

2. I wasn't sure what I was suppose to do with line 16. I get that I need to pass the variable arguments of name and homework to the function to show the results. Ive never seen that before and I tried troubleshooting it then looking online to see examples of what that was. I finally just gave up and solved it without using those three lines in your example.


#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
#include <numeric>

typedef std::vector<double>grades;
std::string getName(std::string &n);
double getAverage(grades& homework,double input);//const
void showResults(std::string &n,grades& homework);
int main()
{
    grades homework;
    double average,input;
    std::string name;
    getName(name);
    getAverage(homework,input);
    showResults(name,homework);
}
std::string getName(std::string &n)
{
    std::cout << "Enter your full name:" <<std::endl;
    std::getline(std::cin,n);
    std::cout <<std::endl;

    return n;
}
double getAverage(grades& homework, double input)
{
    std::cout << "Enter your grades.\n" << std::endl;
    for(int i = 0; i < 5; i++)
    {
        std::cout << i+1 << " grade." <<std::endl;
        std::cin >> input;
        homework.push_back(input);
    }
}
void showResults(std::string &n, grades& homework)
{
    double avg;
    std::cout << n << " Your average grade is:\n" <<std::endl;
    avg = accumulate(homework.begin(),homework.end(),0.0)/homework.size();
    std::cout << avg << std::endl;
}


Was This Post Helpful? 0
  • +
  • -

#5 ndc85430   User is offline

  • I think you'll find it's "Dr"
  • member icon

Reputation: 934
  • View blog
  • Posts: 3,741
  • Joined: 13-June 14

Re: Find average using a vector keeps displaying nan

Posted 03 January 2019 - 11:51 PM

View Postalbert003, on 04 January 2019 - 12:44 AM, said:

double getAverage(grades& homework, double input)
{
    std::cout << "Enter your grades.\n" << std::endl;
    for(int i = 0; i < 5; i++)
    {
        std::cout << i+1 << " grade." <<std::endl;
        std::cin >> input;
        homework.push_back(input);
    }
}



You still seem to be struggling with basic concepts, like functions. Why do you pass input to this function instead using a local variable (i.e. one declared inside the function)? You've also told the compiler that this function should return a double, but it doesn't. Since all the function does is populate homework, why isn't the return type void? Having said that, the function is called getAverage, so you'd think it should return a value. I wouldn't expect a function called that to be populating the container though - it should be given one and compute the average from it. In short, your code is very confusing and I suggest you stop and think about what you actually want to do in this function.

This post has been edited by ndc85430: 04 January 2019 - 01:12 AM

Was This Post Helpful? 1
  • +
  • -

#6 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7361
  • View blog
  • Posts: 15,284
  • Joined: 16-October 07

Re: Find average using a vector keeps displaying nan

Posted 04 January 2019 - 07:01 AM

View Postalbert003, on 03 January 2019 - 07:44 PM, said:

getName is a string function that would return the students name


Yep, let's start there:
// your code
std::string getName(std::string &n)
{
    std::cout << "Enter your full name:" <<std::endl;
    std::getline(std::cin,n);
    std::cout <<std::endl;

    return n;
}

// my sig 
std::string getName();

// WTF are you passing n?!?  What the hell would n even mean?
// my code
std::string getName() {
    std::cout << "Enter your full name:" <<std::endl;
    std::string line;
    std::getline(std::cin, line);
    return line;
}



View Postalbert003, on 03 January 2019 - 07:44 PM, said:

double getAverage would be where the student input their grades

Nope. Let's review.

// returns the name, takes NO arguments
std::string getName();

// look at the return type, we return a the grades vector
// how do we get that data?  Probably by asking the user.
grades getHomework();

// again, the return type makes it clear what we're after
// this will calculate the average based on the vector passed to int
// the const is extremely intentional: you aren't supposed to mess with values you've already gathered, 
// only use them for your calculation
double getAverage(const grades &);

// this is to emphasize that you ask for a name and don't do squat with it...
void showResults(const std::string &name, double average);



Currently, you've already written getAverage... it looks like:
double getAverage(const grades &xs) {
    return std::accumulate(xs.begin(), xs.end(), 0.0) / xs.size();
}


It's cute you've found a canned function for this. Can you do it without the function? I'd expect you to be able to roll your own, as it's only a few lines.

The idea behind getHomework is something like:
grades getHomework() {
    grades homework;
    std::cout << "How many grades will you enter?" << std::endl;
    // your code here
    return homework;
}



Hope this helps.

This post has been edited by baavgai: 04 January 2019 - 07:01 AM
Reason for edit:: tag fail

Was This Post Helpful? 1
  • +
  • -

#7 jimblumberg   User is offline

  • member icon

Reputation: 5645
  • View blog
  • Posts: 17,347
  • Joined: 25-December 09

Re: Find average using a vector keeps displaying nan

Posted 04 January 2019 - 07:15 AM

I'd also suggest you stop using that silly typedef and just call it what it is a std::vector<double>. You still seem to be confused by what a typedef is doing so stop using it.

Jim

This post has been edited by jimblumberg: 04 January 2019 - 07:16 AM

Was This Post Helpful? 3
  • +
  • -

#8 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7361
  • View blog
  • Posts: 15,284
  • Joined: 16-October 07

Re: Find average using a vector keeps displaying nan

Posted 04 January 2019 - 07:48 AM

View Postjimblumberg, on 04 January 2019 - 09:15 AM, said:

I'd also suggest you stop using that silly typedef


Agreed. Which is to say, I actually like a typedef for this sort of thing. However, if it confuses you and you don't need it, don't use it. Do you fully understand how that accumulate is working? If not, don't use that.

The purpose of the skeleton I offered is to break down the program into smaller chunks that can be reasoned about separately. Programming is the art of taking on big problem, the program, and breaking down in to many simpler smaller problems. It's completely understandable if my breakdown isn't your breakdown: if it doesn't make sense to you, don't use it.

The one important thing here is that every part of YOUR program make sense to YOU. If you can meet that one criteria, you'll be in a much better place.
Was This Post Helpful? 2
  • +
  • -

#9 jimblumberg   User is offline

  • member icon

Reputation: 5645
  • View blog
  • Posts: 17,347
  • Joined: 25-December 09

Re: Find average using a vector keeps displaying nan

Posted 04 January 2019 - 10:15 AM

Quote

I actually like a typedef for this sort of thing.

Well, IMO this typedef would probably be better if the name was better. Normally my User Defined Types (structures, classes, typedefs) start with a capital letter and are descriptively named, and in this case I'm not sure that "Grades" would be meaningful enough to justify the bother.


Jim
Was This Post Helpful? 1
  • +
  • -

#10 albert003   User is offline

  • D.I.C Addict

Reputation: 22
  • View blog
  • Posts: 614
  • Joined: 15-December 14

Re: Find average using a vector keeps displaying nan

Posted 07 January 2019 - 05:24 PM

ndc85430 Yeah that was a idiot mistake on my part, I completely forgot to put the return function there.

jimblumberg I'm trying to better understand what typedef does in C++. Which is why I am trying to write a few programs that use it.

I also wanted to thank you Jim for recommending me that book. Its been a great help!.

The C++ book you recommended hasn't covered structs or classes. I know how to use them, but I am trying to do this as if I don't know anything other than what was shown to me so far in the book. The one thing I am changing is using various functions so that the program looks cleaner and easier to read.


baavgai It helped me a lot!. I have a bad habit of overthinking things or not breaking them down to simpler forms. Its a bad habit I'm trying to break.

I figured the program out after the last tips and suggestions from you guys.

This is the program.

#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
#include <numeric>

typedef std::vector<double>grades;
grades getHomework()
{
    double number,input;
    grades homework;
    std::cout << "How many grades will you enter?.\n" <<std::endl;
    std::cin >> number;

    for(int i = 0; i < number; i++)
    {
        std::cout << i+1 << " grade" <<std::endl;
        std::cin >> input;
        homework.push_back(input);
    }
    return homework;
}
std::string getName()
{
    std::string name;
    std::cout << "Enter your full name:" << std::endl;
    std::getline(std::cin,name);

    return name;
}
double getAverage(const grades& homework)
{
    double average;
    double total = 0;
    for(int i = 0; i < homework.size();i++)
    {
        total += homework[i];
    }

    average = total / homework.size();

    return average;
}
void showResults(const std::string &name,grades &homework,double average)
{
    std::cout << name << "'s average grade is:  "<< average << std::endl;
}

int main()
{
    double average;
    std::string name = getName();
    grades homework = getHomework();
    average = getAverage(homework);
    showResults(name,homework,average);
}


Was This Post Helpful? 1
  • +
  • -

#11 jimblumberg   User is offline

  • member icon

Reputation: 5645
  • View blog
  • Posts: 17,347
  • Joined: 25-December 09

Re: Find average using a vector keeps displaying nan

Posted 07 January 2019 - 09:02 PM

What book did you actually acquire?

Quote

I'm trying to better understand what typedef does in C++.

Maybe it would be better to research the problem, or ask specific questions about the topic.

By the way you have several header file includes that are not required. You should only #include headers that you actually use.

Lastly you have a couple of functions that have parameters that are either not used or not properly const qualified.


Jim
Was This Post Helpful? 0
  • +
  • -

#12 ndc85430   User is offline

  • I think you'll find it's "Dr"
  • member icon

Reputation: 934
  • View blog
  • Posts: 3,741
  • Joined: 13-June 14

Re: Find average using a vector keeps displaying nan

Posted 07 January 2019 - 11:37 PM

In your getHomework function, does it make sense for number to be a double?
Was This Post Helpful? 0
  • +
  • -

#13 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7361
  • View blog
  • Posts: 15,284
  • Joined: 16-October 07

Re: Find average using a vector keeps displaying nan

Posted 08 January 2019 - 02:48 AM

Excellent!

A few things. In your loop that's int, the number should also be int.

Good job rolling your own getAverage. Note, you don't really need the variable average, you can simply return total / homework.size();. The fewer variables you have declared, the fewer you have to juggle, so only declaring when needed can make things simpler.

Tackling complexity and breaking problems down into simpler chunks will be your eternal quest. It is the challenge of all programmers. The more you do it, the better you get at it, so carry on.
Was This Post Helpful? 0
  • +
  • -

#14 albert003   User is offline

  • D.I.C Addict

Reputation: 22
  • View blog
  • Posts: 614
  • Joined: 15-December 14

Re: Find average using a vector keeps displaying nan

Posted 08 January 2019 - 04:31 PM

jimblumberg I see the missing const in the parameter of the function showResults. I went through the program till 2am and again all morning long and I can't see where theres a parameter in a function that's not being used.

I am using the book accelerated c++ by Barbra Moo. I tried the other book and I found it hard to follow the lessons. I'm a visual person and understand better when I have examples in front of me.

ndc85430 I used a double incase the person keying in their grades got a 75.5. But now that you mention it, I'll change it to int. Since most people get graded in whole numbers and not floats.

baavgai Thank you for your skeleton example.

Here's the updated program with the changes you guys recommended.

#include <iostream>
#include <string>
#include <vector>

typedef std::vector<double>grades;
grades getHomework()
{
    double input;
    int number;
    grades homework;
    std::cout << "How many grades will you enter?.\n" <<std::endl;
    std::cin >> number;

    for(int i = 0; i < number; i++)
    {
        std::cout << i+1 << " grade" <<std::endl;
        std::cin >> input;
        homework.push_back(input);
    }
    return homework;
}
std::string getName()
{
    std::string name;
    std::cout << "Enter your full name:" << std::endl;
    std::getline(std::cin,name);

    return name;
}
double getAverage(const grades& homework)
{
    double average;
    double total = 0;
    for(int i = 0; i < homework.size();i++)
    {
        total += homework[i];
    }

    average = total / homework.size();

    return average;
}
void showResults(const std::string &name,const grades &homework,double average)
{
    std::cout << name << "'s average grade is:  "<< average << std::endl;
}

int main()
{
    double average;
    std::string name = getName();
    grades homework = getHomework();
    average = getAverage(homework);
    showResults(name,homework,average);
}


Was This Post Helpful? 0
  • +
  • -

#15 jimblumberg   User is offline

  • member icon

Reputation: 5645
  • View blog
  • Posts: 17,347
  • Joined: 25-December 09

Re: Find average using a vector keeps displaying nan

Posted 08 January 2019 - 09:28 PM

Quote

I went through the program till 2am and again all morning long and I can't see where theres a parameter in a function that's not being used.

Look at your showResults() function. Where are you using that grades parameter?

Jim
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2