Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java fraction calculator

I'm really new to Java programming and I have an assignment due for my AP Computer Programming class, so bear with me. I have to figure out how to multiply two fractions together. I was wondering if there was any way to declare a variable inside a method and use it outside that method (my while loop in the intro method). Thank you, hope that wasn't confusing!

import java.util.Scanner;
import java.util.StringTokenizer;

public class javatest3 {
    static int num1 = 0;
    static int num2 = 0;
    static int denom1 = 0;
    static int denom2 = 0;
    public static void main(String[] args){
    System.out.println("Enter an expression (or \"quit\"): "); //prompts user for input
    intro();

}
public static void intro(){
    Scanner input = new Scanner(System.in); 
    String user= input.nextLine();
    while (!user.equals("quit") & input.hasNextLine()){ //processes code when user input does not equal quit
        StringTokenizer chunks = new StringTokenizer(user, " "); //parses by white space
        String fraction1 = chunks.nextToken(); //first fraction
        String operand = chunks.nextToken(); //operator 
        String fraction2 = chunks.nextToken(); //second fraction
        System.out.println("Fraction 1: " + fraction1); 
        System.out.println("Operation: " + operand); 
        System.out.println("Fraction 2: " + fraction2); 
        System.out.println("Enter an expression (or \"quit\"): "); //prompts user for more input


    while (user.contains("*")){
        parse(fraction1);
        parse(fraction2);
        System.out.println("hi");
        int num = num1 * num2;
        int denom = denom1 * denom2;
        System.out.println(num + "/" + denom);
        user = input.next();

    }

    }
}

public static void parse(String fraction) {
    if (fraction.contains("_")){
        StringTokenizer mixed = new StringTokenizer(fraction, "_");
        int wholeNumber = Integer.parseInt(mixed.nextToken());
        System.out.println(wholeNumber);
        String frac = mixed.nextToken();
        System.out.println(frac);
        StringTokenizer parseFraction = new StringTokenizer(frac, "/"); //parses by forward slash
        int num = Integer.parseInt(parseFraction.nextToken());  
        System.out.println(num);
        int denom = Integer.parseInt(parseFraction.nextToken());
        System.out.println(denom);




    }
    else if (!fraction.contains("_") && fraction.contains("/")){
        StringTokenizer parseFraction = new StringTokenizer(fraction, "/"); //parses by forward slash
        int num = Integer.parseInt(parseFraction.nextToken());  
        System.out.println(num);
        int denom = Integer.parseInt(parseFraction.nextToken());
        System.out.println(denom);



    }else{ 
        StringTokenizer whiteSpace = new StringTokenizer(fraction, " "); 
        int num = Integer.parseInt(whiteSpace.nextToken());  
        System.out.println(num);
}

}}

like image 886
Juliet Avatar asked Jan 11 '23 20:01

Juliet


1 Answers

This short answer is "no". Others have already explained why... but here's two possible alternatives. I don't know if you've learned these concepts yet, but the first alternative has to do with passing by reference vs. passing by value, and the second alternative has to do with object-oriented programming.

Alternative #1:

You can declare a variable outside a method, pass it to the method and use it, and then the variable is available outside the method because it was declared outside the method. I think an example will help make this more clear:

void foo () {
    Integer a = 1;
    Integer b = 2;
    bar(a,b);
    System.out.println("a = " + a + ", b = " + b);
}

void bar (Integer a, Integer b) {
    a = 4;
    b = 8;
}

And the result should be a = 4, b = 8. However, it's very important to note that this works because Integer (unlike int) is a class so its objects are passed by reference. If a and b were just ints, then they would be passed by value. That means that bar() would have it's own copy of a and b separate from foo()'s, and modifications to the variables within bar() would not affect foo()'s copies. For example:

void foo () {
    int a = 1;
    int b = 2;
    bar(a,b);
    System.out.println("a = " + a + ", b = " + b);
}

void bar (int a, int b) {
    a = 4;
    b = 8;
}

This would produce the result a = 1, b = 2.

I don't really like this method because it's pretty ugly and easy to make a mistake, but it is possible and will work if done correctly. Plus if you're not doing object-oriented code, your choices may be this or just don't use a function for that part (which is not usually good design). Although this kind of thing is much more common in languages like C and C++. But those languages are more explicit about pass by value or reference, and you have to manipulate pointers manually (whereas Java hides its pointers from the programmer), so it's harder to get confused about when something will be passed by value or reference (though easier to make other kinds of mistakes).

Alternative #2:

This would be my preference, given the choice, but only if you've learned some about object-oriented programming. If you haven't learned that yet, I'd go with another approach (but feel free to read on if you're curious).

I would create a fraction class that has member variables for the numerator and denomonator (and whole number part if you're required to support that - although personally I'd reduce fractions with whole number parts to just numerator and denomonator anyhow, because that's how I do math). Then I'd make a constructor that takes a String parameter, and the body of that constructor would work much like your parse() method. So that would let you do something like this...

String strFractionString = /* initialize the string, e.g., reading from input */
Fraction myFrac = new Fraction(strFractionString); // parses string and assigns num & denom
System.out.println("My Fraction: " + myFrac.numerator + "/" + myFrac.denominator);
like image 75
Dave Lillethun Avatar answered Jan 19 '23 00:01

Dave Lillethun