Testing the following scenarios (of 2 temperatures in Celsius and Fahrenheit)

M

mandy

I have 2 classes: Temperature and the driver class.

Can someone tell me why the following scenarios (in testing 2
temperatures) are notworking right?

Scenarios (1) and (2): If I compare the two temperature in same unit,
i.e both in C and both in F, with one number bigger than the other, I
get error.

(3): Using the same float value, I create a second object in unit C and
the third object in F.

(4): Using the same float value, I create a second object in unit C and
the third object in F.

In both (3) and (4), the program displays - I have a display method of
the temperature netered - the 3rd object with unit of 2nd object but
when comparing using comparison =, >=, <=, scenarios (3) is okay but
scenarios (4) is not.

---------------------------------------------------------------------------------------------------------------------------

Here is the code for the driver:
**********************************************************************************************

HW_413_7_driver

************************************************************************************************/

import java.util.Scanner;
import java.util.*;
import java.io.*;

public class HW_413_7_driver
{

public static void main( String[] Args)
{

System.out.println();
System.out.println();

Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a float value with 2 decimal position for
a temperature.");
float temp = keyboard.nextFloat();
System.out.println("Enter one character for degree scale (C or
F).");
String strScale = keyboard.next();
char scale = strScale.charAt(0);

HW_413_7_Temperature t2 = new HW_413_7_Temperature(temp,scale);

System.out.print("Second Temperature is ");

t2.display(); System.out.println(); System.out.println();


Scanner keyboard3 = new Scanner(System.in);
System.out.println("Enter a float value with 2 decimal position for
a temperature.");
float temp3 = keyboard3.nextFloat();
System.out.println("Enter one character for degree scale (C or
F).");
String strScale3 = keyboard.next();
char scale3 = strScale.charAt(0);

HW_413_7_Temperature t3 = new HW_413_7_Temperature(temp3,scale3);

System.out.print("Third Temperature is ");

t3.display(); System.out.println(); System.out.println();


if ( (t2.equals(t3) )== true)
{
t2.display(); System.out.print(" is equal to "); t3.display();
}
else
{
t2.display(); System.out.print(" is NOT equal to ");
t3.display();
}


System.out.println();

if ( ( t2.isGreater(t3) )== true)
{
t2.display(); System.out.print(" is greater than "); t3.display();
}

else
{
t2.display(); System.out.print(" is NOT greater than ");
t3.display();
}


System.out.println();

if ( (t2.isLess(t3) ) == true)
{
t2.display(); System.out.print(" is less than "); t3.display();
}
else
{
t2.display(); System.out.print(" is NOT less than ");t3.display();
}

System.out.println();

} // end main

}


------------------------------------------------------------------------------------------------------------------------

Here is for Temperature class:
/***********************************************************************************************

HW_413_7_Temperature



Pg 413.7: Write a temperature class that has 2 parameters: a
temperature value (floating point
number) and a character for the scale ('C' or 'F');
- 4 constructors
- 2 accessor methods (get methods) where conversion is done as
required
- 3 mutator methods (set methods)
- three comparison mehtods: is equal to, is greater than, is less
than

************************************************************************************************/

import java.util.Scanner; // for Scanner class
import java.text.NumberFormat;
import java.text.DecimalFormat;


public class HW_413_7_Temperature
{
private float temperature;
private char charScale=' ';

// default constructor
public HW_413_7_Temperature()
{
temperature = 0;
charScale = 'C';
}

// constructor with a parameter
public HW_413_7_Temperature(float newTemperature)
{
setTemparature(newTemperature);
charScale = 'C';
}

// constructor with a parameter
public HW_413_7_Temperature(char newCharScale)
{
temperature = 0;
setCharScale(newCharScale);
}

// constructor with two parameters
public HW_413_7_Temperature(float newTemperature, char newCharScale)
{
//setTemparature(newTemperature);
//setCharScale(newCharScale);

setTemperatureNCharScale(newTemperature, newCharScale);
}


public String getFarenheitTemperature()
{ // use given formula: degreesF= (9 (degreesC/5) + 32;

// here, this keyword contains both float and char; so how to retrive
just float
float degreesF = (9 * ((this.temperature)/5))+ 32;
NumberFormat n = NumberFormat.getInstance();
n.setMaximumFractionDigits(2);
return(n.format(degreesF)); // return as String as required
}


// accessor method ROUND TO THE NEAREST TENTH OF A DEGREE
public String getCelsiusTemperature()
{
// use given formula: degreesC = 5*(degreesF - 32)/9;

// here, this keyword contains both float and char; so how to retrive
just float
float degreesC = 5*((this.temperature) - 32)/9;
DecimalFormat df = new DecimalFormat("###.00");
return(df.format(degreesC)); // return as String as required
}
// mutator method with 1 parameter
public void setTemparature(float newTemperature)
{
temperature = newTemperature;
}

// mutator method with 1 parameter
public void setCharScale(char newCharScale)
{
charScale = newCharScale;
}

// mutator method with 2 parameters
public void setTemperatureNCharScale(float newTemperature, char
newCharScale)
{
temperature = newTemperature;
charScale = newCharScale;
}

// call on driver as t1.equals(t2)
public boolean equals(HW_413_7_Temperature Temperature2)
{
float temp1;
char scale1 = this.charScale;

if (scale1=='C')
temp1 = this.temperature;
else
temp1 = Float.parseFloat(this.getCelsiusTemperature() );

float temp2 = Float.parseFloat(Temperature2.getCelsiusTemperature()
);
// need to parse to float in order to compare

return (temp1==temp2);
}


// call on driver as t1.isGreater(t2)
public boolean isGreater(HW_413_7_Temperature Temperature2)
{
//float temp1 = this.temperature;
//float temp2 = Float.parseFloat(Temperature2.getCelsiusTemperature()
);
// need to parse back to float in order to compare

float temp1;
char scale1 = this.charScale;

if (scale1=='C')
temp1 = this.temperature;
else
temp1 = Float.parseFloat(this.getCelsiusTemperature() );

float temp2 = Float.parseFloat(Temperature2.getCelsiusTemperature()
);
// need to parse to float in order to compare

return (temp1>=temp2);
}

// call on driver as t1.isLess(t2)
public boolean isLess(HW_413_7_Temperature Temperature2)
{
//float temp1 = this.temperature;
//float temp2 = Float.parseFloat(Temperature2.getCelsiusTemperature()
);
// need to parse to float in order to compare
float temp1;
char scale1 = this.charScale;

if (scale1=='C')
temp1 = this.temperature;
else
temp1 = Float.parseFloat(this.getCelsiusTemperature() );

float temp2 = Float.parseFloat(Temperature2.getCelsiusTemperature()
);
// need to parse to float in order to compare

return (temp1<=temp2);

}
// to display temperature entered as it is
public void display()
{
System.out.print(this.temperature);
System.out.print(" in ");
System.out.print(this.charScale);
}

} // end class
 
R

Roedy Green

if ( (t2.equals(t3) )== true)
{
t2.display(); System.out.print(" is equal to "); t3.display();
}
else
{
t2.display(); System.out.print(" is NOT equal to ");
t3.display();
}

That could be collapsed to

System.out.print(" is " + ( t2.equals( t3) ? "" : " NOT " ) + " equal
to" );
 
T

Tom Leylan

Mandy: Your code is overly verbose but frankly I must warn against the
concatenating of individual words into messages based upon conditionals. It
is bad practice and nobody would get away with doing it on a project I was
in charge of. Imagine the trouble to translate into the Spanish, French and
German versions of your software and the cost to identify the messages which
can be output.
 
M

mandy

Tom said:
Mandy: Your code is overly verbose but frankly I must warn against the
concatenating of individual words into messages based upon conditionals.

I fixed all that. Thanks. I took Roedy's suggestion and alos turned
display() to toString().
It is bad practice and nobody would get away with doing it on a project I was
in charge of. Imagine the trouble to translate into the Spanish, French and
German versions of your software and the cost to identify the messages which
can be output.

Gotcha.
 
T

Tom Leylan

Not a problem... I was however suggesting that you "not follow" that
suggestion as it turns the "simple" into the "complex". Software
development isn't about being clever.
 
M

mandy

Tom said:
Not a problem... I was however suggesting that you "not follow" that
suggestion as it turns the "simple" into the "complex".

Oh, then I misunderstood.
Software development isn't about being clever.

I would love to know what are the criteria in SW devleopment.
 
T

Tom Leylan

The secret to good software design is "simplicity".

Take a look at this part of your code:

if ( ( (scale1 == 'f' || scale1 == 'F') && (scale2 == 'f' || scale2 ==
'F') ) || ( (scale1 == 'c' || scale1 == 'C') && (scale2 == 'c' || scale2 ==
'C') ) )

The level of complexity alone tells me the approach is wrong and I suspect
the answer is "probably" wrong or at best the answer has been brute-forced
to return a correct value. I wouldn't trust the algorithm because I don't
see one. :)

Consider that a simple task like comparing two temperatures _can't_ require
unreadable code or what will happen when you start computing things that
aren't so easily understood? What happens to this code when you add "K" to
support Kelvin to TempConvert 2.0?

As you review your code ask yourself questions like; Why can't I be certain
that the "scale" is an upper or lower case letter?

Have you failed to define it one way or the other in your class? By not
defining it you're forcing yourself (and you did some 8 times) to compare
both upper and lowercase with every use. You had one task and in the course
of solving it managed to created an impediment to solving it. For
argument's sake let us say that you can't control the code that returns
charScale. Surely you could capitalize the return value in the assignment
to scale1 and by doing this eliminate 1/2 of the tests.

Better yet your Temperature class could forget about letters. How about a
few static final public int values representing FAHRENHEIT, CELSIUS and
KELVIN? That way nothing that uses the objects needs to know about the
magic letters and they can test for Temperature.FAHRENHEIT instead.

Look again at your isLess() method. Why is isLess() trying to determine
what charScale is doesn't the temp object process the conversion? If so
doesn't it become something along the lines of the following:

public boolean isLess( Temperature temp2 ) {
return ( this.AsCelsius() <= temp2.AsCelsius() )
}

Do we care what setting either temperature has? I think we just need them
using the same scale for the sake of comparison.

SIMPLE is good.
 
R

Roedy Green

if ( ( (scale1 == 'f' || scale1 == 'F') && (scale2 == 'f' || scale2 ==
'F') ) || ( (scale1 == 'c' || scale1 == 'C') && (scale2 == 'c' || scale2 ==
'C') ) )

here is a case where an enum comes is handy. You have an enum for
each temperature scale F C K .

The letter becomes a property of the enum. The magic numbers become a
property of the enum. You could then add new temperature scales just
by adding another enum constant.


You keep distinct your code of factoids about a particular scale out
of the general code.
 
A

Andrew McDonagh

Roedy said:
here is a case where an enum comes is handy. You have an enum for
each temperature scale F C K .

No a enum with with anything other than its enumeration value, is
normally a State object in hiding.

That said, for this particular case, this is where a Strategy Object is
handy. Mixing Enums and States and Strategies into one class will
create a mess of a design.

You really seemed to have a thing about Enums lately.... almost to the
point where you have a hammer and everything is a nail...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top