Need help with Java homework - java

I need some help with my homework assignement. My assignment is to create a program that creates a Till object, takes a payment, issues exact change, tells me which coins I need to use and then tells me how much is in the till after. Below is the code I have written. The USmoney class is done and is working. The teacher offered a cheat sheet. However it's the main class (CoinCalc), getting the till to take the payment and subtract the payment from the amount paid to give me the change that I'm having issues with. Any help would be most appreciated.
public class USmoney {
int dollars = 0;
int cents = 0;
public USmoney(int newcents) {
dollars = newcents /100;
cents = newcents %100;
}
public USmoney(int dollars, int cents) {
this.dollars = dollars;
this.cents = cents;
}
public int getDollars() {
return dollars;
}
public int getCents(){
return cents;
}
}
public class CoinCalc {
public static void main(String[] args) {
USmoney Till1 = new USmoney(100,0);
USmoney billTotal = new USmoney(49);
USmoney amountPaid = new USmoney(100);
double penny = 1;
double nickel = 5;
double dime = 10;
double quarter = 25;
double[] Coin = new double []{penny,nickel,dime,quarter};
}
private void changeFor(USmoney billTotal, USmoney amountPaid) {
}
}

This is a varient of the knapsack problem, you have a couple of steps to implement
Calculate total change
Satisfy change using smallest number of coins
I'd start by implementing a method with the first signature in your USMoney class, and then read up on the knapsack problem in order to implement the second method.
public USMoney subtract(final USMoney value);
public double[] getCoins(final USMoney value);

There are two issues here, which you can consider separately.
Are you able to describe algorithmically how to determine the answer to your question?
Given this description, can you turn it into Java code?
I'll start by addressing the first item: It is essential that you understand exactly what the input is and what the required output is and that you are able to give a precise pseudo code description of how to solve the problem. If you don't know what pseudocode is, then look it up on Wikipedia. Then you can start thinking about how to code it in Java.
From an algorithmic perspective, your problem is very simple.
Say the customer pays amount X and for an item that costs amount C.
First you must check that X >= C. otherwise the customer won't have paid enough, and you can stop right there.
Assuming that X >= C, and that you are able to give exact change, the amount of money in the till will have increased by C after the transaction completes, as this exactly what the customer ends up paying.
Now, the amount of change you have to give should equal X-C. Call this Y.
Test how many times the biggest coin you have available divides Y:
Say the biggest coin has value V, then you should give back the customer Y/V coins of this value.
Afterwards, you need to pay back the customer the remaining money Y'=Y-(Y/V)*V. Make sure you know how division works in Java (see link at the end of this post).
Repeat the procedure to pay Y' back using the second biggest coin and so on.
2.
I won't write out the whole thing in Java, but there are some things you should consider.
Does the Till contain "money" without it being specified exactly what bills/coins it contains, or should you be representing the money as a number of bills and coins?
You will be doing integer division, so your coin values should not be doubles but ints.
You need to access the coin values (how much a dime is worth etc.) from inside the function that calculates change, so the values of the different coins should probably be declared as static member variables of the class CoinCalc, not inside a function.
You need to make sure you know how basic if-else statements and while loops work and how to assign to variables. Then you should be able to code the solution.
You also need to decide what exactly the solution is. It could be a list of coin names with a name repeated for each time it is needed, e.g. [dime,penny,penny], or maybe an array of four numbers with that say how many quartes, dimes, nickels and pennies are needed. If you want a list, you should learn how list datastructures work in Java, by reading the entry LinkedList in the Java documentation.
Good luck!
NB: Because I'm a new user, I can't post as many links as I would like. You can find a good description of division in Java by googling java division and selecting the link to mindprod.com.

It looks like you want help with your changeFor algorithm, so here's an outline:
First subtract billTotal from amountPaid. That will get you how much change to make.
Then make some variables to hold how much change you're giving back. For each of quarter, dime, nickel, penny, if changeRemaining is > the value of the coin, add a coin and subtract the value. Do this for each coin in order until that coin's value fails the test, then move on to the next coin.

In order to call the changeFor() method you need a reference to a CoinCalc class. You can do this different ways, one way is to declare a variable of the CoinCalc class in the main() method like so:
CoinCalc cc = new CoinCalc();
cc.changeFor(billTotal, amountPaid);
But there are still problems, the method changeFor() currently does nothing and the way you have declared the till object and coin array they are not accessible in the changeFor() method.
So work on that problem for a bit then get back to us...
EDIT
Here is how I would structure it, billTotal is a float amountPaid is a USMoney object that internaly keeps track of each denomination of money ($1 bill, quarter, dime, nickel and penny). When someone pays they give you differing amounts of those kinds of money. USMoney needs and method that will return the value of the kinds of money it has (sum of dollars, quarters, etc).
till is another instance of USMoney that has an initial value of the different denominations of money.
USMoney has a method called changeFor(float bill, USMoney paid) that returns another instance of USMoney. You would then call it like so:
USMoney change = till.changeFor(bill, amountPaid);
The changeFor() method then has to determine how to make change based on what is in the till and the difference between bill and the value of amountPaid. NOTE if you don't have enough quarters your calculations should be smart enough to use dimes and nickels if it has enough. If you want to really get clever throw an exception if you can't make change.

Related

Is there a better method for randomizing functions besides Random?

I have 2 strings in an array. I want there to be a 10% chance of one and 90% chance to select the other. Right now I am using:
Random random = new Random();
int x = random.nextInt(100 - 1) + 1;
if (x < 10) {
string = stringArray(0);
} else {
string = stringArray(1);
}
Is this the best way of accomplishing this or is there a better method?
I know it's typically a bad idea to submit a stack overflow response without submitting code, but I really challenge this question of " the best way." People ask this all the time and, while there are established design patterns in software worth knowing, this question almost always can be answered by "it depends."
For example, your pattern looks fine (I might add some comments). You might get a minuscule performance increase by using 1 - 10 instead of 1 - 100, but the things you need to ask yourself are as follows :
If I get hit by a bus, is the person who is going to be working on the application going to know what I was trying to do?
If it isn't intuitive, I should write a comment. Then I should ask myself, "Can I change this code so that a comment isn't necessary?"
Is there an existing library that solves this problem? If so, is it FOSS approved (if applicable) / can I use it?
What is the size of this codebase eventually going to be? Am I making a full program with microservices, a DAO, DTO, Controller, View, and different layers for validation?
Is there an existing convention to solve my problem (either at my company or in general), or is it unique enough that I can take my own spin on it?
Does this follow the DRY principle?
I'm in (apparently) a very small camp on stack overflow that doesn't always believe in universal "bests" for solving code problems. Just remember, programming is only as hard as the problem you're trying to solve.
EDIT
Since people asked, I'd do it like this:
/*
* #author DaveCat
* #version 1.0
* #since 2019-03-9
* Convenience method that calculates 90% odds of A and 10% odds of B.
*
*/
public static String[] calculatesNinetyPercent()
{
Random random = new Random();
int x = random.nextInt(10 - 1 ) + 1
//Option A
if(x <= 9) {
return stringArray(0);
}
else
{
//Option B
return stringArray(1);
}
}
As an aside, one of the common mistakes junior devs make in enterprise level development is excessive comments.This has a javadoc, which is probably overkill, but I'm assuming this is a convenience method you're using in a greater program.
Edit (again)
You guys keep confusing me. This is how you randomly generate between 2 given numbers in Java
One alternative is to use a random float value between 0..1 and comparing it to the probability of the event. If the random value is less than the probability, then the event occurs.
In this specific example, set x to a random float and compare it to 0.1
I like this method because it can be used for probabilities other than percent integers.

How to handle the case that a single simple test case will drive the whole implementation?

When I learn "Test Driven Development", I found an interesting case from the book "The Productive Programmer":
You need to find all factors of a "complete number". A complete number is the sum of all its factors (except the one which equals to the number itself) is equal to the number. So 6 is the minimal complete number, and its factors are 1, 2, 3.
If I want to TDD, first I want to test an simplest test case:
#Test public void completeNumber6() {
CompleteNumber completeNumber = new CompleteNumber(6)
assertEquals(completeNumber.findFactors(), new Int[] {1,2,3});
}
But ! The problem is this simplest case will driven all the implementation of findFactors(), which seems too much for me.
The author gives some suggestions, we can split the requirements into several steps:
check if number is the factor of another one
provide a way to collect some factors into a collection
check each smaller number to see if it's the factor of the given number, collect them
check if the sum of the collected factor equal to the given number
And we can TDD the first 2 steps first:
#Test public void testIsFactor() {}
#Test public void testAddFactor() {}
So there will be 2 public (at least non-private) methods after that:
boolean isFactor(Int n1, Int n2)
void addFactor(Int factor)
The problem is these 2 methods should be private after the whole implementation, since they should only used by findFactors internally!
But if they are changed to private, what shall we do with the exsiting test cases for them?
The author suggests we can change them to private, and use Java refection API to get and test them. Sounds possible, but I'm not sure if it's a good practice to do so.
I also asked some friends, and they gave some other options:
Keep the methods isFactor and addFactor non private as is, that's acceptable
Extract a class FactorChecker and FactorCollector for the 2 methods
Change them to private, and delete the test cases since the functionality of them has been tested in the later test cases (for step 3 & 4)
I'm really puzzled now, which approach is the best practice of TDD?
Seems to me that the fact that the question states these are complete numbers is somewhat irrelevant. You can calculate the factors of any whole number. So given that I'd start with implementing findFactors(1) and then work my way up.
That makes this a slight variation on the classic Prime Factors Kata, the only difference being that you add a 1 to list of factors.

General query about efficiency

I'm relatively new to Java, having taken my first class in it little under a year ago, and I have a question regarding efficiency. I know that
Random rng = new Random();
int num = rng.nextInt(101);
System.out.println("Random number is: " + num); //Example 1
and
Random rng = new Random();
System.out.println("Random number is: " + rng.nextInt(101)); //Example 2
are equivalent. However my question is which is faster to calculate? In my mind, the first example stores a variable, which takes up RAM. The second example doesn't store anything, but has to calculate a lot more things whilst printing than the first example.
In my computing classes, I was taught that information coming from the CPU's internal registers is a lot faster than information coming from the RAM. Does that mean example 2 is technically more efficient for not having stored the number variable before printing it?
I'm of course assuming I will not need the randomly generated number at another point in the program.
Thank you for any and all help :)
Kind regards
Any sane compiler will be able to perform such compile time optimizations to reduce extra lines of code which are there to improve readability.That is not specific to Java(where JIT takes the optimizations to the next level)
Since the number is going to be converted to a String for the concatenation, it will probably be put in memory on the stack anyways.

I would like the Arrays to remember it all

This is about my assignment so I would appreciate generic answers with explanation.
I have a for-loop which I have to make for an online ordering system. The for-loop and ordering all works fine but if the same item is put in twice, then it forgets the previous order for the same item and only remembers the latest one. I am required to use simple arrays and for-loops so I would appreciate if the solution/help was also of this basic level.
My code looks something like this (NOTE: The following is just an example of what part of the loop looks like--this is not a complete program):
for (int i = 0; i < 3; i++) { //I changed the loop so there's no confusion about
//what I am actually asking about.
if (order.equalsIgnoreCase(computer) {
int price = quantity[i] + itemcode;
}
}
To explain further, this loop and the if statement work perfectly if a certain item is only ordered once. But if the user enters, say, an order for a computer once and then after 3 more orders, orders another computer, then the output does not add the previous order in the new order but only remembers the latest one.
I would appreciate any work around suggested for this but again, since this is for my studies, I would appreciate explanations rather than direct solutions.
Please ask me questions in case this is not clear.
"Forgets" suggests that you are overwriting something in your code rather than, say, just incrementing. Go through your code, see what parts of it gets reset when you place a new order. For instance, if you are doing
quantity[1] = getNumberFromUser("How many apples?");
then this would obviously erase the old value each time. If you want to merely increment the number of apples, do something like
quantity[1] += getNumberFromUser("How many apples?");
Another general advice is to use print statements to debug your code. That way you can see for yourself what really happens. Learning to use a real debugger would also be of great benefit.
if you have two or more typres of products and want to calculate the price for all the orders together then you can try the following code,, i think thats very simple,,
int price=0;
for (int i = 0; i < 3; i++) { //I changed the loop so there's no confusion about
//what I am actually asking about.
if (order.equalsIgnoreCase(computer) {
price += quantity[i] + itemcode; //use the previous value of price
}
}
or else if you want to have history for each product separately then you have to try the same with a array of price for each product type..
If you cant get the answer then comment here,,

help regarding rounding off numbers

float per = (num / (float)totbrwdbksint) * 100;
i m getting the value of per as say 29.475342 . i want it to round off upto two decimal places only.like 29.48 .how to achieve this?
You should do this as part of the formatting - the floating point number itself doesn't have any concept of "two decimal places".
For example, you can use a DecimalFormat with a pattern of "#0.00":
import java.text.*;
public class Test
{
public static void main(String[] args)
{
float y = 12.34567f;
NumberFormat formatter = new DecimalFormat("#0.00");
System.out.println(formatter.format(y));
}
}
As Jon implies, format for display. The most succinct way to do this is probably using the String class.
float f = 70.9999999f;
String toTwoDecPlaces = String.format("%.2f", f);
This will result in the string "71.00"
If you need to control how rounding is done you should check BigDecimal ist has several rounding modes. http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html
You need to be careful here, this answer is not related to java, it relates to all aspects of decimals in many programming languages hence it is generic. The danger lies with rounding numbers, is this, and it has happened in my experience and know that it can be tricky to deal with:
Supposing you are dealing with prices on items, the pricing you get from a retail supplier may be different to the price the computer tells you, sure it is marginally small, but it could add up to big money.
Adding a sales tax on a price can either be positive or negative, it can impact the operating margin of the profit/loss balance sheets...
If you are in this kind of arena of development, then my advice is not to adjust by rounding up/down...it may not show up on small sales of the items, but it could show up elsewhere...an accountant would spot it...Best thing to do is to simply, truncate it,
e.g. 29.475342 -> 29.47 and leave it at that, why?, the .005 can add up to big profit/loss.
In conjunction to what is discussed here...electronic tills and registers use their own variety of handling this scenario, instead of dealing with XX.XXXXXXXXXX (like computers, which has 27/28 decimal places), it deals with XX.XX.
Its something to keep in mind...
Hope this helps,
Best regards,
Tom.
you can use the formatted print method System.out.printf to do the formatted printing if that's what you need

Categories

Resources