Win a copy of Microservices Testing (Live Project) this week in the Spring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Liutauras Vilda
  • Henry Wong
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Al Hobbs
  • Carey Brown
Bartenders:
  • Piet Souris
  • Mikalai Zaikin
  • Himai Minh

CurrencyConverter Java program

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello All,

I need assistance with the following project which seems very complicated. I got a code from the forum but it is not using the same attribute. How do modify the code to use the attribute from the details below? Thank you

Class Name: CurrencyConverter
Attribute: exchangeRate
-Exchange rate to convert a US Dollar to ringgit

Constructor: to set the initial value for the attribute
Member methods: • double fromRinggit (…)
-Converts a given amount in ringgit into an equivalent amount in US Dollar  

                                • double toRinggit(..)
-Converts a given amount in the US Dollar into an equivalent ringgit amount







 
Master Rancher
Posts: 4833
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please edit your post and wrap the code in code tags:  Select the code and press the button labelled: Code

You can delete the two empty sections of code tags.
 
Saloon Keeper
Posts: 25816
184
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Note to Norm: Actually, Pubalan did attempt to use Code tags, but didn't realize that the end tag goes at the end of the text to be highlighted, So what we had was Start/End sample-code Start/End when it should have been Start sample-code End.

I fixed it.

And welcome to the Ranch, Pubalan! Although to make code easier to read on-screen, if you could reduce the number of blank lines it would help.
 
Marshal
Posts: 76079
362
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch (again)

Please don't mix doubles (line 8) and floats (line 23). My opinion is, don't use floats at all, unless some other code requires you to.
Don't declare multiple variables on line.
I see you are using Eclipse and have found the best way to stop warnings about Scanners reading System.in
Don't write long methods; the ideal length of the main() method is one statement.
Don't use multiple ifs when you could use switch‑case instead.
If you look at lines 28‑31 and 34‑37, you will find they are identical
 
Norm Radder
Master Rancher
Posts: 4833
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another important point about the code is that it should not hard code the conversion rate in the formulas.
There should be one variable the has the conversion rate.  That variable can then be used in the formulas as needed.
 
 
Tim Holloway
Saloon Keeper
Posts: 25816
184
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote: My opinion is, don't use floats at all, unless some other code requires you to.


integer and double are the "natural" data types for Java. Any work with lesser-sized values will fold up into those forms unless you stringently avoid it. And once upscaled, you can get yelled at by the compiler for attempting to assign those fatter values to skinnier variables. Might as well save the effort, except in cases where storage use is critical. Like if you have 100,000 class instances containing floating-point values and you only need 6.5-digit precision anyway.

Campbell Ritchie wrote:Don't write long methods; the ideal length of the main() method is one statement.




The virtue here is that main() is always very simple. And it's simple to tack on small snippets to the main code for extensions, debugging, general setup calls and so forth. Just don't let it grow!

In truth, any method that runs more than about 20 lines of code is suspect. You could break your current main method into a read-data method, a compute method(s) and output method and have the 3 of them be invoked serially (and repeatedly) by doIt(). Each method should Do One Thing and Do It Well™ (Palm Corporation, I think).
 
Tim Holloway
Saloon Keeper
Posts: 25816
184
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Norm Radder wrote:Another important point about the code is that it should not hard code the conversion rate in the formulas.
There should be one variable the has the conversion rate.  That variable can then be used in the formulas as needed.
 


Good point. Currency exchange rates vary by the minute. However, since "Constants aren't and variables won't":

For a basic app. More sophisticated apps could obtain exchange rates in a more dynamic manner.

Note that I capitalized RINGITT_PER_DOLLAR. This is a convention inherited from the C Programming Language back in the days when C didn't have its const attribute. It's common, but not universal in Java. Just makes it visually obvious that the value is (allegedly) immutable.
 
Campbell Ritchie
Marshal
Posts: 76079
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would give that 4.17 private access unless it is used in several other places, in which case it should have public access.
It is immutable . . . . until somebody rewrites the source code. Then you can have all sorts of other problems, depending which class has been most recently compiled.Gues what your output will be for lines 2 4 and 6.
 
Tim Holloway
Saloon Keeper
Posts: 25816
184
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I would give that 4.17 private access unless it is used in several other places, in which case it should have public access.



Serve me right for doing a copy-and-paste. Yup. Make it private.

One thing IBM taught me by bad example (OS/2) is that there should be one and ONLY one authoritative source for everything and in this case it would be the currency conversion operation not the actual conversion factor.
 
Sheriff
Posts: 17031
298
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's another design to consider. A conversion rate is temporal in nature, that is, it can change over time. At any given point in time, however, there is a specific conversion rate.

I would also look into various terms in the problem domain. In this case, there is "base currency" and "quote currency" as well as "currency pair."

From Investopedia:

In the forex market, currency unit prices are quoted as currency pairs. The base currency – also called the transaction currency - is the first currency appearing in a currency pair quotation, followed by the second part of the quotation, called the quote currency or the counter currency. For accounting purposes, a firm may use the base currency as the domestic currency or accounting currency to represent all profits and losses.

... the base currency represents how much of the quote currency is needed for you to get one unit of the base currency

Given this, I would probably try defining a CurrencyPair class with attributes of baseCurrency, quoteCurrency, and exchangeRate.

Instances of this class would be immutable value objects with final members rather than constant literal values.
 
Norm Radder
Master Rancher
Posts: 4833
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think some of this goes past what a beginner can do.
 
Campbell Ritchie
Marshal
Posts: 76079
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Would your currency pair object represent a transaction? Would you print it from toString() like this?

4170Ringgit @4.17 bought us $1000

It would be easier if you use the three letter abbreviations:-

4170MAR @4.17 bought us 1000USD

In that case you would want five fields, base currency name, base currency amount, rate, quote currency name (supplied to the constructor) and you would calculate quote currency amount.
 
Campbell Ritchie
Marshal
Posts: 76079
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A beginner should be able to work out a CurrencyPair class. I have told you what fields it should have. Of course, we all know it is wrong to use floating‑point arithmetic for money; you should use BigDecimal and round (usually to two decimal places). Look at  this old thread  where I contributed.
 
Tim Holloway
Saloon Keeper
Posts: 25816
184
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:A beginner should be able to work out a CurrencyPair class. I have told you what fields it should have. Of course, we all know it is wrong to use floating‑point arithmetic for money;



Normally that is true. But currency quotes are like interest calculations. At this moment, the exchange rate for US Dollars to Euros is 0.98131448 and the rate for US Dollars to Pound Sterling is 0.82407607.

The time to use BigDecimal over floating-point is after the conversion has been done and actual money is involved.
 
Sheriff
Posts: 6962
2
Eclipse IDE Debian Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's not teally been mentioned in this thread so far, but the class as originally presented is doing far too much, as it combines input, selection of operations, calculations, and output into a single, hard-to-read, hard-to-reuse and hard-to-test lump.

It's entirely possible for good code to be simple and easily tested. It just means that if you need to solve a complex problem you combine the simple, tested, reliable, parts into a larger application.

In this case the actual currency conversion class really only needs a constructor to set the exchange rate plus a pair of conversion methods, and each of these should contain just one line of code.  To make sure it works you need some kind of test cases. Personally I would use JUnit, but if you are not familiar with that, you can get away with a tester class with a main method which creates a currency converter object and calls its methods several times with different values until you are happy that it is fully working.

Once you have that, you can move on to making a user interface. This will probably take the form of another class with a main method which also creates a currency converter object from the same converter class, then reads values from the user, passes them to the appropriate conversion methods, and prints out the results.

By the end, you should have a converter class, a test class, and a user interface class, each with clear responsibilities and easy-to-read code.

Later, if you need to, you can then easily re-use your converter class in any situation you want, perhaps with a web interface, or in a mobile app, or with a JavaFX desktop interface. By taking this approach, you can be confident that it works, and you don't need to change it to be used in different applications.
 
Frank Carver
Sheriff
Posts: 6962
2
Eclipse IDE Debian Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's an example of what I mean by creating your own "test suite" if you don't want to use a testing tool such as JUnit



If all goes well, the result of running the CurrencyConverterTester class should be:
test 1, 1USD->4.167MAR: PASS
test 2, 1MAR->0.24USD: PASS
test 3, 0MAR->0USD: PASS
test 4, 0USD->0MAR: PASS

 
Junilu Lacar
Sheriff
Posts: 17031
298
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nice start, Frank.

Transforming this to something that's more generic isn't too difficult.

First, you rename a few things to use terms specific to the Forex domain:

You can then add a couple of fields to make the intent clearer and to make the class more user-friendly:

Here's a sample run in jshell:

jshell> var myrUSD = new CurrencyPair("MYR/USD", 0.24)
myrUSD ==> 1 MYR = 0.2400 USD

jshell> myrUSD.toBase(1)
$19 ==> 4.166666666666667

jshell> myrUSD.toQuote(1)
$20 ==> 0.24

 
Junilu Lacar
Sheriff
Posts: 17031
298
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's a challenge: Write a method to get the converse of a CurrencyPair object. That is, given a MYR/USD currency pair, calling the method would give back a USD/MYR currency pair with the equivalent exchange rate.
 
Junilu Lacar
Sheriff
Posts: 17031
298
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You could also take advantage of the standard java.util.Currency class:
 
Frank Carver
Sheriff
Posts: 6962
2
Eclipse IDE Debian Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, I've not done much forex work, so the terms "base" and "quote" are unfamiliar, but I'll go with that.

Personally I have an aversion to doing "work" in constructors, particularly work which can be done ahead of time or can fail due to things such as an unrecognized currency code or a malformed string.  I still have nightmares about trying to create a string from bytes before the introduction of StandardCharsets

With all that in mind, I'd probably consider changing the primary constructor to take two pre-made Currency objects, and provide helpers to do the the string split and currency code lookup if needed:

 
Junilu Lacar
Sheriff
Posts: 17031
298
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Frank Carver wrote:
Personally I have an aversion to doing "work" in constructors, particularly work which can be done ahead of time or can fail due to things such as an unrecognized currency code or a malformed string.

With all that in mind, I'd probably consider changing the primary constructor to take two pre-made Currency objects, and provide helpers to do the the string split and currency code lookup if needed:


Oddly enough, that's exactly what I ended up doing while playing around with the design of this class. The motivation, however, was because of the way calling one constructor from another using this() works in Java.

You might also notice my solution to the challenge I posed earlier to create a method that returns the converse of a CurrencyPair.
 
pubalan somasundram
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Junilu and everyone who replied back. Thank you very much for your inputs

I am very sorry about this but i have missed out an important requirement from the same question which is to not add additional attributes. Can i use the same code given by you earlier even with this requirement? Sorry for the trouble again.



Add TWO more suitable and unique member methods for the above class. Ensure these new methods do not functionally overlap with the existing methods. You are not allowed to add additional attributes. Provide reasons in the form of “program comments” (80-150 words) on why you choose these methods.
Test your class program by creating its object in a main() method. The object must produce an appropriate output.



Junilu Lacar wrote:

Frank Carver wrote:
Personally I have an aversion to doing "work" in constructors, particularly work which can be done ahead of time or can fail due to things such as an unrecognized currency code or a malformed string.

With all that in mind, I'd probably consider changing the primary constructor to take two pre-made Currency objects, and provide helpers to do the the string split and currency code lookup if needed:


Oddly enough, that's exactly what I ended up doing while playing around with the design of this class. The motivation, however, was because of the way calling one constructor from another using this() works in Java.

You might also notice my solution to the challenge I posed earlier to create a method that returns the converse of a CurrencyPair.

 
Junilu Lacar
Sheriff
Posts: 17031
298
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

pubalan somasundram wrote:Can i use the same code given by you earlier even with this requirement?


You were given very specific instructions; I doubt you can use any of the code we shared for your assignment. What you can do, however, is study the examples we gave and try to understand how we're thinking about the problem. Figure out for yourself some of the things we're doing to solve a different version of the problem you were given.

One thing I can say is that the instructions you were given, in my opinion, were not really for the benefit of the student trying to learn Java. In real world programming, we're not given such artificial constraints. Real-world problems don't come with such specifics about the solution that you, the programmer, should adhere to. Rather, it's up to the programmer to use their creativity and skill to come up with an appropriate solution.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic