I have this method that computes taxes due for a person with a filing status of single.
But I'm having trouble trying to convert this to a for loop or using an Array instead of a while loop because this code becomes really long and nasty looking. I want to make it look pretty by simplifying the code. Any suggestions?
public void calculateTax()
{
//The constant fields for the tax rate
final double TAXRATE_10 = 0.1; //10%
//This is the tax rate percent on the tax 15%
final double TAXRATE_15PERCENT = 0.15;
//This is the tax rate percent on the tax 25%
final double TAXRATE_25PERCENT = 0.25;
//This is the tax rate percent on the tax 28%
final double TAXRATE_28PERCENT = 0.28;
//This is the tax rate percent on the tax 33%
final double TAXTRATE_33PERCENT = 0.33;
//This is the tax rate percent on the tax 35%
final double TAXRATE_35PERCENT = 0.35;
//constant numbers for tax boundaries.
final int NOTRICH = 8700;
final int MIDDLECLASS = 35350;
final int SORTOFRICH = 85650;
final int RICH = 178650;
final int FORSURERICH = 388350;
//Variables for taxable income, and tax calculation.
long taxableIncome = income - deduction -(numberOfExemption * VAlUEOFEXEMPTION);
double cumulatedTax = 0;
//Calculate the Tax
while(taxableIncome != 0)
{
if(taxableIncome > FORSURERICH)
{
cumulatedTax += ((taxableIncome-FORSURERICH) * TAXRATE_35PERCENT);
taxableIncome = (long)FORSURERICH;
}
else if(taxableIncome > RICH)
{
cumulatedTax += ((taxableIncome-RICH) * TAXTRATE_33PERCENT);
taxableIncome = (long)RICH;
}
else if(taxableIncome > SORTOFRICH)
{
cumulatedTax += ((taxableIncome-SORTOFRICH) * TAXRATE_28PERCENT);
taxableIncome = (long)SORTOFRICH;
}
else if(taxableIncome > MIDDLECLASS)
{
cumulatedTax += ((taxableIncome-MIDDLECLASS) * TAXRATE_25PERCENT);
taxableIncome = (long)MIDDLECLASS;
}
else if(taxableIncome > NOTRICH)
{
cumulatedTax += ((taxableIncome-NOTRICH) * TAXRATE_15PERCENT);
taxableIncome = (long)NOTRICH;
}
else
{
cumulatedTax += ((taxableIncome) * TAXRATE_10);
taxableIncome = 0;
}
}
How about this? thinking in a more object oriented way. I did it for a few classes but you can add functionality by yourrself if you get the idea ;)
I implement it using the Decorator Pattern.
The common interface.
public interface TaxCalculator {
Double calculate(Double tax);
}
the base calculation for all taxes.
public class TaxCalculatorBase implements TaxCalculator{
#Override
public Double calculate(Double tax) {
return tax * TAXRATE_10;
}
}
The decorator abstract class
public abstract class TaxCalculatorDecorator implements TaxCalculator{
private final TaxCalculator decoratee;
/**
* #param decoratee
*/
public TaxCalculatorDecorator(TaxCalculator decoratee) {
super();
this.decoratee = decoratee;
}
#Override
public Double calculate(Double tax) {
Double returnValue = decoratee.calculate(tax);
return taxCalculate(returnValue);
}
protected abstract Double taxCalculate(Double tax);
}
and the decorators concrete classes. I only did 2 as an example
public class NotRichTaxCalculator extends TaxCalculatorDecorator{
public NotRichTaxCalculator(TaxCalculator taxCalculator) {
super(taxCalculator);
}
#Override
protected Double taxCalculate(Double tax) {
return ((tax-NOTRICH) * TAXRATE_15PERCENT);
}
}
Sort of rich tax calculator
public class SortOfRichTaxCalculator extends TaxCalculatorDecorator{
public SortOfRichTaxCalculator(TaxCalculator decoratee) {
super(decoratee);
}
#Override
protected Double taxCalculate(Double cumulatedTax) {
return ((cumulatedTax-SORTOFRICH) * TAXRATE_28PERCENT);;
}
}
and a simple Factory to create objects
public final class TaxCalculatorFactory {
private TaxCalculatorFactory(){}
public static TaxCalculator create(Double taxableIncome){
TaxCalculator taxCalculator= null;
if(taxableIncome > SORTOFRICH)
{
taxCalculator = new SortOfRichTaxCalculator(new NotRichTaxCalculator(new TaxCalculatorBase()));
}else if(taxableIncome > NOTRICH)
{
taxCalculator = new NotRichTaxCalculator(new TaxCalculatorBase());
}
else
{
taxCalculator =new TaxCalculatorBase();
}
return taxCalculator;
}
}
then in client code you only have to write this.
TaxCalculator taxCalculator= TaxCalculatorFactory.create(tax);
Double acumulatedTaxes = taxCalculator.calculate(tax);
Consider the fact that your tax brackets are 1:1 coupled with your tax rates.
final double[][] BRACKETS = {
{388350.0, 0.35},
{178650.0, 0.33},
{85650.0, 0.28},
{35350.0, 0.25},
{8700.0, 0.15}
};
/* ... */
for (double[] bracket: BRACKETS) {
if(taxableIncome > bracket[0]) {
cumulatedTax += ((taxableIncome-bracket[0]) * bracket[1]);
taxableIncome = (long)bracket[0];
}
}
cumulatedTax += taxableIncome * 0.1;
taxableIncome = 0;
If you really like C-style ALLCAPSCONSTANTS, then feel free to declare them, and just use their names instead of the literals I used in my double[][]. If you want to go native with Java, define a TaxBracket class. :)
Edit: misunderstood the intent of your code. I think my edit should do what you want.
I like the approaches above, but I'd encourage you to investigate using an EnumMap instead of the double[][] in agarrett's example.
How about this?
List<Integer> taxSlabs = new ArrayList<Integer>();
taxSlabs.put(388350);
taxSlabs.put(178650);
taxSlabs.put(85650);
taxSlabs.put(35350);
taxSlabs.put(8700);
List<Double> taxRates = new ArrayList<Double>();
taxRates.put(0.35);
taxRates.put(0.33);
taxRates.put(0.28);
taxRates.put(0.25);
taxRates.put(0.15);
//Variables for taxable income, and tax calculation.
long taxableIncome = income - deduction -(numberOfExemption * VAlUEOFEXEMPTION);
double cumulatedTax = 0.0;
for(int indx = 0; indx < taxSlabs.size(); indx++){
int slabLimit = taxSlabs.get(indx).intValue();
if(taxableIncome >= slabLimit ){
cumulatedTax += ((taxableIncome% slabLimit) * taxRates.get(indx).doubleValue());
taxableIncome = (long)slabLimit;
}
}
Related
In the 2 similar methods with measure in their name, they output the data that I want to have output in the last method many times. But if I try to simply call them in the last method the message does not work anymore. I also have another class with a main method where I create an object that calls the last method as many times as needed. Here is the code.
public class Weatherstation{
double temperature;
double windspeed;
double windChillTemperature;
double actualTemperature;
double actualSpeed;
public void measureTemperature(){
for (temperature = -10; temperature <= 30; temperature = temperature + 5)
{
System.out.println(temperature);
if(temperature == 30)
while(temperature > -10)
{
System.out.println(temperature-1);
temperature = temperature - 1;
}
}
}
public void measureWindspeed(){
for (windspeed = 0; windspeed <= 80; windspeed = windspeed + 8)
{
System.out.println(windspeed);
if(windspeed == 80)
while(windspeed > 0)
{
System.out.println(windspeed-16);
windspeed = windspeed-16;
}
}
}
public void calculateWindChillTemperature(){
windChillTemperature = 13.12 + (0.6215 * temperature) + ((0.3965 * temperature) - 11.37) * Math.pow(windspeed, 0.16);
}
public void generateWeatherMessage(){
String warning="";
calculateWindChillTemperature();
if(windspeed >= 70)
warning += "Wind Warning";
if(windChillTemperature >= -18)
warning += "Cold Warning";
System.out.println("Actual weather: Temp: "+temperature+"°C (Wind: "+windspeed+"km/h) Chilltemp: "+windChillTemperature+"°C, "+warning);
}
}
public class WeatherstationTester {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Weatherstation w1 = new Weatherstation();
for(int i = 0; i <= 10; i++)
w1.generateWeatherMessage();
}
}
You're not passing any information into Weatherstation to calculate, so all the variables are zero.
Add a constructor like so:
public Weatherstation(double temperature, double windspeed, double windChillTemperature, double actualTemperature, double actualSpeed) {
this.temperature = temperature;
this.windspeed = windspeed;
this.windChillTemperature = windChillTemperature;
this.actualTemperature = actualTemperature;
this.actualSpeed = actualSpeed;
}
Then modify your test class to pass in the variables:
public class WeatherstationTester {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
for (int i = 0; i <= 10; i++) {
Weatherstation w1 = new Weatherstation(i, i, i, i, i);
w1.generateWeatherMessage();
}
}
}
I have a method in class Employee called calculatePay that does calculations for certain pay and taxes.
public void calculatePay() {
totalHoursWorked = 0;
grossPay = 0;
fedTax = 0;
stateTax = 0;
netPay = 0;
totalTax = 0;
for (int i = 0; i < getNoTimeCards(); i++) {
TimeCard timeCard = getTimeCard(i);
totalHoursWorked += timeCard.getHoursWorked();
}
grossPay = totalHoursWorked * payRate;
if (grossPay >= 200) {
fedTax = (grossPay - 200) * .1;
} else {
fedTax = 0;
}
stateTax = grossPay * .04;
totalTax = fedTax + stateTax;
netPay = grossPay - totalTax;
}
I need to create a method called calculatePay in another class called Company. In this method, I need to create a loop that calls on the calculatePay method in Employee. Is calling on a method in a loop any different than calling on an instance variable? Whatever I try doesn't seem to work. Here's what i currently have for the method in Company:
public void calculatePay() {
for (int i = 0; i < noEmployees; i++) {
Employee employee = getEmployee(i);
employee.calculatePay(); {
return;
}
}
}
Any help in explaining would be great.
Ah, I think I see what you tried to do.
So you tried creating a function, then tried to make it return it's calculated value by using the parentheses when calling it, didn't you? However, that isn't how Java syntax works.
calculatePay() in Employee is a void function, meaning it won't return any value. In this case, you want to have it return the netPay of type double. So instead, you should define the function as:
public double calculatePay() {
// code
netPay = grossPay - totalTax;
return netPay;
}
And in Company you would just do
public calculatePay() {
for (int i = 0; i < noEmployees; i++) {
Employee employee = getEmployee(i);
System.out.println(employee.calculatePay());
}
}
Also, keep in mind this code is incomplete. If you also want calculatePay() in Company to return the total value or something, you would also need to change it's return type to double.
I think your code should have two lists, one of employees and other of time cards.
public void calculatePay()
{
...
totalHoursWorked = getHoursWorked();
...
}
public void calculateEmployeesPay()
{
for(final Employee emp : EmployeeList)
{
emp.calculatePay();
}
}
public double getHoursWorked()
{
double totalHoursWorked = 0.0;
for (final TimeCard tc : TimeCardList)
{
totalHoursWorked += tc.getHoursWorked();
}
return totalHoursWorked;
}
if calculatePay() is void then netPay must changed to be an instance variable instead of a local.
I'm working out a question from a labsheet but i'm only getting 0.0 as answer when running the program. I can't find out what's wrong please help.
The question:
Implement a class Pizza with attribute diameter (in cm), cost_sq_cm (cost per square cm) and area. Its methods are:
• Constructor to create an object of type Pizza with a given diameter and given price_sq_cm.
• Mutator and accessor methods for diameter and cost_sq_cm.
• calcArea to calculate the area of a given pizza.
• getPrice to calculate and return the price of a pizza.
Write a class TestPizza with a main method that declares an object of type Pizza with a user inputted diameter and user-‐inputted cost_sq_cm of a circular pizza, and display the price of the pizza.
The Pizza class:
package Number3;
public class Pizza {
private int diameter;
private float cost_sq_cm;
private double area;
private double price;
public Pizza() //default constructor
{
diameter = 0;
cost_sq_cm = 0;
area = 0;
price = 0;
}
public Pizza(int d,float cost,double a,double p) //overloaded constructor
{
d = diameter;
cost = cost_sq_cm;
a = area;
p = price;
}
public void Constructor() //method
{
Pizza P = new Pizza();
}
public void setDiameter(int d) //mutator
{
d = diameter;
}
public int getDiameter() //accessor
{
return diameter;
}
public void setCost(float c)
{
c = cost_sq_cm;
}
public float getCost()
{
return cost_sq_cm;
}
public double calcArea()
{
area = 3.142 * (diameter * diameter);
return area;
}
public double getPrice()
{
price = area * cost_sq_cm;
return price;
}
public void display()
{
System.out.print("The area is: "+this.price);
}
}
TestPizza:
package Number3;
import java.util.Scanner;
public class TestPizza {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
float area = 0;
Pizza P = new Pizza();
int d; float c,a = 0;
System.out.print("Enter a value for the diameter: ");
d = input.nextInt();
P.setDiameter(d);
System.out.print("Enter a value for the cost: ");
c = input.nextFloat();
P.setCost(c);
P.display();
}
}
I'm new to JAVA. Please be lenient.
You should multiply cost per square centimeter times area to get price. You'll get zero if either one is equal to zero. I see where you've set diameter, but not area.
You set diameter, but you don't calculate area when you set it.
public void setDiameter(int d) //mutator; lose this comment. worthless clutter.
{
d = diameter;
area = calcArea();
}
I'd recommend following the Java idiom. Don't write a display() method; better to override toString().
I'd write it this way:
package cruft;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/**
* Pizza
* #author Michael
* #link https://stackoverflow.com/questions/28658669/classes-and-objects-getting-0-0-as-answer-when-calculating-price-java
* #since 2/22/2015 12:27 PM
*/
public class Pizza {
private static final int DEFAULT_DIAMETER = 38;
private static final double DEFAULT_COST = 15.0;
private static final double DEFAULT_COST_PER_AREA = 0.013226; // 15 euro for a 38 cm diameter pizza
private static final NumberFormat DEFAULT_FORMAT = new DecimalFormat("#.####");
private final int diameter;
private final double costPerArea;
private final double price;
public static void main(String[] args) {
int diameter = ((args.length > 0) ? Integer.valueOf(args[0]) : DEFAULT_DIAMETER);
double costPerArea = ((args.length > 1) ? Double.valueOf(args[1]) : DEFAULT_COST_PER_AREA);
Pizza pizza = new Pizza(diameter, costPerArea);
System.out.println(pizza);
}
public Pizza(int diameter, double costPerArea) {
if (diameter <= 0) throw new IllegalArgumentException("diameter must be positive");
if (costPerArea <= 0) throw new IllegalArgumentException("cost per area must be positive");
this.diameter = diameter;
this.costPerArea = costPerArea;
this.price = this.costPerArea*this.calculateArea();
}
public double getPrice() {
return price;
}
private double calculateArea() {
return Math.PI*this.diameter*this.diameter/4.0;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Pizza{");
sb.append("diameter=").append(diameter);
sb.append(", costPerArea=").append(DEFAULT_FORMAT.format(costPerArea));
sb.append(", price=").append(NumberFormat.getCurrencyInstance().format(getPrice()));
sb.append('}');
return sb.toString();
}
}
For setting a field or another value it is
variable = value;
so
diameter = d;
It looks like your setCost and setDiameter methods need to be changed,
From
d = diameter;
To
this.diameter = d;
Instead of:
System.out.print("The area is: "+this.price);
Use:
System.out.print("The area is: "+this.getPrice());
You need to calculate area as well. So in your main method call it like:
P.calcArea();//to calculate area
You initialised price as 0, when you called new Pizza() and you never called getPrice which is where you calculate the price.
Also change your setter for cost from:
public void setCost(float c) {
c = cost_sq_cm;
}
To
public void setCost(float c) {
cost_sq_cm = c;
}
I'm having a problem adding up the method output and putting it into another method and then printing it. My error is that it keeps printing out the first run of the program. Is there a way to record the multiple runs of the method and put it into a double?
public static void main(String[] args)
{
AnnualUse[] fills = {new AnnualUse (1, 1, 9000, 9420, 16.0, 3.11),
new AnnualUse (2, 30, 9420, 9840, 16.0, 3.08),
new AnnualUse (3, 60, 9840, 10240, 15.23, 3.06)};
String [] oP = new String [3];
int diMin=0;
int diM=0;
double MPin=0;
double MPax=0;
double Primin=0;
double Primax=0;
double roundoff1=0;
double roundoff2=0;
int minDist = Integer.MAX_VALUE;
int maxDist = Integer.MIN_VALUE;
double minMPG = Double.MAX_VALUE;
double maxMPG = Double.MIN_VALUE;
double minPri = Double.MAX_VALUE;
double maxPri = Double.MIN_VALUE;
for (int index=0; index<fills.length; index++)
{
fills[index].calcDistance();
fills[index].calcMPG();
fills[index].calctotalCost();
fills[index].totalDist();
fills[index].totalMPG();
fills[index].totalcost();
}
for (int i = 0; i < fills.length; i++) {
if (fills[i].getDist() < minDist){
minDist = fills[i].getDist();
diMin = minDist ;
}
if (fills[i].getDist() > maxDist) {
maxDist = fills[i].getDist();
diM = maxDist;
}
if (fills[i].getMPG() <minMPG) {
minMPG = fills[i].getMPG();
MPin = minMPG;
}
if (fills[i].getMPG() > maxMPG) {
maxMPG = fills[i].getMPG();
MPax = maxMPG;
roundoff1= Math.round(MPax * 100.0) / 100.0;
}
if (fills[i].getMoolah() < minPri) {
minPri = fills[i].getMoolah();
Primin = minPri;
roundoff2= roundoff2= Math.round(Primin * 100.0) / 100.0;
}
if (fills[i].getMoolah() > maxPri) {
maxPri = fills[i].getMoolah();
Primax = maxPri;
}
}
System.out.println("Fill Up Days Start Miles End Miles Distance Gallons Used MPG Price Cost");
for ( int index=0; index< oP.length; index++)
{
System.out.printf("%3d %8d %10d %10d %9d %13.1f %8.2f %7.2f %8.2f %n" ,
fills[index].getFill(),fills[index].getDay(),
fills[index].getStart(),fills[index].getEnd(),
fills[index].getDist(), fills[index].getUseofG(),
fills[index].getMPG(), fills[index].getCost(),
fills[index].getMoolah());
}
System.out.println();
System.out.println("Minimum:"+" "+diMin+" "+MPin+" "+roundoff2);
System.out.println("Maximum:"+" "+diM+" "+roundoff1+" "+Primax);
System.out.print("Totals:");
for (int index=0; index<1;index++)
System.out.printf( "%20d %20.2f %10.2f", fills[index].getTotal1(),fills[index].getTotal2(),fills[index].total3());
}
first bit of data, from the file I noticed that it's printing out the first run through but I have no idea why it is not adding the values.This is basically how most of the program is. Sorry for not knowing how to explain most of what is going on, I only know the processes actions and don't know to descriptively describe step by step.
class AnnualUse
{
private int counter,day,ender1, starter1, differance,total1 ;
private double amount, cost,MPG,Moolah, minDist,
maxDist,minMPG,maxMPG,minPrice,maxPrice,total2,total3;
AnnualUse (int numberofFills,int days,int starter,int ender,double useofg, double costofg)
{
counter=numberofFills;
day= days;
starter1=starter;
ender1=ender;
amount=useofg;
cost=costofg;
}
public void calcDistance()
{
differance=ender1 - starter1;
}
public int getDist()
{
return differance;
}
public void calcMPG()
{
MPG=differance / amount;
}
public double getMPG()
{
return MPG;
}
public void calctotalCost()
{
Moolah= amount * cost;
}
public double getMoolah()
{
return Moolah;
}
public int getFill()
{
return counter;
}
public int getDay()
{
return day;
}
public int getStart()
{
return starter1;
}
public int getEnd()
{
return ender1;
}
public double getUseofG()
{
return amount;
}
public double getCost()
{
return cost;
}
public void totalDist()
{
total1=+ differance ;
}
public int getTotal1()
{
return total1;
}
public void totalMPG()
{
total2=+MPG;
}
public double getTotal2()
{
return total2;
}
public void totalcost()
{
total3=+Moolah;
}
public double total3()
{
return total3;
}
}
There is too much here for me to give you a specific answer.
It might be worth it for you to clean up the code as much as you can (format it, tidy it, fix as much as you can, etc) and then post it on Code Review for more detailed feedback.
https://codereview.stackexchange.com/
I'm not going to go through all your code for you but you seem to be asking about totals and averages. To calculate those you just need to loop through your values:
double total1 = 0;
double total2 = 0;
for (MyClass mc: theListOfObjects) {
total1 += mc.getFirstTotal();
total2 += mc.getSecondTotal();
}
System.out.println("Totals: "+total1+", "+total2);
System.out.println("Mean: "+(total1/theListOfObjects.size())+", "+(total2/theListOfObjects.size()));
Instead of having separate methods to trying adding the total I just needed to make a variable and then add up all of the inputs.
int total1= fills[0].getDist()+fills[1].getDist()+fills[2].getDist();
class TestTax {
public static void main (String[] args){
NJTax t = new NJTax();
t.grossIncome= 50000;
t.dependents= 2;
t.state= "NJ";
double yourTax = t.calcTax();
double totalTax = t.adjustForStudents(yourTax);
System.out.println("Your tax is " + yourTax);
}
}
class tax {
double grossIncome;
String state;
int dependents;
public double calcTax(){
double stateTax = 0;
if(grossIncome < 30000){
stateTax = grossIncome * 0.05;
}
else{
stateTax = grossIncome * 0.06;
}
return stateTax;
}
public void printAnnualTaxReturn(){
// code goes here
}
}
public class NJTax extends tax{
double adjustForStudents (double stateTax){
double adjustedTax = stateTax - 500;
return adjustedTax;
public double calcTax(){
}
}
}
I am having trouble with the Lesson requirement to:
"Change the functionality of calcTax( ) by overriding it in NJTax. The new version of calcTax( ) should lower the tax by $500 before returning the value."
How is this accomplished. I just have safaribooksonline and no videos for the solution.
http://download.oracle.com/javase/tutorial/java/IandI/override.html
Class names should start with a capital letter as well. Since I'm not exactly sure what you wanted regarding functionality, here's just an example. Super refers to the parent class, in this case being tax. Thus, NJTax's calcTax() method returns tax.calcTax() - 500. You also may want to look into using the #Override annotation as a way of making it clear that a method is being overridden and to provide a compile-time check.
public class NJTax extends tax {
public double adjustForStudents (double stateTax) {
double adjustedTax = stateTax - 500;
return adjustedTax;
}
public double calcTax() {
return super.calcTax() - 500;
}
}
public class NJTax extends tax{
double adjustForStudents (double stateTax){
double adjustedTax = stateTax - 500;
return adjustedTax;
}
public double calcTax(){
double stateTax = super.calcTax();
return this.adjustforStudents(stateTax);
}
}
hint: return the same value as tax.calcTax() minus $500.
For overriding you base class (Tax) implementation of calcTax, just add your own implementation of calcTax in NJTax. This could be as simple as
public double calcTax(){
return super.calcTax() -500;
}