Freezing and Boiling Points

Write your question here.
Hello. I am having a bit of a logic error with my code.
This is challenge 16 from chapter 13 from starting out with c++ 9th edition.
Program Output:
The temperature ethyl:
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <iostream>
using namespace std;

// Create a class called TempPoints
class TempPoints
{
	private:
	int temperature;
	public:
	TempPoints();
	int isEthylFreezing(int);
	int isEthylBoiling(int);
	int isOxygenFreezing(int);
	int isOxygenBoiling(int);
	int isWaterFreezing(int);
	int isWaterBoiling(int);
	void setTemperature(int);
	int getTemperature();
};

// Default constructor
TempPoints::TempPoints()
{
	int temperature = 0;
}

// Determine if Ethyl alcohol is freezing
int TempPoints::isEthylFreezing(int ethylCold)
{
	if (ethylCold <= -173)
	{
		cout << "The ethyl's temperature is cold" << endl;
		return true;
	}
		return false; 	
}


// Determine if the Ethyl alcohol is boiling
int TempPoints::isEthylBoiling(int ethylHot)
{
	if (ethylHot >= 172)
	{
		cout << "The ethyl's temperature is hot" << endl;
		return true;
	} 
	return false; 
}

// Determine if the oxygen is freezing
int TempPoints::isOxygenFreezing(int oxyCold)
{
	if (oxyCold <= -362)
	{
		cout << "The oxygen's temperature is cold" << endl;
		return true;
	} 
		return false; 
}

// Determine if the oxygen is boiling
int TempPoints::isOxygenBoiling(int oxyHot)
{
	if (oxyHot >= -306)
	{
		cout << "The oxygen's temperature is hot" << endl;
		return true;
	} 
		return false; 	
}

// Determine if the water is freezing
int TempPoints::isWaterFreezing(int coldWater)
{
	if (coldWater <= 32)
	{
		cout << "The water's temperature is cold" << endl;
		return true; 
	} 
		return false; 
}

// Determine if the water is boiling
int TempPoints::isWaterBoiling(int hotWater)
{
	if (hotWater >= 212)
	{
		cout << "The water's temperature is hot" << endl;
		return true;
	} 
		return false; 
}

// Set up the temperature
void TempPoints::setTemperature(int temp)
{
	temperature = temp; 
}

// Retrieve the temperature
int TempPoints::getTemperature()
{
	return temperature; 
}

// Prompt the user to enter the temperature for the following
void printTempInfo(TempPoints &tempInput)
{
	int ethyl, oxygen, water; 
	cout << "Temperature for ethyl: ";
	cin  >> ethyl;
	tempInput.getTemperature();
	cout << "Temperature for oxygen: ";
	cin  >> oxygen;
	tempInput.getTemperature();
	cout << "Temperature for water: ";
	cin  >> water;
	tempInput.getTemperature();
}

// Evaluate the temperature conditions for each item
void printTempPoints(TempPoints tempAmounts)
{	
	int ethyl, oxygen, water;
	if (tempAmounts.isEthylFreezing(ethyl))
	{	
		cout << tempAmounts.isEthylFreezing(ethyl) << endl;
	} 
	if (tempAmounts.isEthylBoiling(ethyl))
	{
		cout << tempAmounts.isEthylBoiling(ethyl) << endl;
	}
	if (tempAmounts.isOxygenFreezing(oxygen))
	{
		cout << tempAmounts.isOxygenFreezing(oxygen)<< endl; 
	}
	if (tempAmounts.isOxygenBoiling(oxygen))
	{
		cout << tempAmounts.isOxygenBoiling(oxygen) << endl; 
	}
	if (tempAmounts.isWaterFreezing(water))
	{
		cout << tempAmounts.isWaterFreezing(water) << endl;
	}
	if (tempAmounts.isWaterBoiling(water))
	{
		cout << tempAmounts.isWaterBoiling(water) << endl; 
	}
}
Last edited on
1. Thank you for using code tags, they really help.

2. You accidentally double-posted your code, you should delete the 2nd copy. (delete lines 160-319)

3. You are using uninitialized variables in printTempPoints(). Where are you getting the values?

printTempInfo() looks like it is used to get the values, not printing temperature information as the function name might indicate, but the variables in that function are locally scoped to that function only.
4. Your default ctor at lines 22-25. You are defining a variable scoped to just the body of the ctor, not initializing your temperature data member.

1 possible change:
22
23
24
25
TempPoints::TempPoints()
{
	temperature = 0;
}

Or:
22
23
TempPoints::TempPoints() : temperature { }
{ }

Or:
8
9
10
11
12
int temperature { };

// .... elided code

Temperature() {}
5. I wouldn't have a function's return type as int if it were returning a Boolean value (true/false).

It isn't wrong/bad, the intent would be better if the return type is bool.

There are several different ways to rewrite/refactor the code, depending on how complex you want to make the class. I don't own the book you are using, so I can't really comment on what the program is trying to teach.
I am having a bit of a logic error with my code.


Which is? If the problem is a logic error, then using the debugger to trace through the code should pinpoint the issue.
I think you should re-consider your design!

Instead of having a separate isFooFreezing() and isFooBoiling() for each compound in your class, consider having just one isFreezing() and one isBoiling() function. The freezing/boiling temperature can be passed into the class in the constructor. Then create one instance (object) of your class for each compound:

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
class TempPoints
{
public:
	TempPoints(const int freezingTemp, const int boilingTemp);
	TempPoints::TempPoints(const TempPoints &other);
	bool TempPoints::isFreezing(const int temp) const;
	bool TempPoints::isBoiling(const int temp) const;
private:
	const int freezingTemp;
	const int boilingTemp;
};

TempPoints::TempPoints(const int freezingTemp, const int boilingTemp)
	: freezingTemp(freezingTemp), boilingTemp(boilingTemp) { }

TempPoints::TempPoints(const TempPoints &other)
	: freezingTemp(other.freezingTemp), boilingTemp(other.boilingTemp) { }

bool TempPoints::isFreezing(const int temp) const
{
	if (temp <= freezingTemp)
	{
		std::cout << "temperature is cold" << std::endl;
		return true;
	}
	return false;
}

bool TempPoints::isBoiling(const int temp) const
{
	if (temp >= boilingTemp)
	{
		std::cout << "temperature is hot" << std::endl;
		return true;
	}
	return false;
}

int main()
{
	TempPoints waterTempPoints(32, 212);
	TempPoints oxygenTempPoints(-362, -306);
	...
}


Could also organize your instances in a map:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main() {
	std::map<std::string, TempPoints> myPoints;
	myPoints.insert(std::make_pair("water",  TempPoints(  32,  212)));
	myPoints.insert(std::make_pair("oxygen", TempPoints(-362, -306)));
	...

	const int temp[4] = { 666, 42, -333, -666 };

	for (size_t i = 0; i < _countof(temp); ++i)
	{
		for (std::map<std::string, TempPoints>::const_iterator iter = myPoints.cbegin(); iter != myPoints.cend(); ++iter)
		{
			std::cout << "Is " << iter->first << " boiling at "  << temp[i] << "? --> " << (iter->second.isBoiling(temp[i])  ? "yes" : "no") << std::endl;
			std::cout << "Is " << iter->first << " freezing at " << temp[i] << "? --> " << (iter->second.isFreezing(temp[i]) ? "yes" : "no") << std::endl;
		}
		std::cout << std::endl;
	}

Is oxygen boiling at 666? --> yes
Is oxygen freezing at 666? --> no
Is water boiling at 666? --> yes
Is water freezing at 666? --> no

Is oxygen boiling at 42? --> yes
Is oxygen freezing at 42? --> no
Is water boiling at 42? --> no
Is water freezing at 42? --> no

Is oxygen boiling at -333? --> no
Is oxygen freezing at -333? --> no
Is water boiling at -333? --> no
Is water freezing at -333? --> yes

Is oxygen boiling at -666? --> no
Is oxygen freezing at -666? --> yes
Is water boiling at -666? --> no
Is water freezing at -666? --> yes

👍
Last edited on
Perhaps:

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
#include <map>
#include <iostream>
#include <array>

class TempPoints {
public:
	TempPoints(int freezingTemp, int boilingTemp) : freezingTemp(freezingTemp), boilingTemp(boilingTemp) {}

	bool isFreezing(int temp) const { return temp <= freezingTemp; }
	bool isBoiling(int temp) const { return temp >= boilingTemp; }

private:
	int freezingTemp {};
	int boilingTemp {};
};

int main() {
	const std::map<std::string, TempPoints> myPoints { {"water", {32, 212}}, {"oxygen", {-362, -306}}, {"ethyl", {-173, 172}} };
	constexpr std::array temp { 666, 42, -333, -666 };

	for (const auto& t : temp) {
		for (const auto& [nam, p] : myPoints) {
			std::cout << nam << " at " << t << " is a ";

			if (p.isBoiling(t))
				std::cout << "gas\n";
			else if (p.isFreezing(t))
				std::cout << "solid\n";
			else
				std::cout << "liquid\n";
		}

		std::cout << '\n';
	}
}



ethyl at 666 is a gas
oxygen at 666 is a gas
water at 666 is a gas

ethyl at 42 is a liquid
oxygen at 42 is a gas
water at 42 is a liquid

ethyl at -333 is a solid
oxygen at -333 is a liquid
water at -333 is a solid

ethyl at -666 is a solid
oxygen at -666 is a solid
water at -666 is a solid

Last edited on
The textbook requires that I have a freezing and boiling function individually for water, ethyl, and oxygen. The challenge is chapter 13 the introduction on classes. So I am not sure if I could use the suggestions you are offering since it doesn't follow the details of the problem properly.

Chapter 13(Introduction to Classes):
Challenge # 13: Freezing and Boiling Points
The problem states following:

Design a class called temperature with the appropriate accessor and mutator functions.
The member functions:
isEthylFreezing - This function only returns true if ethyl is freezing otherwise false.
isEthylBoiling - This function only returns true if ethyl is boiling otherwise false.
isOxygenFreezing - This function only returns true if oxygen is freezing otherwise false.
isOxygenBoiling - This function only returns true if ethyl is freezing otherwize false.
isWaterFreezing - This function only returns true if ethyl is freezing otherwise false.
isWaterBoiling - This function only returns true if ethyl is freezing otherwise false.

Write a program that designs a class. The program should ask the user to enter the temperature and display the list of substances that will either freeze or boil at that temperature. For example, if the user enters -20 the class would report that the water freezes and the oxygen will boil.

This is the logic error I was stating earlier in my previous post.
Program Output:
Temperature for ethyl: 12
Temperature for oxygen: 12
Temperature for water: 13
The oxygen's temperature is hot
The oxygen's temperature is hot
1
The temperature's water is cold.
The temperature's water is cold
1

The table the book uses
Substance
Ethyl Alcohol
Oxygen
Water



Freezing Point
-173
-362
32



Boiling Point
172
-306
212

Last edited on
Having separate functions (or separate classes) only makes sense if they actually implement a different logic. Having two or more functions (or classes) that basically do the same thing, just with different "built-in" constants, is a good example of how to not do things! It's redundant "copy & paste" code that bloats your program for no good reason. This makes you program harder to read and harder to maintain...

Whenever possible, you should try to generalize and parameterize things. So, instead of having n separate functions (or classes) that all do the same thing (except for some implicit constants), you should have just one function (or class) that can be parameterized as needed. In other words, make the implicit constant an explicit parameter. This makes your program a whole lot shorter. And, if you need to change or fix your code, then you need to do this in exactly one place – rather than having to change/fix your program in n separate places.

Really, I have seen too many "real world" projects where people created a complete copy of a 1000 lines "spaghetti code" function, just to change one tiny detail. Of course, there were bugs in the "original" function that ended up in the "copy" of that function too. And, of course, when those bugs later were fixed (by another person), it was only fixed it in the "original" function, but not in the "copy" of that function; other person did not scan the whole project for slightly modified copies of the same function that they just fixed. Needless to say, both functions were called in production code. Working with such project is a nightmare for programmer...
Last edited on
I was thinking of what you just mentioned.
I just wasn't sure if it made sense since the problem told to me to do that way.
I will try your suggestion and post an update.
If you really have to, because "the task" requires it, you can still do:

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
#define DEF_SUBSTANCE_FUNC(NAME) \
	static bool is##NAME##Freezing(const int temp) { return tp##NAME.isFreezing(temp); } \
	static bool is##NAME##Boiling (const int temp) { return tp##NAME.isBoiling (temp); }

#define DEC_SUBSTANCE_TP(NAME) \
	static const TempPoints tp##NAME;

#define DEF_SUBSTANCE_TP(NAME, X, Y) \
	const TempPoints WrapperToSatisfyTask::tp##NAME = TempPoints((X), (Y));


class WrapperToSatisfyTask
{
public:
	DEF_SUBSTANCE_FUNC(Ethyl)
	DEF_SUBSTANCE_FUNC(Oxygen)
	DEF_SUBSTANCE_FUNC(Water)

private:
	DEC_SUBSTANCE_TP(Ethyl)
	DEC_SUBSTANCE_TP(Oxygen);
	DEC_SUBSTANCE_TP(Water);
};

DEF_SUBSTANCE_TP(Ethyl,  -172,  173)
DEF_SUBSTANCE_TP(Oxygen, -362, -306)
DEF_SUBSTANCE_TP(Water,    32,  212)


1
2
3
4
int main()
{
	WrapperToSatisfyTask::isWaterBoiling(42);
}


...with the class TempPoints implemented as outlined in previous post:
https://cplusplus.com/forum/beginner/284096/#msg1230147
Last edited on
As per the book, then perhaps:

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
#include <iostream>

class Temp {
public:
	static bool isEthylFreezing(int temp) { return ethyl.isFreezing(temp); }
	static bool isEthylBoiling(int temp) { return ethyl.isBoiling(temp); }
	static bool isOxygenFreezing(int temp) { return oxygen.isFreezing(temp); }
	static bool isOxygenBoiling(int temp) { return oxygen.isBoiling(temp); }
	static bool isWaterFreezing(int temp) { return water.isFreezing(temp); }
	static bool isWaterBoiling(int temp) { return water.isBoiling(temp); }

	static void doEthyl(int t) {
		if (isEthylBoiling(t))
			std::cout << "Ethyl is boiling\n";

		if (isEthylFreezing(t))
			std::cout << "Ethyl is freezing\n";
	}

	static void doOxygen(int t) {
		if (isOxygenBoiling(t))
			std::cout << "Oxygen is boiling\n";

		if (isOxygenFreezing(t))
			std::cout << "Oxygen is freezing\n";
	}

	static void doWater(int t) {
		if (isWaterBoiling(t))
			std::cout << "Water is boiling\n";

		if (isWaterFreezing(t))
			std::cout << "Water is freezing\n";
	}

private:
	class TempPoints {
	public:
		TempPoints(int freezingTemp, int boilingTemp) : freezingTemp(freezingTemp), boilingTemp(boilingTemp) {}

		bool isFreezing(int temp) const { return temp <= freezingTemp; }
		bool isBoiling(int temp) const { return temp >= boilingTemp; }

	private:
		int freezingTemp {};
		int boilingTemp {};
	};

	const static inline TempPoints water { 32, 212 };
	const static inline TempPoints oxygen { -362, -306 };
	const static inline TempPoints ethyl { -173, 172 };
};

int main() {
	Temp temp;
	int t {};

	std::cout << "Enter temperature (Fahrenheit): ";
	std::cin >> t;

	temp.doWater(t);
	temp.doEthyl(t);
	temp.doOxygen(t);
}



Enter temperature (Fahrenheit): -20
Water is freezing
Oxygen is boiling

Here is an update:

I have made some improvements however the issue I is when I input a value and the computer set the degrees to 0 for Farhenheit. I realize its because I haven't enter anything that deals with the print function I made.

So any suggestions for the user input.


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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <iostream>
using namespace std;

// Create a class called Tempeature
class Temperature
{
	private:
	int temperature;
	public:
	Temperature();
	Temperature(int);
	bool isEthylFreezing();
	bool isEthylBoiling();
	bool isOxygenFreezing();
	bool isOxygenBoiling();
	bool isWaterFreezing();
	bool isWaterBoiling();
	int getTemperature();
};

// Default Constructor 
Temperature::Temperature()
{
	temperature = 0; 
}

// Constructor
Temperature::Temperature(int temp)
{
	temperature = temp;
}

// Accessor
int Temperature::getTemperature()
{
	return temperature;
}

// Determine if the ethyl is freezing
bool Temperature::isEthylFreezing()
{
	int ethylCold = -173;
	if (getTemperature() <= ethylCold)
	{
		return true;
	}
		return false; 
}

// Determine if the ethyl is boiling
bool Temperature::isEthylBoiling()
{
	int ethylHot = 172;
	if (getTemperature() >= ethylHot)
	{
		return true;
	}
		return false;
}

// Determine if the oxygen is freezing
bool Temperature::isOxygenFreezing()
{
	int oxyFreeze = -362;
	if (getTemperature() <= oxyFreeze)
	{
		return true;
	}
		return false; 
}

// Determine if the oxygen is boiling
bool Temperature::isOxygenBoiling()
{
	int oxyBoil = -306;
	if (getTemperature() >= oxyBoil)
	{
		return true;
	}
		return false; 
}

// Determine if the water is freezing
bool Temperature::isWaterFreezing()
{
	int coldWater = 32;
	if(getTemperature() <= coldWater)
	{
		return true;
	}
		return false;
}

// Determine if the water is boiling
bool Temperature::isWaterBoiling()
{
	int hotWater = 212;
	if(getTemperature() >= hotWater)
	{
		return true;
	}
		return false;
}


void isFreezing(Temperature freezing)
{

	cout << "These substances are freezing at " << freezing.getTemperature()
		 << " degrees F: " << endl; 
	if (freezing.isEthylFreezing())
	{
		cout << "Ethyl" << endl;
	}
	if (freezing.isOxygenFreezing())
	{
		cout << "Oxygen" << endl;
	}
	if (freezing.isWaterFreezing())
	{
		cout << "Water" << endl; 
	}
}

void isBoiling(Temperature boiling)
{
	cout << "These substances are boiling " << boiling.getTemperature() 
		 << " degress F: " << endl;	
	if	(boiling.isEthylBoiling())
	{
		cout << "Ethyl" << endl;
	}
	if	(boiling.isOxygenBoiling())
	{
		cout << "Oxygen" << endl;
	}
	if	(boiling.isWaterBoiling())
	{
		cout << "Water" << endl; 
	}
}

void isPrintTemperature(Temperature temp)
{ 
	int therometer;
	cout << "Enter a temperature in Fahrenheit: ";
	cin  >> therometer;
	isFreezing(temp);
	isBoiling(temp);
}		
	

// Main test driver
int main()
{
	Temperature points;
	isPrintTemperature(points);
	system("PAUSE");
	return 0; 
}


Program Output:
Enter a temperature in Fahrenheit: 32
These substances are freezing at 0 degrees F:
Water
These substances are boiling at 0 degrees F:
Oxygen
Press any key to continue...
... or alternatively then:

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
#include <iostream>

class Temp {
public:
	Temp(int t_) : t(t_) {}

	bool isEthylFreezing() const { return ethyl.isFreezing(t); }
	bool isEthylBoiling() const { return ethyl.isBoiling(t); }
	bool isOxygenFreezing() const { return oxygen.isFreezing(t); }
	bool isOxygenBoiling() const { return oxygen.isBoiling(t); }
	bool isWaterFreezing() const { return water.isFreezing(t); }
	bool isWaterBoiling() const { return water.isBoiling(t); }

	void display() const {
		if (isEthylBoiling())
			std::cout << "Ethyl is boiling\n";

		if (isEthylFreezing())
			std::cout << "Ethyl is freeing\n";

		if (isOxygenBoiling())
			std::cout << "Oxygen is boilng\n";

		if (isOxygenFreezing())
			std::cout << "Oxygen is freezing\n";

		if (isWaterBoiling())
			std::cout << "Water is boiling\n";

		if (isWaterFreezing())
			std::cout << "Water is freezing\n";
	}

private:
	class TempPoints {
	public:
		TempPoints(int freezingTemp, int boilingTemp) : freezingTemp(freezingTemp), boilingTemp(boilingTemp) {}

		bool isFreezing(int temp) const { return temp <= freezingTemp; }
		bool isBoiling(int temp) const { return temp >= boilingTemp; }

	private:
		int freezingTemp {};
		int boilingTemp {};
	};

	const static inline TempPoints water { 32, 212 };
	const static inline TempPoints oxygen { -362, -306 };
	const static inline TempPoints ethyl { -173, 172 };
	int t {};
};

int main() {
	int t {};

	std::cout << "Enter temperature (Fahrenheit): ";
	std::cin >> t;

	Temp temp(t);

	temp.display();
}

Last edited on
Topic archived. No new replies allowed.