I have an assignment to write a program to project your annual fuel usage based on three fill ups of a car. I have to use two separate classes. This is my first class, titled AnnualFuelUse.
public class AnnualFuelUse
{
private static int endMiles, startMiles,fillUp, days,distance;
private double gallonsUsed, pricePerGallon,MPG,cost;
AnnualFuelUse(int fu, int d, int sm, int em, double gu, double price)
{
fillUp = 0;
days = d;
startMiles = sm;
endMiles = em;
gallonsUsed = gu;
pricePerGallon = price;
distance = 0;
MPG = 0.0;
cost = 0.0;
}
public void calcDistance ()
{
distance = endMiles - startMiles;
}
public int getDistance(){
return distance;
}
//calculates miles per gallon
public void calcMPG()
{
MPG = distance /gallonsUsed;
}
public double returnMPG(){
return MPG;
}
public void totalCost(){
cost= gallonsUsed * pricePerGallon;
}
public double getCost(){
return cost;
}
public int returnStart(){
return startMiles;
}
public int returnEnd(){
return endMiles;
}
public int returnDays(){
return days;
}
public double returnGallons(){
return gallonsUsed;
}
public double returnPrice(){
return pricePerGallon;
}
}
This is my second class, titled AnnualFuelUseTester. (sorry for the long names, but it's required)
public class AnnualFuelUseTester
{
public static void main(String[]args)
{
AnnualFuelUse[]fuel = {new AnnualFuelUse(1,1,45023,45231,10.00,2.95),
new AnnualFuelUse(2,4,45231,45480,11.70,2.99),
new AnnualFuelUse(3,8,45480,45659,9.30,3.01),
new AnnualFuelUse(4,13,45659,45961,14.90,3.01)};
for (int index = 0; index<fuel.length;index++)
{
fuel[index].calcDistance();
fuel[index].calcMPG();
fuel[index].totalCost();
}
System.out.println(" Fill Up Days Start Miles End Miles Distance Gallons Used MPG Price Cost ");;
for(int index = 0; index < fuel.length; index++)
{
System.out.printf("%5d %6d %9d %12d %12d %10.2f %13.1f %6.2f %6.2f \n",
index+1,fuel[index].returnDays(),fuel[index].returnStart(),fuel[index].returnEnd(),fuel[index].getDistance(),fuel[index].returnGallons(),fuel[index].returnMPG(),fuel[index].returnPrice(),fuel[index].getCost());
}
My problem is that when I run the program, the days, start miles, end miles, and distance columns all have the same numbers in them, the data for the last fill up. The gallons used, MPG, Price, Cost, all work fine. So in the Days Column, instead of reading 1, 4, 8, 13, it reads 13, 13, 13, 13.
I would appreciate some help in fixing this problem.
Your fields should not be static. That means one per class (not instance)
private static int endMiles, startMiles,fillUp, days,distance;
should be
private int endMiles, startMiles,fillUp, days,distance;
Related
Foreword: sorry for all the code, I know most of it is redundant for this question.
This class takes a description (size), a cost, and a quantity as arguments and returns the number of times the object was created (transaction_number), the total quantity specified for all the objects created (total_quantity), and (is supposed to) return the total cost of all the object created.
public class SalesTransaction
{
private static int counter = 1;
public final int transaction_number;
private static int order_quantity = 0;
public final int total_quantity;
private static double temp_grand_total = 0;
public final double grand_total;
private String size;
private double cost;
private int quantity;
public SalesTransaction(String size, double cost, int quantity)
{
this.size = size;
this.cost = cost;
this.quantity = quantity;
this.transaction_number = counter++;
order_quantity += quantity;
this.total_quantity = order_quantity;
temp_grand_total += totalCostAfterTax(cost*quantity); // this is wrong!
this.grand_total = temp_grand_total;
}
public static double discountAmount(int quantity, double cost)
{
double discount_amount = 0;
if (quantity > 20)
{
discount_amount = cost * 0.10;
}
return discount_amount;
}
public static double totalCostBeforeTax(SalesTransaction temp)
{
double total_cost;
int quantity = temp.quantity;
double cost = temp.cost;
total_cost = quantity * cost;
double discount_amount = discountAmount(quantity, total_cost);
total_cost = total_cost - discount_amount;
return total_cost;
}
public static double totalCostAfterTax(double total_cost)
{
total_cost = total_cost * 1.15;
return total_cost;
}
public static void printStats(SalesTransaction temp)
{
System.out.println("Transaction Number: " + temp.transaction_number);
System.out.println("Size: " + temp.size);
System.out.println("Cost Per Table: "+ temp.cost);
System.out.println("Number of Tables: " + temp.quantity);
System.out.println("Total Tables So Far: " + temp.total_quantity);
double total_cost_before_tax = totalCostBeforeTax(temp);
double discount_amount = discountAmount(temp.quantity, total_cost_before_tax);
System.out.println("Discount: " + discount_amount);
double total_cost_after_tax = totalCostAfterTax(total_cost_before_tax);
temp.temp_grand_total = total_cost_after_tax;
System.out.println("Cost for this transaction: " + total_cost_after_tax);
System.out.println("Total cost: "+ temp.grand_total);
System.out.println();
}
}
And this is just a tester class.
public class SalesTester
{
public static void main(String[] args)
{
SalesTransaction one = new SalesTransaction("Small", 10.0, 10);
one.printStats(one);
SalesTransaction two = new SalesTransaction("Medium", 20.0, 30);
two.printStats(two);
SalesTransaction three = new SalesTransaction("Large", 30.0, 40);
three.printStats(three);
}
}
The problem is that I can't figure out how to store the grand_total. I tried doing it the same way I stored the total_quantity but I can see why that isn't working.
How can I keep track of the grand total of all the transactions (objects) so I can then print it out on the console?
I assume there's another way of expressing this in the constructor but I'm not sure how and I couldn't find any examples of this.
The simplest solution is to use a static field on your SalesTransaction class which holds the grand_total. A static variable is shared by all instances of a class.
private static double grandTotal = 0;
public SalesTransaction(double cost) {
grandTotal += cost;
}
However, this has some disadvantages in the long run. It would mean you can't have transactions as members of different grand totals. This is why it's called the singleton anti-pattern.
A much better way to solve the problem is to make an additional class such as TransactionGroup, which contains SalesTransaction objects in a List, and sums together the costs when needed.
public class TransactionGroup {
private List<SalesTransaction> transactions = new ArrayList<>();
public void addTransaction(SalesTransaction st) {
transactions.add(st);
}
public double getGrandTotal() {
double sum = 0;
for (SalesTransaction st : transactions) {
sum += st.getCost();
}
return sum;
}
}
I am practicing some Java and one of the applications I am writing asks to output the world population in the next 75 years.
I am using the population growth model. My issue is that my application outputs 'Infinity' in the column where the estimated population should be output.
This is my code:
import java.util.Calendar;
import java.util.regex.Matcher;
public class WorldPopulationGrowth {
public static void main(String[] args) {
double currentWorldPopulation = 7.4e9;
double worldPopulationGrowthRate = 1.13;
double anticipatedWorldPopulation;
int initialYear = Calendar.getInstance().get(Calendar.YEAR);
System.out.println("Year\tAnticipated World Population (in billions)\tPopulation " +
"increase since last year");
System.out.println(String.format("%d\t%.1e\t\t\t\t\t\t\t\t\t\t\tNA", initialYear, currentWorldPopulation) );
for(int i=1; i < 76; i++){
int year = initialYear + i;
double growthExponential = worldPopulationGrowthRate*year*1.0;
anticipatedWorldPopulation = currentWorldPopulation * Math.pow(Math.E, growthExponential);
System.out.println(String.format("%d\t%.1e\t\t\t\t\t\t\t\t\t\t\t", year, anticipatedWorldPopulation));
currentWorldPopulation = anticipatedWorldPopulation;
}
}
}
Let's take a careful look at the first iteration of your code, as if we were debugging it (Make sure you try to do this in the future!)
currentWorldPopulation = 7.4e9
worldPopulationGrowthRate is 1.13
initialYear is 2016
your loop begins, i is 1
year is set to 2017
growthExponential is set to 1.13 * 2017 = 2279.21 (this is the start of your problem)
anticipatedWorldPopulation is set to 7.4e9 * e^2279.21
this is roughly 7.4e9 * 7.05e989... KABOOM
Revisit your calculations, and step through your application (ideally in a debugger) to see your problems.
#Krease found your problem.
I recoded it. Once you fix the issue he found it's fine. I used JDK 8 lambdas and gave you both percentage and exponential growth models. The code prints both for comparison:
import java.util.function.DoubleFunction;
/**
* Simplistic population growth model
* #link https://stackoverflow.com/questions/38805318/getting-infinity-output-instead-of-actual-numbers/38805409?noredirect=1#comment64979614_38805409
*/
public class WorldPopulationGrowth {
public static void main(String[] args) {
double currentWorldPopulation = 7.4e9;
double worldPopulationGrowthRate = 1.13;
int numYears = 76;
int startYear = 1976;
double populationExponential = currentWorldPopulation;
ExponentialGrowthModel modelExpGrowth = new ExponentialGrowthModel(worldPopulationGrowthRate);
double populationPercentage = currentWorldPopulation;
PercentageGrowthModel modelPercentGrowth = new PercentageGrowthModel(worldPopulationGrowthRate);
System.out.println(String.format("%10s %20.3e %20.3e", startYear, currentWorldPopulation, currentWorldPopulation));
for (int i = 1; i < numYears; ++i) {
populationExponential = modelExpGrowth.apply(populationExponential);
populationPercentage = modelPercentGrowth.apply(populationPercentage);
System.out.println(String.format("%10s %20.3e %20.3e", startYear+i, populationExponential, populationPercentage));
}
}
}
class ExponentialGrowthModel implements DoubleFunction<Double> {
private double exponent;
ExponentialGrowthModel(double exponent) {
this.exponent = exponent;
}
private double getExponent() {
return exponent;
}
public void setExponent(double exponent) {
this.exponent = exponent;
}
#Override
public Double apply(double value) {
return value*Math.exp(this.getExponent());
}
}
class PercentageGrowthModel implements DoubleFunction<Double> {
private double percentageIncrease;
PercentageGrowthModel(double percentageIncrease) {
this.percentageIncrease = percentageIncrease;
}
private double getPercentageIncrease() {
return percentageIncrease;
}
public void setPercentageIncrease(double percentageIncrease) {
this.percentageIncrease = percentageIncrease;
}
#Override
public Double apply(double value) {
return value*(this.getPercentageIncrease());
}
}
I'm writing a program that provides the final bill for a stay at a hotel with parameters for Room #, # of guests, duration of stay, and the price per person per night.
I have the math correct in my BBRoom Class however it doesn't seem to take and process the information in the class parameters?
Driver Class:
public class BedAndBreakfastDriver {
public static void main(String[] args) {
//float price, int rmNum, int numOccupants, int duration
//or
//int rmNum, int numOccupants, int duration, float price
BBRoom Smith;
Smith = new BBRoom(29.95, 16, 1, 5);
System.out.println(Smith);
}
}
BBRoom Class:
public class BBRoom {
final int MAXCAP = 4;
final int MINCAP = 1;
final int MINSTAY = 1;
int room;
int persons;
int nights;
double cost;
double surcharge;
double cleanUp;
double cottageCost;
NumberFormat fmt1 = NumberFormat.getCurrencyInstance();
BBRoom(double price, int rmNum, int numOccupants, int duration){}
BBRoom( int rmNum, int numOccupants, int duration, double price){}
private int getRoomNumber(int rmNum){
room = rmNum;
return room;
}
private int getPersons(int numOccupants){
if (numOccupants < MINCAP){
persons = MINCAP;
}if(numOccupants > MAXCAP){
persons = MAXCAP;
}else{
persons = numOccupants;
}
return persons;
}
private int getNights(int duration){
if(duration < MINSTAY){
nights = MINSTAY;
}else{
nights = duration;
}
return nights;
}
private double setCost(double price){
return price;
}
private double getCost(double price){
if (persons < 2){
cost = price*2*nights;
}else{
cost = (persons*price*nights);
}
return cost;
}
private double BBCottage(double cost){
surcharge = (12.95*nights);
cleanUp = 47.99;
cottageCost = cost+surcharge+cleanUp;
return cottageCost;
}
public String toString(){
String bill = ("Room Number"+room+" "+"Guests:"+persons+" "+"Nights:"+nights+" "+"Basic Package:"+ fmt1.format(cost)+" "+"Cottage Upgrade:"+fmt1.format(cottageCost) );
return bill;
}
}
For some reason I keep getting the output to display every variable as
"Room Number:0 Guests:0 Nights:0 Basic Package:0.00 Cottage Upgrade:0.00"
Any help would be appreciated. Thanks!
P.S. I'd also prefer to turn my BBCottage method into a subclass but I'm not quite sure how to accomplish that. If I could get some guidance on that as well it would be great!
Your constructor has an empty body
BBRoom(double price, int rmNum, int numOccupants, int duration){} // <<<<<<< nothing going on in {}
All relevant fields are initialized to their default value of 0. Implement the constructor to do what you want.
You never actually set the values inside BBRoom. Also, the methods getVariable(int something) should be split into a separate get() and set(int something) methods, because otherwise you're simultaneously getting and setting a variable.
In your toString method, you call values that would be returned from get(), but those are never set. To fix it, you need to set them inside your constructor.
Your constructers need to set initial values.
BBRoom:
public class BBRoom {
final int MAXCAP = 4;
final int MINCAP = 1;
final int MINSTAY = 1;
int room;
int persons;
int nights;
double cost;
double surcharge;
double cleanUp;
double cottageCost;
NumberFormat fmt1 = NumberFormat.getCurrencyInstance();
BBRoom(double price, int rmNum, int numOccupants, int duration){
someInstanceVariable = price;
room = rmNum;
persons = numOccupants;
..and so on..
}
BBRoom( int rmNum, int numOccupants, int duration, double price){
..do the same here..
}
private int getRoomNumber(int rmNum){
room = rmNum;
return room;
}
private int getPersons(int numOccupants){
if (numOccupants < MINCAP){
persons = MINCAP;
}if(numOccupants > MAXCAP){
persons = MAXCAP;
}else{
persons = numOccupants;
}
return persons;
}
private int getNights(int duration){
if(duration < MINSTAY){
nights = MINSTAY;
}else{
nights = duration;
}
return nights;
}
private double setCost(double price){
return price;
}
private double getCost(double price){
if (persons < 2){
cost = price*2*nights;
}else{
cost = (persons*price*nights);
}
return cost;
}
private double BBCottage(double cost){
surcharge = (12.95*nights);
cleanUp = 47.99;
cottageCost = cost+surcharge+cleanUp;
return cottageCost;
}
public String toString(){
String bill = ("Room Number"+room+" "+"Guests:"+persons+" "+"Nights:"+nights+" "+"Basic Package:"+ fmt1.format(cost)+" "+"Cottage Upgrade:"+fmt1.format(cottageCost) );
return bill;
}
}
As for separating Cottage into another class:
BBCottage:
public class BBCottage {
public BBCottage(double cost){
surcharge = (12.95*nights);
cleanUp = 47.99;
}
public double getCottage() {
cottageCost = cost+surcharge+cleanUp;
return cottageCost;
}
}
Edit: I also realized that in your main, you're doing System.out.println(Smith);. You have print the method, not Smith. So first of all, I'd change BBRoom to have getters and setters:
void setRmNum(int rm) {
room = rm;
}
int getRmNum() {
return room;
}
Then, in your main, do System.out.println(Smith.getRmNum());
I have a method in the Candy Class named pricePerHundredGrams and what it is supposed to do is multiply the variable price times 100.00 and divide that answer by the variable weightGrams, and finally return that result to the variable wammy. When the variable wammy is called for in the very 2nd last statement of this code, it is supposed to pass the answer to return result. And ultimately c1 and c2 should display that result as well...but I get NaN for "per hundred grams". What is wrong with my code?
public class whatever
{ public static void main (String[] args)
{
processCandies();
System.out.println("end of processing");
}
public static void processCandies()
{
Candy c1 = new Candy("Hershey", 145, 4.35, 233);
Candy c2 = new Candy("Milky Way", 390, 2.66, 126);
System.out.println(c1);
System.out.println(c2);
}
}
class Candy
{
private String name;
private int calories;
private double price;
private double weightGrams;
double wammy = pricePerHundredGrams(price, weightGrams);
/**
Constructor
#param name
#param calories
#param price
#param gram
*/
public Candy(String n, int cal, double p, double wG)
{
name = n;
calories = cal;
price = p;
weightGrams = wG;
}
public String getName()
{
return name;
}
public int getCalories()
{
return calories;
}
public double getPrice()
{
return price;
}
public double getWeightGrams()
{
return weightGrams;
}
public double pricePerHundredGrams(double price, double weightGrams)
{
return (price * 100.00) / weightGrams;
}
public String toString()
{
String result;
result = name + "\n" + calories + " calories\n" + weightGrams + " grams\n" + wammy + " per hundred grams\n";
return result;
}
}
You are initializing wammy with the result of pricePerHundredGrams, but price and weightGrams haven't been initialized yet, so they're both 0. For double arithmetic, 0 divided by 0 is NaN (it's indeterminate in math).
Initialize wammy after price and weightGrams have valid values in your constructor:
public Candy(String n, int cal, double p, double wG)
{
name = n;
calories = cal;
price = p;
weightGrams = wG;
// Initialize wammy here.
wammy = pricePerHundredGrams(price, weightGrams);
}
Additionally, since they are already instance variables, you don't need to pass price and weightGrams as parameters to pricePerHundredGrams.
Write a static method named calculateAverageWeight, to be added to the Bowl class, which is passed an array of Bowl objects, and returns the average weight of the Bowls in the array.
this is the Bowl class:
public class Bowl {
private double weight;
private boolean empty;
private String origin; // country of manufacture
public Bowl(double w, boolean e, String origin) {
weight = w;
empty = e;
this.origin = origin;
}
public double getWeight() {
return weight;
}
public boolean getEmpty() {
return empty;
}
public String getOrigin() {
return origin;
}
public void setEmpty(boolean emptyStatus) {
empty = emptyStatus;
}
public String toString() {
return ("from " + origin + " weight: " + weight);
}
The following code worked:
public static double calculateAverageWeight(Bowl[] bowls)
{
double sum=0;
double average=0;
for(int j=0; j<bowls.length; j++)
{
sum+=bowls[j].getWeight();
average=sum/bowls.length;
}
return average;
}
but I don't understand why my most recent code didn't as they seem to run almost identically to me?:
public static double calculateAverageWeight(Bowl[] bowls){
double sum=0;
double k=bowls.length;
for(int j=0; j<bowls.length; j++){
sum=sum+bowls[j].getWeight();}
double average=sum/k;
return average;}
The code for the calculateAverageWeight is OK, but you're missing a "}" at the end of the Bowl class.
Also, your calculateAverageWeight method must be inside another class, so you may be missing something there too. May you post your code ?
public static double calculateAverageWeight(Bowl[] bowls)
{
double sum=0;
double average=0;
for(int j=0; j<bowls.length; j++)
{
sum+=bowls[j].getWeight();
average=sum/bowls.length;
}
return average;
}