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.
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;
}
}
Whenever I compile my code, I receive the following errors:
constructor SalesPerson in class SalesPerson cannot be applied to
given types; error: constructor Player in class Player cannot be
applied to given types;
But it doesn't list any types. The code in question is
Modify the DemoSalesperson application so each Salesperson has a successive ID number from 111 through 120 and a sales value that ranges from $25,000 to $70,000, increasing by $5,000 for each successive Salesperson. Save the file as DemoSalesperson2.java.*/
SalesPerson class:
public class SalesPerson {
// Data fields for Salesperson include an integer ID number and a double annual sales amount
private int idNumber;
private double salesAmount;
//Methods include a constructor that requires values for both data fields, as well as get and set methods for each of the data fields.
public SalesPerson(int idNum, double salesAmt) {
idNumber = idNum;
salesAmount = salesAmt;
}
public int getIdNumber() {
return idNumber;
}
public void setIdNumber(int idNum) {
idNumber = idNum;
}
public double getSalesAmount() {
return salesAmount;
}
public void setSalesAmount(double salesAmt) {
salesAmount = salesAmt;
}
}
Driver:
public class DemoSalesPerson2 {
public static void main(String[] args) {
SalesPerson s1 = new SalesPerson(111, 0);
final int NUM_PERSON = 10;
SalesPerson[] num = new SalesPerson[NUM_PERSON];
for (int x = 1; x < num.length; x++) {
// NUM_PERSON
num[x] = new SalesPerson((111 + x + "|" + 25000 + 5000 * (x)));
System.out.println(x + " " + s1.getIdNumber() + " " + s1.getSalesAmount());
}
}
}
Change this: num[x] = new SalesPerson((111 + x + "|" + 25000 + 5000 * (x)));
to this: num[x] = new SalesPerson((111 + x), (25000 + 5000 * (x)));
You had it right here SalesPerson s1 = new SalesPerson(111, 0);.
Notice the difference between the two constructor calls.
As Sssss pointed out, you're handing in a String as the constructor param when your method requires two ints.
Code jotted down here, haven't tested it. Should get you pointed in the right direction however.
public class DemoSalesPerson2
{
public static void main(String[] args)
{
SalesPerson[] num = new SalesPerson[10];
final int START_NUM =111;
final double START_SALARY=25_000;
for (int x =0; x<num.length; x++) {
num[x] =new SalesPerson(START_NUM+x,START_SALARY+5000*(x));
System.out.println(num[x].getIdNumber()+" "+num[x].getSalesAmount() );
}
}}
try this!!
Here is my code - all it does for the weightedProduct() is return 0.00.
Where did I go wrong? I need it to multiply the units * price and return the product.
public class FrameArray {
private String frameInventory;
private int[] units;
private double[] price;
private double product;
public FrameArray( String frame, int[] unitsArray, double[] priceArray, double product )
{
frameInventory = frame;
units = unitsArray;
price = priceArray;
product = weightedProduct(unitsArray, priceArray);
}
public void setFrameInventory( String frame )
{
frameInventory = frame;
}
public String getFrameInventory()
{
return frameInventory;
}
public double weightedProduct(int[] unitsArray, double[] priceArray){
double value = 0;
double product = 0;
for(int i = 0; i < unitsArray.length; i++){
value = (double) (unitsArray[i] * priceArray[i]);
product = product + value;}
return product;
}
public void displayMessage()
{
System.out.printf( "Current frame inventory\n\n");
}
public void processInventory()
{
outputInventory();
}
public void outputInventory()
{
System.out.println( "Inventory levels:\n");
System.out.printf( "Style Qty Price Value\n\n");
for (int frame = 0; frame < price.length; frame++)
System.out.printf( "Frame %2d: %3d %5.2f %5.2f\n",
frame + 1, units[ frame ], price[ frame], product );
}
}
This is effect of Shadowing.
I think there is ambiguity in the FrameArray().
The product used in the statement just assigns the value to the parameter in function scope.
product = weightedProduct(unitsArray, priceArray);
Just correct it as shown:
public FrameArray( String frame, int[] unitsArray, double[] priceArray, double product )
{
frameInventory = frame;
units = unitsArray;
price = priceArray;
this.product = weightedProduct(unitsArray, priceArray);
}
You can simply remove the product parameter for the FrameArray() too as it is just updating that state variable through weightedProduct() function`s return value.
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;
This code produces accurate output, aside from the final column of data output.
The output is meant to show the non-decimal vote percent value of the candidates.
An error in my logic has caused the aforementioned value to print as 0.
Output appears as follows:
public class Candidate {
public String name;
public int numVotes;
public Candidate(String name, int numVotes) {
this.name = name;
this.numVotes = numVotes;
}
public String getName() {
return name;
}
public int getNumVotes() {
return numVotes;
}
public String toString() {
return getName() + " received " + getNumVotes() + " votes.";
}
}
import java.util.*;
public class TestCandidate {
public static void main(String [] args) {
ArrayList<Candidate> list = new ArrayList<Candidate>();
list.add(new Candidate("John Smith", 5000));
list.add(new Candidate("Mary Miller", 4000));
list.add(new Candidate("Michael Duffy", 6000));
list.add(new Candidate("Tim Robinson", 2500));
list.add(new Candidate("Joe Ashtony", 1800));
System.out.println("Results per candidate:");
System.out.println("______________________\n");
int total = getTotal(list);
printVotes(list);
System.out.print("\nCandidate\t\tVotes Received\t\t% of Total Votes");
printResults(list);
System.out.println("\n\nTotal number of votes in election: " + total);
}
public static void printResults(ArrayList<Candidate> list) {
String name = "";
int percent = 0;
int votes = 0;
int total = getTotal(list);
for(Candidate token : list) {
name = token.getName();
votes = token.getNumVotes();
percent = (votes / total) * 100;
System.out.printf("\n%1s\t%12d\t%17d", name, votes, percent);
}
}
public static void printVotes(ArrayList<Candidate> list) {
for(Candidate token : list) {
System.out.println(token);
}
}
public static int getTotal(ArrayList<Candidate> list) {
int total = 0;
for(Candidate token : list) {
total += token.getNumVotes();
}
return total;
}
}
You are performing integer division here.
percent = (votes / total) * 100;
votes will always be inferior or egal than total, so it's likely that votes/total will result in 0 due to integer division.
Either change percent as double and cast one of the operand of the division to double, or if you want to keep percent as an integer, multiply vote by 100 first and then divide it by total.
percent = (votes*100) / total;