Placing validation with multiple functions

Hello! I'm currently working on a class problem where I am calculating wind chill and cloud base based of user inputs. I have the program functioning to all the requirements except one.

If the user enters a value greater than 50.0 for the temperature OR the user enters a value 3.0 or less for the wind speed I want to still compute cloud base and just set wind chill to ***. I also want to display a message below all the data explaining why. My question is really how would I go about this? I know it's an if else statement but where would be the best place to do it?

Also any formatting tips are appreciated this is my first time using setw.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;
//functions
void input_data(double &fahrenhiet, double &windspeed, double &dewPoint);
double wind_chill(double fahrenheit, double windSpeed);
double cloud_base(double fahrenheit, double windSpeed);
void output_data(double fahrenheit, double windSpeed, double dewPoint, double wc, double cb);

int main()
{   //Variables
    double fahrenheit, windSpeed, dewPoint, wc, cb;
    //Calling functions
    input_data(fahrenheit, windSpeed, dewPoint);

    wc = wind_chill(fahrenheit, windSpeed);

    cb = cloud_base(fahrenheit, dewPoint);

    output_data(fahrenheit, windSpeed, dewPoint, wc, cb);

    return 0;
}

// input_data function
void input_data(double &fahrenheit, double &windSpeed, double &dewPoint)
{   //formatting input
    cout << " -----------------------------------------------------------" << endl;
    cout << "|" << setw(60) << "|" << endl;
    cout << "|" << "    This program determines wind chill using temperature   " << "|" << endl;
    cout << "|" << "    in Farenheit and win speed in mph, and computes    " << setw(5) << "|" << endl;
    cout << "|" << "    the cloud base using the dew point in Farenheit.       " << "|" <<endl;
    cout << "|" << setw(60) << "|" << endl;
    cout << " -----------------------------------------------------------" << endl;

    cout << "\nEnter the temperature in degrees Farenheit: ";
    cin >> fahrenheit;
    cout << "Enter the wind speed in mph: ";
    cin >> windSpeed;
    cout << "Enter the dew point in degrees Fahrenheit: ";
    cin >> dewPoint;
}
//function calculating wind chill
double wind_chill(double fahrenheit, double windSpeed)
{
    double wc = 35.74+.6215*(fahrenheit)-35.75*(pow(windSpeed,0.16))+0.4275*(fahrenheit)*(pow(windSpeed,0.16));
    return wc;
}

//functino calculating cloud base
double cloud_base(double fahrenheit, double dewPoint)
{
    double tempSpread = fahrenheit - dewPoint;
    double cb = (tempSpread/4.4)*1000;
    return cb;
}
//output function to display data
void output_data(double fahrenheit, double windSpeed, double dewPoint, double wc, double cb)
{
    cout << fixed << setprecision(1);
    //formatting output
    cout << "\nTemperature    " << "Wind speed" << "    Dew Point" << "     Wind Chill" << "    Cloud Base";
    cout << "\n--------------------------------------------------------------------" << endl;
    cout << setw(7) <<fahrenheit << setw(15) << windSpeed << setw(14) << dewPoint << setw(14) << wc << setw(15) << cb;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//output function to display data
void output_data(double fahrenheit, double windSpeed, double dewPoint, double wc, double cb)
{

    const double absolute_zero_in_archaic_units = -459.67 ;

    if( fahrenheit < absolute_zero_in_archaic_units ) cout << "invalid temperature\n" ;
    else if( dewPoint < absolute_zero_in_archaic_units ) cout << "invalid dew point\n" ;
    else if( windSpeed < 0.0 ) cout << "invalid wind speed\n" ;

    else // valid values for temperature, wind speed and dew point
    {
        cout << fixed << setprecision(1);
        //formatting output
        cout << "\nTemperature    " << "Wind speed" << "    Dew Point" << "     Wind Chill" << "    Cloud Base";
        cout << "\n--------------------------------------------------------------------" << endl;

        if( fahrenheit <= 50.0 && windSpeed > 3.0 ) // display wind chill
            cout << setw(7) <<fahrenheit << setw(15) << windSpeed << setw(14) << dewPoint << setw(14) << wc << setw(15) << cb << '\n' ;

        else // do not display wind chill
        {
            cout << setw(7) <<fahrenheit << setw(15) << windSpeed << setw(14) << dewPoint << setw(14) << "***" << setw(15) << cb << '\n' ;

            cout << "\nnote: wind chill was omitted because:\n" ;
            if( fahrenheit > 50.0 ) cout << "    temperature is too high\n" ;
            if( windSpeed <= 3.0 ) cout << "    wind speed is too low\n" ;
        }
    }
}
A note on:
1
2
3
4
5
6
double wind_chill( double fahrenheit, double windSpeed )
{
  double wc = 35.74+.6215*(fahrenheit)-35.75*(pow(windSpeed,0.16))
             +0.4275*(fahrenheit)*(pow(windSpeed,0.16));
  return wc;
}

There are unnecessary parentheses that have no effect on the result, but make reading a bit more difficult. Taking them out:
1
2
3
4
5
6
double wind_chill( double fahrenheit, double windSpeed )
{
  double wc = 35.74 + .6215*fahrenheit - 35.75*pow(windSpeed,0.16)
            + 0.4275*fahrenheit*pow(windSpeed,0.16);
  return wc;
}

There is no actual need for the local variable either:
1
2
3
4
5
double wind_chill( double fahrenheit, double windSpeed )
{
  return 35.74 + .6215*fahrenheit - 35.75*pow(windSpeed,0.16)
         + 0.4275*fahrenheit*pow(windSpeed,0.16);
}

However, you call pow() twice with same input. That could use a variable:
1
2
3
4
5
double wind_chill( double fahrenheit, double windSpeed )
{
  const auto PW = pow( windSpeed, 0.16 );
  return 35.74 + .6215*fahrenheit - 35.75*PW + 0.4275*fahrenheit*PW;
}

Or note that PW is common to two terms and rearrange:
1
2
3
4
double wind_chill( double fahrenheit, double windSpeed )
{
  return 35.74 + .6215*fahrenheit + (0.4275*fahrenheit - 35.75)*pow( windSpeed, 0.16 );
}


In principle one can shuffle terms around in all the ways that math says are legal.
However, floating point math can get tricky because floats and doubles have limited precision that requires rounding at certain steps.
Nice, looks good. Some tweaks I'd make:
- Add a check to make sure that fahrenheit >= dewPoint, or you'll get negative cloud base elevation results.
- Remove all the comments since they don't add any value at all. Could discuss input and output units or something, but just writing "input_data function" when it's clearly named input_data(...) is absolutely pointless. All your comments are examples of bad comments.
- Add units to the output. It's unclear to the user that the cloud base is an elevation in feet.
- Fix all the incorrect spellings of "Fahrenheit"

Last edited on
Thank you all for the replies all have been really beneficial!

@keskiverto Genuinely curious, I've seen constants in c++ by what exactly is the "auto" for?
Last edited on
Before C++11 the keyword auto had a different meaning.
Here it was used in the new meaning, which is "compiler deduces type automatically".
http://en.cppreference.com/w/cpp/language/auto

I could have written:
const double PW = pow( windSpeed, 0.16 );
The pow() has multiple overloads: http://www.cplusplus.com/reference/cmath/pow/
The windSpeed and 0.16 both have type double.
Therefore, the selected overload is double pow(double,double).
The variable PW is thus initialized with a double value.

When the auto is used, the compiler takes the type of the initializer and uses it as type of the variable. That does not gain us much in here, but how about in this:
1
2
3
4
5
void gaz( const std::map<int,std::vector<std::string>> & foo )
{
  auto bar = foo.rbegin();
  // ...
}

What is the real type of bar?
Is it std::map<int,std::vector<std::string>>::const_reverse_iterator ?
Do we even need to know, if the auto gets the job done?
Topic archived. No new replies allowed.