Win a copy of The Java Performance Companion this week in the Performance forum!

# Need Help with java.lang.NullPointerException

Lou Pelagalli
Ranch Hand
Posts: 150
1
Hi Richard,

I can't see the logic in that !

The only logic I have in that is that it works for temperature, but you're right it is arbitrary.

As long as all the other units are relative to the base unit then it doesn't matter.

Maybe I'll make it grams for Weight and Mass, that's about in the middle. But I think for Winston's suggestion to work,

F/C = ((C/F + 40) * K) - 40
, for temperature the base would have to be Kelvin.

Lou

Junilu Lacar
Bartender
Posts: 7480
50
Lou Pellegrini wrote:
Richard's and Junilu's posts about reciprocals are more about units than the mathematical definition of reciprocals, which produced correct results in one direction only.

(Value / fromMks) = units, then (units * toMks) yields the correct results in both directions.

Not sure what you mean by that first part. Dimensional analysis aside, reciprocals are a pretty straightforward concept. Unless you tried to use multiplication both ways (thus yielding a correct result in only one direction), you should get correct results both ways using the same number: multiply by it one way, divide by it going the other way.

Winston Gutkowski
Bartender
Posts: 10422
63
Lou Pellegrini wrote:But I think for Winston's suggestion to work,
F/C = ((C/F + 40) * K) - 40
, for temperature the base would have to be Kelvin.

Not at all; especially since Kelvin is measured in the same units as Centigrade, which is far more commonly used, so it would seem sensible to me to use the latter as your base. Then "convert to base" for Kelvin is simply K - 273.15.

As far as other systems go, I suspect it's best to use the standard that they do. For example, SI has specifically defined base units and for mass it's the kilogram, which is far from being the smallest.

For imperial, you may well have to do a bit of hunting; but for distance for example, I believe that the inch has now been standardized to be exactly 2.54 centimetres, so it might be worth making that your base unit.

HIH

Winston

Lou Pelagalli
Ranch Hand
Posts: 150
1
Hi Junilu,

Not sure what you mean by that first part. Dimensional analysis aside, reciprocals are a pretty straightforward concept. Unless you tried to use multiplication both ways (thus yielding a correct result in only one direction), you should get correct results both ways using the same number: multiply by it one way, divide by it going the other way.

That's exactly what I meant - trying to use reciprocal multiplication in both directions.

Using units allowed for the input to decide when to do the conversion and provided correct results in both directions with a single process.

Less code = less stink!

Lou

Junilu Lacar
Bartender
Posts: 7480
50
Lou Pellegrini wrote:Hi Junilu,
That's exactly what I meant - trying to use reciprocal multiplication in both directions.

Using units allowed for the input to decide when to do the conversion and provided correct results in both directions with a single process.

Less code = less stink!

Less code is not necessarily less stink. It all depends on semantics and the names you choose, and the structure of the code. If you've ever read Martin Fowler's "Refactoring" book, the first refactoring example given at the beginning of the book actually ends up with more code than the original unrefactored version. However the refactored code is cleaner and has better separation of concerns. Until I see your finished work, I couldn't tell you if there was anything I'd do differently. I would say that my inclination would still be to have two separate methods: convertTo() and convertFrom() where convertTo would use the reciprocal of the number used by convertFrom.

Winston Gutkowski
Bartender
Posts: 10422
63
Lou Pellegrini wrote:That's exactly what I meant - trying to use reciprocal multiplication in both directions.

Which is fine if you can; however, as you've seen above °K→°C is not a multiplication, it's an offset, regardless of which one you choose as the base. Now you can also reverse that, but I'd follow Junilu's advice to begin with, and then see if you can't normalize the process later.

One thing that's probably worth noticing is that a single unit, while it might contain some useful information, doesn't actually give you the conversion; its the intersection between two units that does, so if you have n units of one particular scheme (eg, SI mass) and m units of another one (eg, Avoirdupois) of the same type, you have n * m possible conversions. That's why I suggested using a "base" unit.

Winston

Junilu Lacar
Bartender
Posts: 7480
50
If you want to see a library that has pretty much the design choices that we've been pushing here, take a look at Joda-Money: http://www.joda.org/joda-money/apidocs/index.html

You'll see that Money has a convertTo method, among others. There's a CurrencyUnit and CurrencyUnitDataProvider with a registerCurrency() method, much like the Factory and register thing I mentioned a few posts back. This kind of design is where you end up after numerous refactorings though; it hardly ever comes from a grand "design up front" effort.

Winston Gutkowski
Bartender
Posts: 10422
63
Winston Gutkowski wrote:as you've seen above °K→°C is not a multiplication, it's an offset

Actually, it just occurred to me that we're actually dealing with apples and oranges here.

Everything we've been talking about other than temperature - inches, metres, grams, currency etc - are units; Kelvin is a system or "scale". Its unit (1 "degree") is the same as Centigrade, but its start point is different. The other two are also scales, but Fahrenheit also has a different unit: 5/9ths of a degree Centigrade. So in fact there are only 2 major temperature units, but 3 scales based on them.

A few other examples of scales would be clock time (ie, timezones), hardness (of which there are several), and tonal scales. I suspect there are lots of others, but those are the ones which spring to mind.

HIH

Winston

Junilu Lacar
Bartender
Posts: 7480
50
Winston Gutkowski wrote:Kelvin is a system or "scale". Its unit (1 "degree") is the same as Centigrade, but its start point is different.

Actually, assuming the wikipedia entry is accurate, the Kelvin IS the unit of measure; it's just Kelvin, not degree Kelvin. Kelvin is often used in conjunction with degree Celsius, which has the same magnitude.

Winston Gutkowski
Bartender
Posts: 10422
63
Junilu Lacar wrote:Actually, assuming the wikipedia entry is accurate, the Kelvin IS the unit of measure.

Point taken. I was simply trying to point out the difference between the unit, which is simply a magnitude, and so directly convertible with any other unit of the same type by some factor; and a system or scale, which is where you get your offsets and possibly different styles (eg, logarithmic vs. linear).

Winston

Junilu Lacar
Bartender
Posts: 7480
50
You're right about that, Winston. That's what I was getting at when I said there's a difference between a conversion factor and a conversion formula. A factor is just one number. A conversion formula takes into account the scale and the relative reference point. This goes back to your assertion that the OP should decide on a base unit.

Lou Pelagalli
Ranch Hand
Posts: 150
1
Hi All,

I finally got a couple of simple conversions working properly. Had trouble with BigDecimal.divide(BigDecimal) scaling the decimal points correctly. Seems that if you don't have the BigDecimal.scale(int) set correctly the divide method returns the numerator - ick.

Junilu wrote
Maybe you could show your proposed XML for defining the factors you'd use for converting Fahrenheit to Celcius and vice versa. What about the XML for converting Kelvin, Rankine, and all the other temperature scales listed here: http://en.wikipedia.org/wiki/Comparison_of_temperature_scales#Comparison_of_temperature_scales? Then, when you have that, show some sample code that would use the objects you deserialize from that XML. Would that code have a lot of conditional statements and checks for specific classes of conversions? If it does, then it's smelly, brittle code. That would be my point. Hope this helps clarify my ramblings a little.

All the code is posted below, with the exception of simple-xml-2.7.jar. I tried to upload it all in a zip file but that's not allowed.

MeasurementTest.java is the main class.

Feedback would be appreciated.

Winston wrote

No long lines Winston, max = 80 characters, but I can't figure out how to get Eclipse to use 62 characters.

Thanks,

Lou

MeasurementTest.java

MKSFactors3.xml

Converter.java

Measurement.java

Scheme.java

Category.java

Conversions.java

Junilu Lacar
Bartender
Posts: 7480
50
A few things:

1. Do some research on double checked locking. Start here: http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java . Again, I have to question why you even have to worry about things like lazy initialization at this point. This is premature optimization. Try to stop doing it. It's the root of all evil (per Donald Knuth).
2. Converter class violates the Single Responsibility Principle. You mix concerns of converting with concerns of formatting. Leave formatting out of it.
3. Code is not very object-oriented. Note that if you follow advice in #2, you will be left with no "internal state" for the Converter class. And all the "knowledge" about conversions is actually kept outside of the Converter class. This code is leaning more towards Functional Programming than Object-Oriented Programming.

Lou Pelagalli
Ranch Hand
Posts: 150
1
Hi Junilu,

1. Do some research on double checked locking. Start here: http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java . Again, I have to question why you even have to worry about things like lazy initialization at this point. This is premature optimization. Try to stop doing it. It's the root of all evil (per Donald Knuth).
2. Converter class violates the Single Responsibility Principle. You mix concerns of converting with concerns of formatting. Leave formatting out of it.
3. Code is not very object-oriented. Note that if you follow advice in #2, you will be left with no "internal state" for the Converter class. And all the "knowledge" about conversions is actually kept outside of the Converter class. This code is leaning more towards Functional Programming than Object-Oriented Programming.

1. Ok.
2. Ok.
3. I agree the converter is a function. Servlets are coming.

Thanks,

Lou

Junilu Lacar
Bartender
Posts: 7480
50
Lou Pellegrini wrote:Hi Junilu,
3. I agree the converter is a function. Servlets are coming.

Take care to avoid a beginner mistake of loading up your servlet with anything more than flow control. Having more than flow control logic in a servlet is manageable only for the smallest of applications. Search for "layering of web applications" and "business delegate"