qazwsx598
qazwsx598

Reputation: 23

Incrementer inside loop adds more than one, why?

I'm trying to increment the values inside of an array that corresponds to how many times that discount has been used. The incrementation works well if the discount is 0% (discount = 1.0) but for 20%, 30%, and 40% (discount is 0.8, 0.7, 0.6 respectively) the related index in the counts array is incremented by 2. Finally, if discount = 0.5 counts[4] is incremented by 8. I feel like it has something to do with what iteration of the for loop I'm in but I can't figure it out.

Heres the class that I think holds the problem:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package softwaresales;
/**
 *
 * @author python
 */
public class SoftwareSales {
    private int unitsSold;
    private final double UNIT_PRICE = 99.0;
    private final int[] UNITS_LOW_RANGES = {1, 10, 20, 50, 100};
    private final double[] DISCOUNTS = {1.0, 0.8, 0.7, 0.6, 0.5};
    private static int[] counts = {0, 0, 0, 0, 0};

    SoftwareSales(int u){
        unitsSold = u;
    }

    public int getUnitsSold(){
        return unitsSold;
    }

    public double getDiscount(){
        double discount = 1;
        for (int i = 0; i < 4; i++){
            if((unitsSold >= UNITS_LOW_RANGES[i]) &&
                    (unitsSold < UNITS_LOW_RANGES[i+1])){
                counts[i] += 1;
                discount = DISCOUNTS[i];
            }
            else if (unitsSold >= 100){
                counts[4] += 1;
                discount = DISCOUNTS[4];
                System.out.print("*");
            }
        }
        return discount;
    }

    public double getCost(){
        return unitsSold * UNIT_PRICE * getDiscount();
    }

    public int[] getCounts(){
        return counts;
    }
}

Here's a sample input :

13
31
115
101
96
8
29
103
27
129

And the related output:

Units sold: 13
Discount: 19.999999999999996%
Price: $1029.6000000000001

Units sold: 31
Discount: 30.000000000000004%
Price: $2148.2999999999997

Units sold: 115
Discount: 50.0%
Price: $5692.5

Units sold: 101
Discount: 50.0%
Price: $4999.5

Units sold: 96
Discount: 40.0%
Price: $5702.4

Units sold: 8
Discount: 0.0%
Price: $792.0

Units sold: 29
Discount: 30.000000000000004%
Price: $2009.6999999999998

Units sold: 103
Discount: 50.0%
Price: $5098.5

Units sold: 27
Discount: 30.000000000000004%
Price: $1871.1

Units sold: 129
Discount: 50.0%
Price: $6385.5

=================
=               =
=   DISCOUNTS   =
=               =
=================
0% discounts: 1
20% discounts: 2
30% discounts: 6
40% discounts: 2
50% discounts: 32

As you can see there is only one instance where a 0% discount was given which is represented in the output. There is also only one instance each of 20% and 40% discounts but the output shows 2 for each, similar to the 30% discount. Also there was 4 instances of a 50% discount being given, but as you can see the array was incremented 32 times...

Here's my main program where I call getDiscount().

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package softwaresales;
import java.io.*;
import java.util.Scanner;

/**
 *
 * @author python
 */
public class SofwareSalesDriver {

    /**
     * @param args the command line arguments
     * @throws java.io.IOException
     */
    public static void main(String[] args) throws IOException {
        String file_location;
        Scanner kb = new Scanner(System.in);
        CreateInputFile inputs = new CreateInputFile();
        System.out.println("Enter the PATH to the folder where you would like" +
                " the in/out files: ");
        System.out.println("\nExamples:\nLinux: /home/%USER_NAME%/Documents/" + 
                "\nor Windows: C:\\\\users\\\\%USER_NAME%\\\\Documents\\\\");
        System.out.print("\nEnter PATH: ");
        file_location = kb.nextLine();
        String infile = file_location + "Inputs.txt";
        String outfile = file_location + "Outfile.txt";
        File file = new File(outfile);
        FileWriter writer = new FileWriter(file);
        int unitsSold = 0;
        SoftwareSales customer = new SoftwareSales(unitsSold);
        int[] counts = customer.getCounts();
        inputs.createInputFile(file_location);
        Scanner fileLine = new Scanner(new File(infile));
        while (fileLine.hasNextInt()){
            unitsSold = fileLine.nextInt();
            customer = new SoftwareSales(unitsSold);
            writer.write("Units sold: " + unitsSold + "\n" + 
                    "Discount: " + (1 - customer.getDiscount())*100 + "%\n" +
                    "Price: $" + customer.getCost() + "\n\n");
        }
        writer.write("=================\n=               =\n" +
                "=   DISCOUNTS   =\n=               =\n" +
                "=================\n" + 
                "0% discounts: "+ counts[0] / 2 +
                "\n20% discounts: " + counts[1] + 
                "\n30% discounts: " + counts[2] + 
                "\n40% discounts: " + counts[3] + 
                "\n50% discounts: " + counts[4] + "\n\n");

        writer.close();
    }
}

Upvotes: 0

Views: 77

Answers (1)

Illedhar
Illedhar

Reputation: 251

If I get your code correctly, the error is related to the if-statement in your for loop. You should have the check before the for loop, otherwise you increment the counter multiple times per loop if unitsSold >= 100 because the else statement is called for each loop iteration.

if (unitsSold >= 100){
    counts[4] += 1;
    discount = DISCOUNTS[4];
    System.out.print("*");
} else {
    for (int i = 0; i < 4; i++){
        if((unitsSold >= UNITS_LOW_RANGES[i]) &&
                (unitsSold < UNITS_LOW_RANGES[i+1])){
            counts[i] += 1;
            discount = DISCOUNTS[i];
        }
    }
}

The reason for the double counting of some numbers is due to that function:

public double getCost(){
    return unitsSold * UNIT_PRICE * getDiscount();
}

Here, you call getDiscount() again, which will again trigger the whole process and add the respective value to counts[i].

I would recommend you the following: Instead of calculating the discount twice, you could just pass the discount as a parameter like getCost(double discount). This way, you prevent calling this function twice.

Just a quick notice at the end: Normally, you should refrain from performing modifications of global variables in getters if you do not intend to actually count the number of getter-calls. Probably, the discount calculation could be moved to the constructor and the getDiscount() only returns the discount that has been previously calculated in the constructor. But that just as a side note.

Upvotes: 1

Related Questions