Thread: Temperature Average and Median using Vectors

  1. #16
    Guest
    Guest
    Your bad words example looks super convoluted, you're really overthinking this. You might want to try and do your problems with pen and paper first, instead of coding away; it can really help one focus. Thinking takes time, writing the code takes a minute.

    Code:
    for (int i = 0; i < (signed int)words.size(); i++) { }
    Unless you need a signed value for your logic, use an unsigned one to compare, instead of casting.
    Code:
    for(size_t i = 0; i < words.size(); ++i) { }
    You can shorted this function:
    Code:
    void keep_window_open()
    {
        cout <<"Press any key.\n";
        cin.get();
    }

  2. #17
    Registered User
    Join Date
    Mar 2015
    Posts
    384
    @Elysia: How do you take the average of the two middle numbers? Sort the list, divide the size of the vector by 2, and then try to somehow isolate the two middle elements? How do I isolate them, if so?

    Guest: I cast it because otherwise it keeps giving me a warning about comparing an unsigned int to a signed int. So it's okay in this case, and I shouldn't worry about the warning?

    In the Review for the chapter, there's a set of Drills that each works on or modifies the same program, and I'm having some trouble with that program. I have to read two numbers on each run through a while loop, and print them out, then print the smaller and larger ones, then I have to print out that the two are the same (only) if they are the same; right now I'm kind of stuck there since it keeps taking one of the numbers either as a 0 or as part of the number when I put in a number in hundreds or thousands or I put one in tens, after I've given it the first set of inputs and it's told me which one is larger and which is smaller.

    Here is the code:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void keep_window_open();
    
    int main()
    {
        double value1 = 0;
        double value2 = 0;
        char c;
         cout << "Keep entering two numbers; to end the stream of inputs,  just enter \"|\" or something that isn't a number.\n";
        while (cin >> value1 >> value2)
        {
            if (value1 == value2)
            {
                cout << "The two values are the same (" << value1 << ", " << value2 << ").\n";
            }
            else
            {
                if (value1 < value2)
                {
                    cout << "The smaller value is: " << value1 << "\n";
                }
                else if (value1 > value2)
                {
                    cout << "The smaller value is: " << value2 << "\n";
                }
                double larger = (value1 > value2) ? value1 : value2;
                cout << "The larger value is: " << larger << "\n";
            }
            cin >> c;
            cin.ignore();
            if (c == '|')
            {
                break;
            }
        }
        keep_window_open();
    }
    
    void keep_window_open()
    {
        cin.clear();
        cout << "Please enter a character to exit: ";
        char ch;
        cin >> ch;
        cin.ignore();
        return;
    }
    For the function keep_window_open(), it has to be there so that the output window stays open so I can see the full output, since, on Windows systems, the program control exits immediately after the program's output is shown - Code::Blocks keeps the window open with the "press any key to continue" line, but running from the Command Line or by double-clicking on the executable will end up having the window close immediately after the program code control reaches the end of the program, if I don't put in either cin.ignore() enough times or use that other function. If it's a program that just prints something to the screen and then exits, without that function (or just cin.ignore()) the window just flashes by really quickly and you don't get to see the output at all (when you run it at the Command Line by yourself, it just immediately goes back to showing a blinking prompt beside the name of the folder your program's executable is in, the program's control having exited immediately).

    Edit:

    Here's the output for a set of inputs as of right now:
    Code:
    Keep entering two numbers; to end the stream of inputs, just enter "|" or someth
    ing that isn't a number.
    45 100
    The smaller value is: 45
    The larger value is: 100
    100 100
    The smaller value is: 0
    The larger value is: 100
    100 45
    The smaller value is: 0
    The larger value is: 45
    45 45
    45
    The two values are the same (45, 45).
    45 100
    100
    The two values are the same (100, 100).
    100
    100
    The smaller value is: 0
    The larger value is: 100
    100 100
    The smaller value is: 0
    The larger value is: 100
    100
    100 100
    The smaller value is: 0
    The larger value is: 100
    ^Z
    Please enter a character to exit: l
    
    Process returned 0 (0x0)   execution time : 66.691 s
    Press any key to continue.
    Isn't that weird output? So what's going on?
    Last edited by Osman Zakir; 04-11-2015 at 06:13 AM.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Osman Zakir View Post
    @Elysia: How do you take the average of the two middle numbers? Sort the list, divide the size of the vector by 2, and then try to somehow isolate the two middle elements? How do I isolate them, if so?
    You know how to pick out a number from an array. So if you have arrays of, say:

    1 2
    1 2 3
    1 2 3 4

    How do you pick out the middle numbers and what's the median?

    Guest: I cast it because otherwise it keeps giving me a warning about comparing an unsigned int to a signed int. So it's okay in this case, and I shouldn't worry about the warning?
    No, you should not ignore it. That's why you should use size_t instead, because it's unsigned and typically what .size() returns in the first place. Or you can do

    for (auto size = v.size(), i = 0 * size; i < size; i++)

    Since I use auto, the type of size becomes the same type returned by v.size(). By multiplying i by size, I force it to get the same type. By multiplying with 0, I obviously initialize it to 0.

    In the Review for the chapter, there's a set of Drills that each works on or modifies the same program, and I'm having some trouble with that program. I have to read two numbers on each run through a while loop, and print them out, then print the smaller and larger ones, then I have to print out that the two are the same (only) if they are the same; right now I'm kind of stuck there since it keeps taking one of the numbers either as a 0 or as part of the number when I put in a number in hundreds or thousands or I put one in tens, after I've given it the first set of inputs and it's told me which one is larger and which is smaller.
    Remove the portion:
    Code:
            cin >> c;
            cin.ignore();
            if (c == '|')
            {
                break;
            }
    The code

    Code:
        while (cin >> value1 >> value2)
    will fail once you enter a non-number, and thus forces the loop to terminate anyway. Doing this, it worked for me.

    To explain why, consider that cin >> c reads a character, so the first character of the number you enter gets eaten by this line.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Mar 2015
    Posts
    384
    The spec for the problem says to read two numbers on every iteration of the while-loop, and to terminate the stream of inputs when the program reads in a '|' character. That's why I did that. Should I combine those two conditions with the Boolean OR up in the while-loop's parentheses, or will that not make it work correctly?

    Maybe I should do this instead:
    Code:
    if (value1 == '|' || value2 == '|')
    {
        break;
    }
    or this

    Code:
    while (cin >> value1 >> value2 || value1 == '|' || value2 == '|')
    {
        // my code, without the break statement
    }
    Unless that will also either cause the compiler to throw errors at me or make the program not work as desired.

    Well, never mind; I just tried doing that, and it causes the program to just exit even when the keep_window_open() function is called - i.e. it doesn't read in the character and just exits.

    Anyway, other than wanting it to terminate input-reading when it reads in the bar character, it's working as desired up until there now.

    So the next part I have to do in the Drill, that I don't how to do, is this:

    Change the program so that it writes out the numbers are almost equal after writing out which is the larger and the smaller if the two numbers differ by less than 1.0/100.
    Really, how do I tell if two numbers have only a difference of less than 1.0/100 (is that 1.0 divided by 100, or 1.0 or 100?)?

    Anyway, I'm not exactly sure that I know all that well how to take just one number out of an array, but I can tell by looking at those numbers what the medians are; if I'm not mistaken, for 1 and 2 it's 1.5; for 1, 2 and 3 it's 2 (I'm not sure about this one); and for 1, 2, 3 and 4, it's 2.5. Do I just take those numbers, find their size (i.e. number of elements in the array or vector), and just divide by two if it's an even number? But then how do I figure it out if it's an odd number of elements?
    Last edited by Osman Zakir; 04-11-2015 at 08:10 AM.

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Osman Zakir View Post
    The spec for the problem says to read two numbers on every iteration of the while-loop, and to terminate the stream of inputs when the program reads in a '|' character. That's why I did that. Should I combine those two conditions with the Boolean OR up in the while-loop's parentheses, or will that not make it work correctly?
    According to what I read, that is not the case:
    Keep entering two numbers; to end the stream of inputs, just enter "|" or something that isn't a number.

    As for how to solve it otherwise, you have to read a string. "|" cannot be read into an integer. Because a string can read anything, you can later convert it into a number, if desired.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #21
    Registered User
    Join Date
    Mar 2015
    Posts
    384
    Alright.

    In this program, though, what variable should I try to do modulo 2 to, to see if it's even or not? I can't use temps[temp] since that's only in the other for-loop. Should I initialize another variable to keep track of the vector elements and put that in the brackets, and then check if the value is even or odd?

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Osman Zakir View Post
    Should I initialize another variable to keep track of the vector elements and put that in the brackets, and then check if the value is even or odd?
    What would this do?

    In real life, if you have a sequence of numbers, how would you calculate the median?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #23
    Registered User
    Join Date
    Mar 2015
    Posts
    384
    Tell me what I'm doing wrong here:
    Code:
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    void keep_window_open();
    
    int main()
    {
        vector<double> temps;
        double temp;
        for (cin >> temp)    // read into temp
        {
            temps.push_back(temp);     // put temp into vector
        }
        // compute mean temperature:
        double sum = 0;
        for (double x : temps) sum += x;
        {
            cout << "Average temperature: " << sum/temps.size() << '\n';
            // compute median temperature:
            sort(temps.begin(), temps.end());        // sort temperatures
    
            if (temps[temp] % 2 == 0)
            {
                cout << "Median temperature: " << temps[temps.size()/2] << '\n';
            }
            else
            {
                cout << "Median temperature: " << temps[(temps.size() + 1) / 2] << "\n";
            }
        }
        keep_window_open();
    }
    
    // define keep_window_open() to keep the window open on Windows machines
    // when running the program via double-clicking the .exe file directly
    void keep_window_open()
    {
        cin.clear();
        cout << "Please enter a character to exit: ";
        cin.get();
        cin.ignore();
        return;
    }
    These are the messages the compiler gives me:
    Code:
    ||=== Build: Debug in temperature_vector (compiler: GNU GCC Compiler) ===|
    C:\Users\Osman\programming\stroustrup_programming_using_c++\temperature_vector\temperature_vector.cpp||In function 'int main()':|
    C:\Users\Osman\programming\stroustrup_programming_using_c++\temperature_vector\temperature_vector.cpp|13|error: expected ';' before ')' token|
    C:\Users\Osman\programming\stroustrup_programming_using_c++\temperature_vector\temperature_vector.cpp|19|error: expected primary-expression before 'for'|
    C:\Users\Osman\programming\stroustrup_programming_using_c++\temperature_vector\temperature_vector.cpp|19|error: expected ')' before 'for'|
    C:\Users\Osman\programming\stroustrup_programming_using_c++\temperature_vector\temperature_vector.cpp|21|error: 'sum' was not declared in this scope|
    C:\Users\Osman\programming\stroustrup_programming_using_c++\temperature_vector\temperature_vector.cpp|25|error: invalid operands of types '__gnu_cxx::__alloc_traits<std::allocator<double> >::value_type {aka double}' and 'int' to binary 'operator%'|
    ||=== Build failed: 5 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
    Why does it say, "sum was not declared in this scope"? I've clearly declared it.

  9. #24
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    This is syntactically invalid:
    Code:
    for (cin >> temp)
    You probably wanted to write a while loop.

    This is syntactically valid but misleading:
    Code:
    for (double x : temps) sum += x;
    {
        cout << "Average temperature: " << sum/temps.size() << '\n';
        // compute median temperature:
        sort(temps.begin(), temps.end());        // sort temperatures
    
        if (temps[temp] % 2 == 0)
        {
            cout << "Median temperature: " << temps[temps.size()/2] << '\n';
        }
        else
        {
            cout << "Median temperature: " << temps[(temps.size() + 1) / 2] << "\n";
        }
    }
    In more conventional formatting, it is equivalent to:
    Code:
    for (double x : temps)
    {
        sum += x;
    }
    
    {
        cout << "Average temperature: " << sum/temps.size() << '\n';
        // compute median temperature:
        sort(temps.begin(), temps.end());        // sort temperatures
    
        if (temps[temp] % 2 == 0)
        {
            cout << "Median temperature: " << temps[temps.size()/2] << '\n';
        }
        else
        {
            cout << "Median temperature: " << temps[(temps.size() + 1) / 2] << "\n";
        }
    }
    You probably don't need the extra code block as that block can be placed directly in the main function's scope. If you do want another code block, then you might as well move it to a separate function as it is a reasonably good candidate to be another function.

    This is problematic: temps[temp] % 2. temps[temp] is a double, but operator% is not defined for double operands. You probably wanted to write temps.size() % 2 instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #25
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    >>if (temps[temp] % 2 == 0)
    What does this do? What are you trying to achieve with it?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #26
    Registered User
    Join Date
    Mar 2015
    Posts
    384
    The line
    Code:
    for (cin >> temp)
    Was supposed to be
    Code:
    for (double temp; cin >> temp;)
    So it's a different kind of for-loop, but not exactly a while-loop. I kind of messed up while trying to modify the code to fit the new need. Sorry about that.

    Anyway, I'll probably put that other part in another function, but for now, just let me know if it's correct and whatnot.
    Code:
        double sum = 0;
        for (double x : temps) sum += x;
        {
            cout << "Average temperature: " << sum/temps.size() << '\n';
            // compute median temperature:
            sort(temps.begin(), temps.end());        // sort temperatures
    
            if (temps.size() % 2 == 0)
            {
                cout << "Median temperature: " << temps[temps.size()/2] << '\n';
            }
            else
            {
                cout << "Median temperature: " << temps[(temps.size() + 1) / 2] << "\n";
            }
        }
    Would doing it like that give me the correct value for the Median if the number of elements in the vector is odd?
    Last edited by Osman Zakir; 04-11-2015 at 10:11 AM.

  12. #27
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Osman Zakir
    Anyway, I'll probably put that other part in another function
    If you don't, then at the very least format it like what I demonstrated, otherwise readers could miss the "sum += x;" because they might perceive the following block of code as being the body of the range-based for loop when it is not.

    Quote Originally Posted by Osman Zakir
    Would doing it like that give me the correct value for the Median if the number of elements in the vector is odd?
    Substitute some odd and even sizes and reason about it. For example, suppose the size is 3. The median would then be the element at index 1. (3 + 1) / 2 == 2. Therefore, it is wrong.

    Also, note that the computation of median for an even size is also wrong: you should take the mean of the two middle elements instead, e.g., suppose the size is 4, the median would then be the mean of the elements at indices 1 and 2.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #28
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Osman Zakir View Post
    Would doing it like that give me the correct value for the Median if the number of elements in the vector is odd?
    Think about it. Reason about it.
    This is a basic mathematical formula. This doesn't even have the term "programming" applied to it! You should be able to solve this yourself!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #29
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You may want to study this link to better understand how to find the median.

    If you have an odd number of elements in your vector then the median is the middle number (size() / 2). When you have an even number of elements in your vector the median is the average of the middle two items (size() / 2) and ((size() / 2) + 1).

    Jim

  15. #30
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Why do you spill the answer?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 27
    Last Post: 02-14-2015, 11:17 AM
  2. Pointers (Average and Median)
    By blackqueen212 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2014, 11:33 AM
  3. Replies: 17
    Last Post: 04-17-2012, 05:46 PM
  4. CPU temperature
    By Kempelen in forum Windows Programming
    Replies: 1
    Last Post: 05-23-2011, 04:06 AM
  5. Vectors in vectors - pointers and iterators
    By fisherking in forum C++ Programming
    Replies: 8
    Last Post: 07-27-2010, 09:34 AM