2

This is a school assignment. I got this text file that I need to read values from as follows
T = ticket sales, D = donations, E = expenses and the text file list it as;

T 2000.00
E 111.11
D 500.00
E 22.22

I want to get the data from the text file, add the like values, ask the user if they wish to add additional data, then display the computed output.

import java.io.*;
import java.util.Scanner;

public class MyEventManager {
public static String amountType;
public static int amount;

public static String validationMethodType () throws IOException
{
    Scanner keyboard = new Scanner ( System.in );
    System.out.printf("\nPlease enter an amount type ('T' - Tickets), ('D' - Donations), ('E' - Expenses): ");
    amountType = keyboard.next().toUpperCase();
    char choice = amountType.charAt(0);
    //choice = Character.toUpperCase(choice);

    if (choice != 'T' && choice != 'D' && choice != 'E')
    {
       do
       {
           System.out.printf("\nInvlaid amount entered...");
           System.out.printf("\nPlease enter an amount type ('T' - Tickets), ('D' - Donations), ('E' - Expenses): ");
           amountType = keyboard.next().toUpperCase();
           choice = amountType.charAt(0);
           //choice = Character.toUpperCase(choice);
       }
       while(choice != 'T' && choice != 'D' && choice != 'E');
       return amountType;
    }
    else
    {
        return amountType;
    }
}
public static int validationMethodAmount()
{
  Scanner keyboard = new Scanner ( System.in );
  System.out.printf("\nPlease enter an amount (amount must be positive and non-zero): ");
  amount = keyboard.nextInt();

  if (amount <= 0)
  {
    do
    {
       System.out.printf("\nInvlaid amount entered...");
       System.out.printf("\nPlease enter an amount (amount must be positive and non-zero): ");
       amount = keyboard.nextInt();
    }
    while (amount <= 0);
    return amount;
  }
  else
  {
    return amount;
  } 
}
public static void main(String [] args) throws IOException
{
    Scanner keyboard = new Scanner ( System.in );
    System.out.printf("This program will read a text file and add data to it, then compute the results.\n\n");  // display purpose
    MyEventClass myEvent = new MyEventClass();  //create object
    //
    String readFile = "Event.txt";  //file location constant
    try
    {
    File inputFile = new File (readFile);   //open the file
    InputStream is; 
    Scanner scanFile = new Scanner (inputFile); //scan the file
    {
        is = new BufferedInputStream(new FileInputStream(inputFile));
        //
        try 
        {
        while(scanFile.hasNext())
        {
            if ( scanFile.hasNextLine())
            {
                myEvent.instanceMethod(amountType, amount);
            }

        }
        }
        catch (IllegalArgumentException o)
                {
                System.out.println("Error code 3: No data found!" );
                }

    }
    byte[] c = new byte[1024];
    int count = 1;
    int readChars;

    while ((readChars = is.read(c)) != -1) 
    {
        for (int i = 0; i < readChars; ++i)
        {
            if (c[i] == '\n')
            {
                ++count;
            }
        }
    }
        System.out.println("Total number of valid lines read was " + count);
        }
        catch (FileNotFoundException e)
        {
            System.out.println("Error code 4: The file " + readFile + " was not found!" );
        }
        System.out.println("Are there any more amounts to add that where not in the text file? ");
        String questionOne = keyboard.next();

        if ("y".equalsIgnoreCase(questionOne))
        {
            validationMethodType();
            validationMethodAmount();
            myEvent.instanceMethod(amountType, amount);

        }
        myEvent.displayResults();
    }
}

The second class

public class MyEventClass {
    private double ticketSales;
    private double moneyDonated;
    private double moneySpent;

public MyEventClass () 
{
    this.ticketSales = 0.0;
    this.moneyDonated = 0.0;
    this.moneySpent = 0.0;

}

public double getTicketSales ()
{
    return ticketSales;
}

public double getMoneyDonated ()
{
    return moneyDonated;
}

public double getMoneySpent ()
{
    return moneySpent;
}

public double instanceMethod (String amountType, double amount) 
{

    char choice = amountType.charAt(0);
    if(amount <= 0)    
    {
        throw new IllegalArgumentException("Error code 1: Amount should be larger then 0");   
    }    

    if(choice != 'T' && choice != 'D' && choice != 'E')
    {
        //increment the current total for the amount type specified by the first parameter by the amount in the second paramter?
       return amount++;    
    }
    else
    {
        throw new IllegalArgumentException("Error code 2: Invalid input, data will be ignored");
    }
}       

public void displayResults()
{
    double income = this.ticketSales + this.moneyDonated;
    double profits = income - this.moneySpent;
    System.out.printf("\nTotal Ticket Sales: " + "%8.2f", this.ticketSales);
    System.out.printf("\nTotal Donations: " + "%11.2f" + " +", this.moneyDonated);
    System.out.printf("\n                    --------");
    System.out.printf("\nTotal Income: " + "%14.2f", income);
    System.out.printf("\nTotal Expenses: " + "%12.2f" + " -", this.moneySpent);
    System.out.printf("\n                    --------");
    System.out.printf("\nEvent Profits: " + "%13.2f", profits);
    System.out.println();
    }
}

I think one of my issues is in instanceMethod return where it is supposed to add the values here.

Current output;

run:
This program will read a text file and add data to it, then compute the results.

Exception in thread "main" java.lang.NullPointerException
    at MyEventClass.instanceMethod(MyEventClass.java:34)
    at MyEventManager.main(MyEventManager.java:90)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Community
  • 1
  • 1
  • `nextInt()` doesn't do a good job of reading numbers with decimal points... – ajb Feb 22 '16 at 02:03
  • `nextDouble()` maybe? –  Feb 22 '16 at 02:09
  • Can you add a little more information including any errors or what behavior you are experiencing in your code now? – pczeus Feb 22 '16 at 02:11
  • Yes, that would work much better. (Actually, when dealing with money amounts, you should use `BigDecimal` since `double` values aren't really exact values. But since you're new, `nextDouble()` will work well enough for this purpose. You can learn about `BigDecimal` later.) – ajb Feb 22 '16 at 02:11
  • May you can look @ this link [Reading double values from a file](http://stackoverflow.com/questions/1855753/reading-double-values-from-a-file) – Abhijeet Feb 22 '16 at 02:12
  • @pczeus I added the output about in my question. –  Feb 22 '16 at 02:16
  • That's helpful..which line is 34? :) It seems like the only candidate line is the `amountType.charAt()` call. – pczeus Feb 22 '16 at 02:17
  • @pczeus line 34 is in the instanceMethod for the second class, `char choice = amountType.charAt(0);` –  Feb 22 '16 at 02:18
  • @ajb I've updated the validationMethodAmount with `nextDouble()` and changed it at the top as well. –  Feb 22 '16 at 02:23

2 Answers2

1

You are never setting the amountType to a value read from scanFile.nextLine()

In your main method, Change your if/while condition that looks like this:

    while(scanFile.hasNext())
    {
        if ( scanFile.hasNextLine())
        {
            myEvent.instanceMethod(amountType, amount);
        }

    }

To this:

        while(scanFile.hasNextLine())
        {
            String line = scanFile.nextLine().trim();
            String[] tokens = line.split(" ");
            String amountType = tokens[0];
            double amount = Double.parseDouble(tokens[1]);
            myEvent.instanceMethod(amountType, amount);
        }

Also in your main method, where you catch Exceptions, add a line to print the stack trace, that will help you with debugging issues: e.printStackTrace();

pczeus
  • 7,709
  • 4
  • 36
  • 51
  • Thank you for the response this bit did get the code moving along, however now I get the output `Error Code 3: No data found!` `Total number of valid lines read was 4` `Are there any more amounts to add that where not in the text file?` after this I can enter more data and keep going however why is it not reading those text values for the input? –  Feb 22 '16 at 02:39
  • Yes, I see you are not parsing the input line into the amountType and amount. I will update the answer for your to show how the input should be parsed. – pczeus Feb 22 '16 at 02:39
  • Also if I enter `Y` for the question there, and then `T` and `2` as an input I get `Exception in thread "main" java.lang.IllegalArgumentException: Error code 2: Invalid input, data will be ignored` `at MyEventClass.instanceMethod(MyEventClass.java:46)` `at MyEventManager.main(MyEventManager.java:122)` `Java Result: 1` `BUILD SUCCESSFUL (total time: 3 minutes 42 seconds)` –  Feb 22 '16 at 02:47
  • I have updated the answer, which does successfully get the data from the input file and call your instanceMethod with expected values. You still have other issues in the instanceMethod, but no longer related to the question. – pczeus Feb 22 '16 at 02:53
  • Awsome, Thank you! I still have some issues to work out, but at least its not showing errors now. I just need to figure out how to add the values together as there are all still showing `zero` –  Feb 22 '16 at 03:05
1

Adding onto pczeus' answer, you also need to set the amount. Changing

amountType = scanFile.nextLine();

to

String[] temp = scanFile.nextLine().split(" ");

amountType = temp[0];
amount = new Double(temp[1]);

Should address the issue. The next error after that is in your class, it appears the choice options are reversed.

    if (choice == 'T' || choice == 'D' || choice == 'E') {
        //increment the current total for the amount type specified by the first parameter by the amount in the second paramter?
        return amount++;
    } else {
        throw new IllegalArgumentException("Error code 2: Invalid input, data will be ignored");
    }

Should be

    if (choice != 'T' && choice != 'D' && choice != 'E') {
        throw new IllegalArgumentException("Error code 2: Invalid input, data will be ignored");
    } else {
        //increment the current total for the amount type specified by the first parameter by the amount in the second paramter?
        return amount++;
    }

Your final class would come out to something like

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class MyEventManager {

    private Map<String, Double> amountMap = new HashMap<>();
    public String amountType;
    public double amount;

    public static void main(String[] args) throws IOException {
        MyEventManager eventManager = new MyEventManager();
        eventManager.runEvent();
    }

    private void runEvent() throws IOException {
        System.out.printf("This program will read a text file and add data to it, then compute the results.\n\n");

        File inputFile = new File("Event.txt");
        handleFileInput(inputFile);

        System.out.println("Are there any more amounts to add that where not in the text file?\n");
        Scanner keyboard = new Scanner(System.in);
        String questionOne = keyboard.next();

        if ("y".equalsIgnoreCase(questionOne)) {
            do {
                validationMethodType();
                validationMethodAmount();
                addAmount(amountType, amount);

                System.out.println("Are there any more amounts to add that where not in the text file?\n");
                keyboard = new Scanner(System.in);
                questionOne = keyboard.next();
            } while (questionOne.equalsIgnoreCase("y"));
        }

        displayResults();
    }

    private void handleFileInput(File inputFile) throws IOException {
        try (Scanner scanFile = new Scanner(inputFile)) {
            int lineCount = 0;
            while (scanFile.hasNext()) {
                if (scanFile.hasNextLine()) {
                    String[] temp = scanFile.nextLine().split(" ");

                    String amountType = temp[0];
                    double amount = new Double(temp[1]);

                    try {
                        checkType(amountType);
                        checkAmount(amount);
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                        continue;
                    }

                    addAmount(amountType, amount);
                    lineCount++;
                }
            }
            System.out.println("Total number of valid lines read was " + lineCount);
        } catch (FileNotFoundException e) {
            System.out.println("Error code 4: The file " + inputFile.getName() + " was not found!");
        }
    }

    private String validationMethodType() throws IOException {
        Scanner keyboard = new Scanner(System.in);
        System.out.printf("\nPlease enter an amount type ('T' - Tickets), ('D' - Donations), ('E' - Expenses): ");
        amountType = keyboard.next().toUpperCase();

        if (amountTypeValid(amountType)) {
            do {
                System.out.printf("\nInvlaid amount entered...");
                System.out.printf("\nPlease enter an amount type ('T' - Tickets), ('D' - Donations), ('E' - Expenses): ");
                amountType = keyboard.next().toUpperCase();
            }
            while (amountTypeValid(amountType));
        }

        return amountType;
    }

    private double validationMethodAmount() {
        Scanner keyboard = new Scanner(System.in);
        System.out.printf("\nPlease enter an amount (amount must be positive and non-zero): ");
        amount = keyboard.nextInt();

        if (amount <= 0) {
            do {
                System.out.printf("\nInvlaid amount entered...");
                System.out.printf("\nPlease enter an amount (amount must be positive and non-zero): ");
                amount = keyboard.nextInt();
            }
            while (amount <= 0);
        }

        return amount;
    }

    private void checkAmount(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Error code 1: Amount should be larger then 0");
        }
    }

    private void checkType(String type) {
        if (amountTypeValid(type)) {
            throw new IllegalArgumentException("Error code 2: Invalid input, data will be ignored");
        }
    }

    private void addAmount(String amountType, double amount) {
        if (amountMap.containsKey(amountType)) {
            double currentAmount = amountMap.get(amountType);
            amountMap.put(amountType, currentAmount + amount);
        } else {
            amountMap.put(amountType, amount);
        }
    }

    private boolean amountTypeValid(String type) {
        return !type.equalsIgnoreCase("T") && !type.equalsIgnoreCase("D") && !type.equalsIgnoreCase("E");
    }

    private void displayResults() {
        double ticket = amountMap.containsKey("T") ? amountMap.get("T") : 0;
        double donated = amountMap.containsKey("D") ? amountMap.get("D") : 0;
        double spent = amountMap.containsKey("E") ? amountMap.get("E") : 0;
        double income = ticket + donated;
        double profits = income - spent;
        System.out.printf("\nTotal Ticket Sales: " + "%8.2f", ticket);
        System.out.printf("\nTotal Donations: " + "%11.2f" + " +", donated);
        System.out.printf("\n                    --------");
        System.out.printf("\nTotal Income: " + "%14.2f", income);
        System.out.printf("\nTotal Expenses: " + "%12.2f" + " -", spent);
        System.out.printf("\n                    --------");
        System.out.printf("\nEvent Profits: " + "%13.2f", profits);
        System.out.println();
    }
}
Mamof
  • 181
  • 5
  • 13
  • This did not help, I did not get any additional errors but same output as before. –  Feb 22 '16 at 02:50
  • @Mamof You are right, I was in the process of updating the answer as well. Thanks. – pczeus Feb 22 '16 at 02:55
  • I've expanded my answer to include the remaining error. While we are able to help address the errors you will want to go back through the code to understand why you were getting them. As this is a school assignment you'll want to really understand why the errors were happening. – Mamof Feb 22 '16 at 02:56
  • Could not agree more, I've been working at this all week, and waiting till the last moment to post my question so I made sure I exhausted all other options for finding the issues. –  Feb 22 '16 at 02:58
  • Awesome the program is running bug-free now, it still is not adding data correctly, ie still returning all `zero` values for output. –  Feb 22 '16 at 03:02
  • Depending on how you're running your code you may want to get an IDE that allows you to debug and step through the logic. This will allow you to see what is happening to each variable as it's running. My preference is something like IntelliJ by JetBrains. – Mamof Feb 22 '16 at 03:02
  • I'm using NetBeans @Mamof –  Feb 22 '16 at 03:03
  • When in doubt, simplify. Your MyEventClass is basically just a Map. Instead of passing into the class just check if the map contains a key of the type and add it to the existing value or puts it into the map directly. – Mamof Feb 22 '16 at 03:13
  • a bit cryptic there but I think I know what your saying, I'm trying to figure it out now, I got four hours before I have to submit this lol hopfully I get it done by then. I've downloaded IntelliJ and going to send it through that and see what happens. –  Feb 22 '16 at 03:16