# Critiques for program that integrates functions

The function is entered by the user as a series of coefficients and powers in the form of numerators and denominators. There is a little error somewhere with negative numbers that I'm working on finding. Other than that, I just want to know about the coding style.

Class Integration

package calculus;
import java.util.Scanner;
public class Integration
{
//create various fields to decide the integration method to be used
RationalNumbers coeffFraction;
RationalNumbers powerFraction;
private final int DIRECT = 1;
private final int SUBSTITUTION = 2;
//private final int TRIGONOMETRIC = 3;
//private final int INTEGRATION_BY_PARTS = 4;
//private final int LOGARITHMIC = 5;

//create fields to store various variables needed during the integration process
private double[] coeffX;
private double[] powers;
private int numberOfVariables;

//fields to select integration method
private int integrationMethod;
private Scanner select;

//constructor
/**a constructor that prompts the user to select a number that denotes a certain
* integration type and matches it to a consequent method that implements the type
* of integration that has been selected
*/
public Integration()
{
select = new Scanner(System.in);
System.out.println("Enter the number denoting the method you want to execute");
System.out.println("1. Direct Integration \n" +
"2. Integration by substitution \n" +
"3. Integration of trigonometric functions \n" +
"4. Integration by parts \n" +
"5. Integration of Logarithmic functions \n");

//get input
System.out.print("SELECT: ");
integrationMethod = select.nextInt();

switch(integrationMethod)
{
case DIRECT:
directIntegration();
break;
case SUBSTITUTION:
substitutionIntegration();
break;
default:
System.out.println("Sorry that method is yet to be defined");

}

}

/** this method is for integrating simple functions directly.
* */
public void directIntegration()
{
select = new Scanner(System.in);
System.out.println("Direct Integration Selected\n" +
"f(x) = Axa + Bxb + Cxc + Dxd + ... + Nxn");
System.out.println("\nEnter the number of variables in your function: ");
numberOfVariables = select.nextInt();

//initialize necessary arrays to hold all the variable coefficients and powers
coeffX = new double[numberOfVariables];
powers = new double[numberOfVariables];

//initialize the first prompts as 'A' and 'a'
char coPrompt = 'A';
char powPrompt = 'a';

System.out.println("Enter the coefficients and powers");

//control input coefficients
System.out.println("COEFFICIENTS");

for(int counter=0; counter<coeffX.length; counter++, coPrompt++)
{
int numerator;
int denominator;

System.out.print(coPrompt + ": \n" +
"\tnumerator = ");
numerator = select.nextInt();
System.out.print("\tdenominator = ");
denominator = select.nextInt();

double coefficient = (double)numerator / denominator;

coeffX[counter] = coefficient;
}

//control input powers
System.out.println("POWERS");

for(int counter=0; counter<powers.length; counter++, powPrompt++)
{
int numerator;
int denominator;

System.out.print(powPrompt + ": \n" +
"\tnumerator = ");
numerator = select.nextInt();
System.out.print("\tdenominator = ");
denominator = select.nextInt();

double power = (double)numerator / denominator;

powers[counter] = power;
}

//new powers and coefficients after integration
System.out.print("\nIntegrating ... \n F(x) = ");

for(int counter = 0; counter<powers.length && counter<coeffX.length; counter++)
{
powers[counter] = powers[counter] + 1;
coeffX[counter] = coeffX[counter] / powers[counter];

powerFraction = new RationalNumbers(powers[counter]);
coeffFraction = new RationalNumbers(coeffX[counter]);

//code to output
if (counter == (coeffX.length - 1) && counter == (powers.length - 1))
{
System.out.print(coeffFraction.rationalize() + "x" + powerFraction.rationalize());
}
else
{
System.out.print(coeffFraction.rationalize() + "x" + powerFraction.rationalize() + " + ");
}
}
}

/** this method utilizes substitution to integrate functions.
* */
public void substitutionIntegration()
{
System.out.println("You have selected substitution integration lakini \nbado sijaitengeneza");
}
}


Class RationalNumbers

package calculus;

import helper.GreatestCommonDivisor;
public class RationalNumbers
{
GreatestCommonDivisor helper;
private String stringValue;
private double decimalValue;
private int numerator;
private int denominator;
private boolean recurring = false;

public RationalNumbers(double value)
{
decimalValue = value;
stringValue = String.valueOf(Math.abs(decimalValue));
checkRecurrence();
}

//method to check whether the value passed is recurring or not
public void checkRecurrence()
{
if(stringValue.length() > 4)
{
if(stringValue.charAt(3) == stringValue.charAt(4))
{
recurring = true;
}
}
}

public void ratios()
{
int countDecimalPlaces = 0;

//code to extract recurring numbers and add their behavior
if(recurring)
{
int firstValue = (int)(100 * decimalValue);
int secondValue = (int)(1000 * decimalValue);

denominator = 900;
numerator = secondValue - firstValue;
}
else
{
for(int counter = 2; counter<stringValue.length(); counter++)
{
countDecimalPlaces++;
}

denominator = (int)(Math.pow(10, countDecimalPlaces));

if(decimalValue >= 1)   //setting of numerator for improper fractions
{
numerator = (int)(decimalValue * denominator);
}

else
{
numerator = Integer.parseInt(stringValue.substring(2));
}
}
}

public String rationalize()
{
int[] rations = new int[2];
String fraction;

ratios();
helper = new GreatestCommonDivisor(numerator, denominator);

if(decimalValue<0)  //cater for decimal numbers inputed
{
rations[0] = (numerator / helper.gcd()) * (-1);
}
else
{
rations[0] = numerator / helper.gcd();
}

rations[1] = denominator / helper.gcd();

if(rations[1] == 1)
{
fraction = String.valueOf(rations[0]);
}

else
{
fraction = (rations[0] + "/" + rations[1]);
}

return fraction;
}
}


Class GreatestCommonDivisor

package helper;
/**This class has a constructor that accepts two values and
* then implements the gcd() method to find the greatest common
* divisor of the values*/
public class GreatestCommonDivisor
{
private int numerator;
private int denominator;
private int gcd = 1;

public GreatestCommonDivisor(int value1, int value2)
{
numerator = value1;
denominator = value2;
}

public int gcd()
{
int dividend = 2;

//check here for the problem when you are freshazamiz
while(dividend <= Math.min(numerator, denominator))
{
while(numerator % dividend == 0 && denominator % dividend == 0)
{
numerator = numerator / dividend;
denominator = denominator / dividend;
gcd = gcd * dividend;
}

dividend++;
}

return gcd;
}
}


Why do you have commented out code? If you do need it please throw it away. Leaving it commented out does not help.

I'd also replace all these constants with an Enum to improve readability and maintainability of the code. With the Enum you can also rely on the compiler to check that you use a valid value.

private final int DIRECT = 1;
private final int SUBSTITUTION = 2;
private final int TRIGONOMETRIC = 3;
private final int INTEGRATION_BY_PARTS = 4;
private final int LOGARITHMIC = 5;


In order to have a more object oriented solution, I'd replace the switch that you use to choose the integration method with polymorphism or with a strategy pattern.

I'd also avoid mixing methods that handle input/output and methods that does the computation of the result. Consider having I/O in a separate class that the one actually doing the integration.

Is your RationalNumbers class representing a single number or a set of number? If it has to represent a single number please call it RationalNumber.

I'd introduce a Fraction data type and use it to introduce the output of the rationalize method. Why should it return a String?

• Fraction data type? I do not think i am familiar with that. i will rectify the code appropriately however I just want to point out that for proper output, I needed to the rationalize method to return a string rather than an array(because it has to return 2 values). – Kis Jun 29 '13 at 18:46
• I was suggesting you to create a new Fraction class to represent mathematical fractions. It should have two attributes (The numerator and the dividend) and it should solve cleanly the issue you have returning two values. – mariosangiorgio Jun 29 '13 at 18:48
• Thank you. Polymorphism vs switch, I/O vs Computation, Naming Conventions & style (I cant beleive I missed this) and Fraction class. Thank you Mario for your pointers and help. – Kis Jun 29 '13 at 18:53
• @mariosangiorgio No need for a Fraction type. RationalNumber is OP's fraction type. rationalize is just a bad name for toString. – abuzittin gillifirca Jul 1 '13 at 6:48