0

I am trying to call my methods within main but after entering my dollars and cents, the values don't change when I print them

import java.text.DecimalFormat;
import java.util.Scanner;

public class ChangeMachine {


public static void main(String[] args) {

System.out.println("Change is good");

int dollars = 0;
int cents = 0;
int toonie = dollars/2;
int loonie  = dollars%2;
int quarter = cents/25;
int dime = (cents%25)/10;
int nickel = ((cents%25)%10)/5;

    ChangeMachine.getAmountFromUser(dollars, cents);
    ChangeMachine.calculateCoins(dollars, cents);
    ChangeMachine.displayInvoice(dollars, cents, toonie, loonie, quarter, dime, nickel);

}

Method to input the dollars and cents Here I'm able to enter the amount but it won't appear when I try to display it

public static void getAmountFromUser(int dollars, int cents) {

Scanner input = new Scanner(System.in);

    System.out.print("How many dollars? ");
    dollars = input.nextInt();

    System.out.print("How many cents? ");
    cents = input.nextInt();
    System.out.println();

    input.close();

}

Method to calculate coins

public static void calculateCoins (int dollars, int cents){
DecimalFormat df = new DecimalFormat("#0.00");
double amount = dollars + cents/100.0;
System.out.println("$"+df.format(amount)+" requires:");

//-----Bonus-----
dollars=dollars+(cents+2)/100;
cents=(cents+2)%100;
//---------------

}

Method to display coins needed

public static void displayInvoice (int dollars, int cents, int toonie, int    loonie, int quarter, int dime, int nickel){


System.out.println(toonie+" Toonies");
System.out.println(loonie+" Loonies");
System.out.println(quarter+" Quarters");
System.out.println(dime+" Dimes");
System.out.println(nickel+" Nickels");

}

}
Gary
  • 13,303
  • 18
  • 49
  • 71
obonmarc
  • 11
  • 4

3 Answers3

2

... the values don't change when I print them

Yes, they shouldn't be changed because Java is a pass-by-value language. Any primitive variable, that is passed to a method, will not be changed (you are passing just a value of this variable, a new local variable will be created for the method).

How to solve that?

  1. returning a changed value from a method
  2. making operations over instance variables without local variable use
  3. writing a custom class which keeps primitives

EDIT:

When we start talking about returning multiple values from a method, possibly, our methods are built not completely good (e.g. break the single responsibility principle). In that case, we need to refactor our methods. Consider methods with a single responsibility (calculateDollars, calculateCents, displayCoin). It will help to separate your code into small logical parts and make them more independent.

EDIT 2:

Now you are bound up with variables defined in the program's beginning. They, in their turn, are bound up with values of variables at that point. Take a look how you may correct that:

public int getLoonie(int dollars) {
   return dollars % 2;
}

Better? Let's call it in the displayInvoice:

System.out.println(getLoonie(dollars) + " Loonies");

or much better

System.out.println(getLoonie(userCash.getDollars()) + " Loonies");
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • how do i return multiple values from a method? – obonmarc Oct 16 '16 at 22:50
  • You could create a simple class "Input" that holds the dollars and cents entered by the user and return an instance of this class. – Michael Lihs Oct 16 '16 at 23:03
  • @obonmarc Or you could return an array of int for simplicity. But a class is recommended. Then you could use that class as a single parameter argument to the other methods (assuming you can mutate or change its values). – Jörgen Lundgren Oct 16 '16 at 23:07
  • @MichaelLihs, yes, a good point, I'm just thinking about, I'd name it as `Cash` – Andrew Tobilko Oct 16 '16 at 23:08
  • Writing a new class, wouldn't I need new variables? – obonmarc Oct 16 '16 at 23:18
  • @obonmarc Something like this would do, but you may have to add some more methods: public final class Cash { private int cents; private int dollars; public Cash(int dollars, int cents) { this.dollars = dollars; this.cents = cents; } public int calculateToonie() { return this.dollars / 2; } public int getCents() { return this.cents; } public int getDollars() { return this.dollars; } public void setCents(int cents) { this.cents = cents; } public void setDollars(int dollars) { this.dollars = dollars; } } – Jörgen Lundgren Oct 16 '16 at 23:27
  • @obonmarc, you will create a new instance of this class once inside the `getAmountFromUser` method – Andrew Tobilko Oct 16 '16 at 23:29
1

References to parameter arguments (local variables) in Java are pass-by-value, rather than pass-by-reference.

Each method has their own set of local variable references. When you re-assign a new value to a local variable reference, this change is local to that method.

Edit:

Here's one way to do it:

import java.text.DecimalFormat;
import java.util.Scanner;

public final class ChangeMachine {
    private ChangeMachine() {

    }

    public static Cash getAmountFromUser() {
        try(final Scanner input = new Scanner(System.in)) {
            System.out.print("How many dollars? ");

            final int dollars = input.nextInt();

            System.out.print("How many cents? ");

            final int cents = input.nextInt();

            return new Cash(dollars, cents);
        }
    }

    public static void calculateCoins(final Cash cash) {
        final DecimalFormat decimalFormat = new DecimalFormat("#0.00");

        final double amount = cash.getDollars() + cash.getCents() / 100.0D;

        System.out.println("$" + decimalFormat.format(amount) + " requires:");

        cash.setDollars(cash.getDollars() + (cash.getCents() + 2) / 100);
        cash.setCents((cash.getCents() + 2) % 100);
    }

    public static void displayInvoice(final Cash cash) {
        System.out.println(cash.calculateToonies() + " Toonies");
        System.out.println(cash.calculateLoonies() + " Loonies");
        System.out.println(cash.calculateQuarters() + " Quarters");
        System.out.println(cash.calculateDimes() + " Dimes");
        System.out.println(cash.calculateNickels() + " Nickels");
    }

    public static void main(final String[] args) {
        final Cash cash = getAmountFromUser();

        calculateCoins(cash);
        displayInvoice(cash);
    }

    private static final class Cash {
        private int cents;
        private int dollars;

        public Cash(final int dollars, final int cents) {
            this.dollars = dollars;
            this.cents = cents;
        }

        public int calculateDimes() {
            return this.cents % 25 / 10;
        }

        public int calculateLoonies() {
            return this.dollars % 2;
        }

        public int calculateNickels() {
            return this.cents % 25 % 10 / 5;
        }

        public int calculateQuarters() {
            return this.cents / 25;
        }

        public int calculateToonies() {
            return this.dollars / 2;
        }

        public int getCents() {
            return this.cents;
        }

        public int getDollars() {
            return this.dollars;
        }

        public void setCents(final int cents) {
            this.cents = cents;
        }

        public void setDollars(final int dollars) {
            this.dollars = dollars;
        }
    }
}
0

Were you able to compile this code before? I was just checking the ChangeMachine, getAmountFromUser, and CalculateCoins methods to check them out in Notepad ++ and came up with several errors. The last two lines of code in getAmountFromUser , System.out.println(); and 'input.close();' don't seem to be necessary.

As for the other errors, I'm seeing a lot of class, interface, or enum expected errors.

009
  • 83
  • 1
  • 1
  • 11