Having successfully created a policy holder and writing the information to csv I try to run the program again using a do while loop but receive an inputmismatchexception after typing surname.
Can someone point me in the right direction or advise what I am doing wrong with this piece of code?
Here is example of what happens...
console
/**
*
*/
package InsurancePolicySystem;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Scanner;
import java.util.stream.Collectors;
/**
* #author
*
*/
public class InsurancePolicy {
// create variables
private String surname;
private int age;
private String motorType;
private String motorPolicyId;
private String addAnother;
private String pattern = "^[a-zA-Z](\\s?[a-zA-Z]){2,29}$";
// import scanner for user input
Scanner scanner = new Scanner(System.in);
// time stamp number. -1 used on month as time stamp displays next year instead
// of current year
int year = Calendar.getInstance().get(Calendar.YEAR);
int month = Calendar.getInstance().get(Calendar.MONTH) - 1;
// sum of the year and month
int timeStamp = year + month;
/**
* default constructor
*/
public InsurancePolicy() {
}
/**
* non default constructor
*
* #param surname
* #param age
* #param motorType
* #param motorPolicyId
*/
public InsurancePolicy(String surname, int age, String motorType, String motorPolicyId) {
this.surname = surname;
this.age = age;
this.motorType = motorType;
this.motorPolicyId = motorPolicyId;
}
/**
*
* #return
*/
public String getSurname() {
return surname;
}
/**
* Surname should be more than 3 letters and not greater than 20. Anything more
* will cause a not valid error!
*
* #param surname
* #throws IllegalArgumentException
*/
public void setSurname(String surname) throws IllegalArgumentException {
this.surname = surname;
}
/**
*
* #return
*/
public int getAge() {
return age;
}
/**
* Age must be between 18 & 50 Any other age will produce not eligible error!
*
* #param age
* #throws IllegalArgumentException
*/
public void setAge(int age) throws IllegalArgumentException {
if ((age >= 18) && (age <= 50)) {
this.age = age;
} else {
throw new IllegalArgumentException("Not eligible for an insurance policy!");
}
}
/**
*
* #return
*/
public String getMotorType() {
return motorType;
}
/**
* motor type should only be either CAR, TAXI or BUS. if statement to prevent
* other vehicle types and throw error if user inputs a different vehicle.
*
* #param motorType
* #throws IllegalArgumentException
*/
public void setMotorType(String motorType) throws IllegalArgumentException {
if (motorType.equals("CAR") || motorType.equals("TAXI") || motorType.equals("BUS")) {
this.motorType = motorType;
} else {
throw new IllegalArgumentException("Not eligible for an insurance policy!");
}
this.motorType = motorType;
}
/**
*
* #return
*/
public String getMotorPolicyId() {
return motorPolicyId;
}
/**
*
* #param motorPolicyId
*/
public void setMotorPolicyId(String motorPolicyId) {
this.motorPolicyId = motorPolicyId;
}
/**
* Method to write policy holder particulars to a csv file. Creates ArrayList
* and uses collect joining to add comma for file.
*
* #throws IOException
*/
public void writeToFile() throws IOException {
BufferedWriter writer = new BufferedWriter(
new FileWriter("/Users/johnj/eclipse-workspace/InsuranceProject/insurance.csv", true));
// creates policy holder (insurance) array
ArrayList<String> insurance = new ArrayList<String>();
insurance.add(surname);
insurance.add(Integer.toString(age));
insurance.add(motorType);
insurance.add(motorPolicyId);
// write array to csv file
String collect = insurance.stream().collect(Collectors.joining(", "));
System.out.println(collect);
writer.write(collect);
writer.newLine();
writer.flush();
writer.close();
}
/**
* Builds and generates user input. Will then add it into an array list and
* append to writeToFile(). Included do while loop for user to continue creating
* policy profiles without having to re run program.
*
* #param motorType
*/
public void addPolicyHolder() throws IOException {
try {
do {
// enter policy holder surname. Checks pattern to ensure compliance
System.out.println("Please type your surname...");
surname = scanner.next(pattern).toUpperCase().trim();
setSurname(this.surname);
// user input age
System.out.println("Please type your age...");
age = scanner.nextInt();
setAge(this.age);
// user input motor type which is converted to upper case
System.out.println("Please type your motor type i.e. CAR, TAXI or BUS...");
motorType = scanner.next().toUpperCase().trim();
setMotorType(this.motorType);
System.out.println(); // used to create next line space
// Motor Policy Id should be 3 characters from surname as well as time stamp. If
// time stamp odd number add 1 or else add 0 if even.
motorPolicyId = surname.substring(0, 3) + timeStamp;
if (timeStamp % 2 == 0) {
motorPolicyId = this.motorPolicyId + 0;
} else {
motorPolicyId = this.motorPolicyId + 1;
}
// creates csv file
writeToFile();
// prints completed user input of policy holder
System.out.println();
System.out.println("Surname :" + this.surname);
System.out.println("Age :" + this.age);
System.out.println("Policy Ref :" + this.motorPolicyId);
System.out.println("Motor Type: :" + this.motorType);
System.out.println(); // used to create next line space
// asks user if they would like to create a different policy holder
System.out.println("Add another Policy Holder (Y or N)..");
addAnother = scanner.next();
} while (addAnother.equalsIgnoreCase("Y")); // If N program ends.
} catch (Exception exception) { // if exception program ends
System.out.println(
"There is a problem ... Policy Holder does meet necessary criteria, run the program again.");
} finally {
scanner.close();
System.out.println("Program ended!"); // end of program
}
}
public static void main(String[] args) throws IOException {
InsurancePolicy insurancePolicy = new InsurancePolicy();
insurancePolicy.addPolicyHolder();
}
}
I am able to complete a first run but do while loop fails when trying to add another policy holder.
Related
I have a project that is a hardware store consisting of methods that save, search, and edit data. The data is the items stored in a txt database. I have to create a JUNIT test case that tests the methods of the hardware store class. There are three classes in total: hardwarestore, mainapp, and item. But the only one that needs to be tested is hardwarestore. And the only methods that don't need to be tested are the readDatabase() and the writeDatabase().
For my JUNIT classes I have hardwarestoretest that I will implement with test methods for the hardwarestore class. I also have a testrunner class that runs the test methods in hardwarestoretest. The test methods will compose of assertion tests.
Assertions
I am fairly new with JUNIT testing and need just some help getting started. I wrote part of the test classes but they fail when ran. The output I get says that there are no runnable tests even though I tried to implement a test method for addNewItem.
Here is my code for hardwarestore in a hardwarestore package
Item.java
package hardwarestore;
/**
* This class is a very simple representation of a hardware item. There are only getter
* methods and no setter methods and as a result an item cannot be mutated once
* initialized. An item object can also call the two override methods
* <CODE>toString()</CODE> and <CODE>equals()</CODE>
*
* #author Junye Wen
*/
public class Item {
private final String idNumber;
private final String name;
private final String category;
private int quantity;
private final float price;
/**
* This constructor initializes the item object. The constructor provides no
* user input validation. That should be handled by the class that creates a
* item object.
*
* #param idNumber a <b><CODE>String</CODE></b> that represents the ID
* random string of length 5 – can contain letters and numbers
*
* #param name a <b><CODE>String</CODE></b> that represents the name.
*
* #param category a <b><CODE>String</CODE></b> that represents the category.
* Door&Window, Cabinet& Furniture, Fasteners, Structural, Other.
*
* #param quantity a <b><CODE>int</CODE></b> that represents the quantity
*
* #param price an <b><CODE>float</CODE></b> that represents the price
*
*/
public Item(String idNumber, String name, String category, int quantity, float price) {
this.idNumber = idNumber;
this.name = name;
this.category = category;
this.quantity = quantity;
this.price = price;
}
/**
* This method returns the item's tracking number.
*
* #return a <b><CODE>String</CODE></b> that is the ID number of the item.
*/
public String getIdNumber() {
return idNumber;
}
/**
* This method returns the item's name.
*
* #return a <b><CODE>String</CODE></b> that is the item's name.
*/
public String getName() {
return name;
}
/**
* This method returns the item's category.
*
* #return a <b><CODE>String</CODE></b> that is the item's category.
*/
public String getCategory() {
return category;
}
/**
* This method returns the item's quantity.
*
* #return an <b><CODE>int</CODE></b> that is the item's weight
*/
public int getQuantity() {
return quantity;
}
/**
* This method set the item's quantity.
*
* #param quantity a <b><CODE>int</CODE></b> that represents the quantity
*/
public void setQuantity(int quantity) {
this.quantity= quantity;
}
/**
* This method returns the item's price.
*
* #return a <b><CODE>float</CODE></b> that is the item's price
*/
public float getPrice() {
return price;
}
/**
* This method returns the item's fields as a string representation.
*
* #return a <b><CODE>String</CODE></b> that lists the fields of the item
* object delineated by a space and in the same order as the constructor
*/
#Override
public String toString() {
return idNumber + "~" + name + "~" + category + "~" + quantity + "~"
+ String.format("%.2f", price) + "\n";
}
/**
* This method provides a way to compare two item objects.
*
* #param c a <b><CODE>Item</CODE></b> object that is used to compare to
* <b><CODE>this</CODE></b> item. Two orders are equal if their ID is the
* same.
* #return the <CODE>boolean</CODE> value of the comparison.
*/
public boolean equals(Item c) {
return c.getIdNumber().equals(this.idNumber);
}
}
HardwareStore.java
package hardwarestore;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Scanner;
/**
* This class is used to represent a database interface for a list of
* <CODE>item</CODE>'s. It using a plain-text file "database.txt" to store and
* write item objects in readable text form. It contains an
* <CODE>ArrayList</CODE> called <CODE>itemList</CODE> to store the database in
* a runtime friendly data structure. The <CODE>itemList</CODE> is written to
* "database.txt" at the end of the <CODE>HardwareStore</CODE> object's life by
* calling <CODE>writeDatabase()</CODE>. This class also provides methods for
* adding, removing, and searching for items in the list.
*
* #author Junye Wen
*/
public class HardwareStore {
private ArrayList<Item> itemList;
private static final String DATA_FILE_NAME = "database.txt";
/**
* This constructor creates an empty ArrayList and then calls the
* <CODE>readDatabase()</CODE> method to populate items previously stored.
*
* #throws IOException
*/
public HardwareStore() throws IOException {
itemList = new ArrayList<>();
readDatabase();
}
/**
* Method getAllItemsFormatted returns the current list of items in the Arraylist in
* no particular order.
*
* #return a formatted String representation of all the items in itemList.
*/
public String getAllItemsFormatted() {
return getFormattedItemList(itemList);
}
/**
* Private method getFormattedPackageList used as an auxiliary method to return a given ArrayList
* of items in a formatted manner.
*
* #param items the item list to be displayed.
* #return a formatted String representation of all the items in the list give as a parameter.
*/
private String getFormattedItemList(ArrayList<Item> items) {
String text = " ------------------------------------------------------------------------------------\n" +
String.format("| %-10s| %-25s| %-20s| %-10s| %-10s|%n", "ID Number", "Name", "Category", "Quantity", "Price") +
" ------------------------------------------------------------------------------------\n";
for (int i = 0; i < items.size(); i++) {
text += String.format("| %-10s| %-25s| %-20s| %-10s| %-10s|%n",
items.get(i).getIdNumber(),
items.get(i).getName(),
items.get(i).getCategory(),
Integer.toString(items.get(i).getQuantity()),
String.format("%.2f", items.get(i).getPrice()));
}
text += " ------------------------------------------------------------------------------------\n";
return text;
}
/**
* This method is used to add a item to the itemList ArrayList.
*
* #param idNumber a <CODE>String</CODE> representing the ID number of item
* #param name a <CODE>String</CODE> representing the name of item
* #param category a <CODE>String</CODE> representing the category of item
* #param quantiy an <CODE>int</CODE> representing the quantiy of item
* #param price a <CODE>float</CODE> representing the price of item
*/
public void addNewItem(String idNumber, String name, String category, int quantiy, float price) {
//If passed all the checks, add the item to the list
itemList.add(new Item(idNumber, name, category, quantiy, price));
System.out.println("Item has been added.\n");
}
/**
* Add a certain quantity of the given item index.
* Preconditions: 1. Item exists.
* #param itemIndex the index of the item in the itemList
* #param quantity the quantity to remove
*/
public void addQuantity(int itemIndex, int quantity) {
Item temp = getItem(itemIndex);
temp.setQuantity(temp.getQuantity() + quantity);
System.out.println("Quantity updated.\n");
}
/**
* Removes a certain quantity of the given item index.
* Preconditions: 1. Item exists. 2. Quantity to remove smaller than current quantity.
* #param itemIndex the index of the item in the itemList
* #param quantity the quantity to remove
*/
public void removeQuantity(int itemIndex, int quantity) {
Item temp = getItem(itemIndex);
temp.setQuantity(temp.getQuantity() - quantity);
System.out.println("Quantity updated.\n");
}
/**
* Returns all the items that (partially) match the given name.
* #param name the name to match.
* #return a string containing a table of the matching items.
*/
public String getMatchingItemsByName(String name) {
ArrayList<Item> temp = new ArrayList<Item>();
for (Item tempItem : itemList) {
if (tempItem.getName().toLowerCase().contains(name.toLowerCase())) {
temp.add(tempItem);
}
}
if (temp.size() == 0) {
return null;
} else {
return getFormattedItemList(temp);
}
}
/**
* Returns all the items with current quantity lower than (or equal) the
* given threshold.
* #param quantity the quantity threshold.
* #return a string containing a table of the matching items.
*/
public String getMatchingItemsByQuantity(int quantity) {
ArrayList<Item> temp = new ArrayList<Item>();
for (Item tempItem : itemList) {
if (tempItem.getQuantity() <= quantity) {
temp.add(tempItem);
}
}
if (temp.isEmpty()) {
return null;
} else {
return getFormattedItemList(temp);
}
}
/**
* This method can be used to find a item in the Arraylist of items.
*
* #param idNumber a <CODE>String</CODE> that represents the ID number of
* the item that to be searched for.
* #return the <CODE>int</CODE> index of the items in the Arraylist of
* items, or -1 if the search failed.
*/
public int findItem(String idNumber) {
int index = -1;
for (int i = 0; i < itemList.size(); i++) {
String temp = itemList.get(i).getIdNumber();
if (idNumber.equalsIgnoreCase(temp)) {
index = i;
break;
}
}
return index;
}
/**
* This method is used to retrieve the Item object from the
* <CODE>itemList</CODE> at a given index.
*
* #param i the index of the desired <CODE>Item</CODE> object.
* #return the <CODE>Item</CODE> object at the index or null if the index is
* invalid.
*/
public Item getItem(int i) {
if (i < itemList.size() && i >= 0) {
return itemList.get(i);
} else {
System.out.println("Invalid Index.\n");
return null;
}
}
/**
* This method opens the database file and overwrites it with a
* text representation of all the items in the <CODE>itemList</CODE>. This
* should be the last method to be called before exiting the program.
*
* #throws IOException
*/
public void writeDatabase() throws IOException {
PrintWriter pw = new PrintWriter(DATA_FILE_NAME);
for (Item c : itemList) {
pw.print(c.toString());
}
pw.close();
}
/**
* The method opens the database file and initializes the <CODE>itemList</CODE>
* with its contents. If no such file exists, then one is created.
* The contents of the file are "loaded" into the itemList ArrayList in no
* particular order. The file is then closed during the duration of the
* program until <CODE>writeDatabase()</CODE> is called.
*
* #throws IOException
*/
public void readDatabase() throws IOException {
File dataFile = new File(DATA_FILE_NAME);
// If data file does not exist, create it.
if (!dataFile.exists()) {
System.out.println("database.txt does not exist, creating one now . . .");
//if the file doesn't exists, create it
PrintWriter pw = new PrintWriter(DATA_FILE_NAME);
//close newly created file so we can reopen it
pw.close();
return; // No need to try to read anything from an empty file, so return.
}
Scanner itemScanner = new Scanner(new FileReader(dataFile));
//Initialize the Array List with items from database.txt
while (itemScanner.hasNextLine()) {
// split values using the space character as separator
String[] temp = itemScanner.nextLine().split("~");
itemList.add(new Item(temp[0], temp[1], temp[2],
Integer.parseInt(temp[3]), Float.parseFloat(temp[4])));
}
//item list is now in the ArrayList completely so we can close the file
itemScanner.close();
}
}
MainApp.java
package hardwarestore;
import java.io.IOException;
import java.util.Scanner;
/**
* This is the main class of the Hardware Store database manager. It provides a
* console for a user to use the 5 main commands.
*
* #author Junye Wen
*/
public class MainApp {
// This object will allow us to interact with the methods of the class HardwareStore
private final HardwareStore hardwareStore;
private static final Scanner CONSOLE_INPUT = new Scanner(System.in); // Used to read from System's standard input
/**
* Default constructor. Initializes a new object of type HardwareStore
*
* #throws IOException
*/
public MainApp() throws IOException {
hardwareStore = new HardwareStore();
}
/**
* Shows all items in the inventory.
*/
public void showAllItems() {
System.out.print(hardwareStore.getAllItemsFormatted());
}
/**
* This method will add items quantity with given number. If the item does
* not exist, it will call another method to add it.
*
*/
public void addItemQuantity() {
System.out.println("Please input the ID of item");
String idNumber = CONSOLE_INPUT.nextLine();
if (!idNumber.matches("[A-Za-z0-9]{5}")) {
System.out.println("Invalid ID Number: not proper format. "
+ "ID Number must be 5 alphanumeric characters.\n");
return;
}
int itemIndex = hardwareStore.findItem(idNumber);
if (itemIndex != -1) { // If item exists in the database
System.out.println("Item found in database. Please enter quantity to add.");
int quantity = CONSOLE_INPUT.nextInt();
if (quantity <= 0) {
System.out.println("Invalid quantity. "
+ "The addition amount must be larger than 0.\n");
return;
}
hardwareStore.addQuantity(itemIndex, quantity);
} else {
//If it reaches here, the item does not exist. We need to add new one.
System.out.println("Item with given number does not exist.\n");
// Enter name
System.out.println("\nPlease type the name of item.");
String name = CONSOLE_INPUT.nextLine();
// Entery category
String category = null;
System.out.println("\nPlease select the category of item.");
System.out.println("1: Door&Window\n2: Cabinet&Furniture\n3: Fasteners\n4: Structural\n5: Other");
int selection = CONSOLE_INPUT.nextInt();
switch (selection) {
case 1:
category = "Door&Window";
break;
case 2:
category = "Cabinet&Furniture";
break;
case 3:
category = "Fasteners";
break;
case 4:
category = "Structural";
break;
case 5:
category = "Other";
break;
default:
System.out.println("Invalid category number.");
return;
}
// Entery quantity
System.out.println("\nPlease type the quantity of the item.");
int quantity = CONSOLE_INPUT.nextInt();
if (quantity < 0) {
System.out.println("Invalid price. "
+ "The quantity cannot be smaller than 0.");
return;
}
// Enter price
System.out.println("\nPlease type the price of the item.");
float price = CONSOLE_INPUT.nextFloat();
if (price < 0) {
System.out.println("Invalid price. "
+ "The price cannot be smaller than 0.");
return;
}
hardwareStore.addNewItem(idNumber, name, category, quantity, price);
}
}
/**
* This method will remove the given quantity of an item with given number.
* If the item does not exist, it will show an appropriate message.
*/
public void removeItemQuantity() {
System.out.println("Please input the ID of item");
String idNumber = CONSOLE_INPUT.nextLine();
if (!idNumber.matches("[A-Za-z0-9]{5}")) {
System.out.println("Invalid ID Number: not proper format. "
+ "ID Number must be at least 5 alphanumeric characters.");
return;
}
int itemIndex = hardwareStore.findItem(idNumber);
int currentQuantity;
if (itemIndex == -1) {
System.out.println("Item does not exist.\n");
return;
} else {
currentQuantity = hardwareStore.getItem(itemIndex).getQuantity();
System.out.println("Current quantity: " + currentQuantity + "\n");
}
System.out.println("Please input the quantity to remove.");
int quantity = CONSOLE_INPUT.nextInt();
if (quantity > currentQuantity) {
System.out.println("Invalid quantity. "
+ "The removal amount must be smaller than current quantity.\n");
} else {
hardwareStore.removeQuantity(itemIndex, quantity);
}
}
/**
* This method can search item by a given name (part of name.
* Case-insensitive.) Will display all items with the given name.
*/
public void searchItemByName() {
System.out.println("Please input the name of item.\n");
String name = CONSOLE_INPUT.nextLine();
String output = hardwareStore.getMatchingItemsByName(name);
if (output == null) {
System.out.println("Item not found.");
} else {
System.out.println(output);
}
}
/**
* This method can search item below a certain quantity. Will display all
* items fits such condition.
*/
public void searchItemByQuantity() {
System.out.println("Please enter the quantity:\n");
int quantity = CONSOLE_INPUT.nextInt();
if (quantity < 0) {
System.out.println("Quantity should be at least 0.\n");
}
String output = hardwareStore.getMatchingItemsByQuantity(quantity);
if (output == null) {
System.out.println("No items found below given quantity.");
} else {
System.out.println(output);
}
}
public void saveDatabase() throws IOException {
hardwareStore.writeDatabase();
}
/**
* This method will begin the user interface console. Main uses a loop to
* continue executing commands until the user types '6'.
*
* #param args this program expects no command line arguments
* #throws Exception
*/
public static void main(String[] args) throws Exception {
MainApp app = new MainApp();
String welcomeMessage = "\nWelcome to the Hardware Store database. Choose one of the following functions:\n\n"
+ "\t1. Show all existing items in stock and their quantities.\n"
+ "\t2. Add a new quantity of a specific item to the stock.\n"
+ "\t3. Remove a certain quantity of a specific item type.\n"
+ "\t4. Search for an item (given its name or part of its name).\n"
+ "\t5. Show a list of all items below a certain quantity.\n"
+ "\t6. Exit program.\n";
System.out.println(welcomeMessage);
int selection = CONSOLE_INPUT.next().charAt(0);
CONSOLE_INPUT.nextLine();
while (selection != '6') {
switch (selection) {
case '1':
app.showAllItems();
break;
case '2':
app.addItemQuantity();
break;
case '3':
app.removeItemQuantity();
break;
case '4':
app.searchItemByName();
break;
case '5':
app.searchItemByQuantity();
break;
case 'h':
System.out.println(welcomeMessage);
break;
default:
System.out.println("That is not a recognized command. Please enter another command or 'h' to list the commands.");
break;
}
System.out.println("Please enter another command or 'h' to list the commands.\n");
selection = CONSOLE_INPUT.next().charAt(0);
CONSOLE_INPUT.nextLine();
}
CONSOLE_INPUT.close();
System.out.print("Saving database...");
app.saveDatabase();
System.out.println("Done!");
}
}
Here are my test classes in a test package
HardwareStoreTest.java
package test;
import static org.junit.Assert.assertNotNull;
import java.io.IOException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.jupiter.api.Test;
import hardwarestore.*;
public class HardwareStoreTest {
public static HardwareStore hardwarestore = null;
#BeforeClass
public static void createEnvironment() throws IOException {
hardwarestore = new HardwareStore();
}
#AfterClass
public static void clearEnvironment() {
hardwarestore = null;
System.out.println("Environment cleared");
}
#Test
public static void testAddItem() {
hardwarestore.addNewItem("123543","sink","other",23,24.95f);
assertNotNull("Test Failed message", hardwarestore.getItem(0));
}
}
TestRunner.java
package test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(HardwareStoreTest.class);
if(result.getFailures().size()==0) {
System.out.println("All tests successfull!");
}else {
System.out.println("No. of failed test cases = "+ result.getFailures().size());
for(Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
}
}
}
Change your import at the top and the Test shouldn't be static.
import org.junit.Test
#Test
public void addNewItem(){
hardwarestore.addNewItem("123RT", "sink", "kitchen", 34, 4.51f);
assertNotNull("Test Failed Message", hardwarestore.getItem(0));
}
I am currently enrolled in the Udacity Android Basics Nanodegree program.
One task now is to create a ReportCard Java Class which would allow a school to store a student’s grades for a particular year.
While I submitted my project and it successfully passed review, I was given the suggestion of using an ArrayList instead of hard-coding the subjects for which grades could be given.
While implementing this suggestion, I am extremely struggling. I already searched throught StackOverflow for hours and haven't yet found a problem-solving answer.
So, here is my code:
package com.example.android.reportcardclass;
/**
* Report Card class
* This class prepares a student report card.
*/
public class ReportCard {
/**
* Class Attributes
*/
private String mStudentName;
private int mYear;
private byte mGerman;
private byte mEnglish;
private byte mMathematics;
private byte mGeography;
private byte mSocialSciencesAndEconomics;
private byte mPhysics;
private byte mReligion;
private byte mPhysEd;
private byte mMusic;
/**
* Default Constructor for ReportCard class
*
* #param studentName Name of the student
* #param year Year in which the student is in
* #param german Mark in the subject German
* #param english Mark in the subject English
* #param mathematics Mark in the subject Mathematic
* #param geography Mark in the subject Geography
* #param socialSciencesAndEconomics Mark in the subject Social Sciences and Economics
* #param physics Mark in the subject Physcics
* #param religion Mark in the subject Religion
* #param physEd Mark in the subject Physical Education
* #param music Mark in the subject Music
*/
public ReportCard(String studentName, int year,
byte german, byte english, byte mathematics,
byte geography, byte socialSciencesAndEconomics,
byte physics, byte religion, byte physEd,
byte music) {
mGerman = german;
mEnglish = english;
mMathematics = mathematics;
mGeography = geography;
mSocialSciencesAndEconomics = socialSciencesAndEconomics;
mPhysics = physics;
mReligion = religion;
mPhysEd = physEd;
mMusic = music;
}
/**
* This method is to get Student Name
*
* #return Student Name
*/
public String getStudentName() {
return mStudentName;
}
/**
* This method is to set Student Name
*
* #param studentName Name of the student
*/
public void setStudentName(String studentName) {
mStudentName = studentName;
}
/**
* This method is to get the year in which the student is in
*
* #return Year in which the student is in
*/
public int getYear() {
return mYear;
}
/**
* This method is to set the year in which the student is in
*
* #param year Year in which the student is in
*/
public void setYear(int year) {
mYear = year;
}
/**
* These are the setter and getter methods for the marks of the student in the respective subject
*/
public byte getGerman() {
return mGerman;
}
public void setGerman(byte german) {
mGerman = german;
}
public byte getEnglish() {
return mEnglish;
}
public void setEnglish(byte english) {
mEnglish = english;
}
public byte getMathematics() {
return mMathematics;
}
public void setMathematics(byte mathematics) {
mMathematics = mathematics;
}
public byte getGeography() {
return mGeography;
}
public void setGeography(byte geography) {
mGeography = geography;
}
public byte getSocialSciencesAndEconomics() {
return mSocialSciencesAndEconomics;
}
public void setSocialSciencesAndEconomics(byte socialSciencesAndEconomics) {
mSocialSciencesAndEconomics = socialSciencesAndEconomics;
}
public byte getPhysics() {
return mPhysics;
}
public void setPhysics(byte physics) {
mPhysics = physics;
}
public byte getReligion() {
return mReligion;
}
public void setReligion(byte religion) {
mReligion = religion;
}
public byte getPhysEd() {
return mPhysEd;
}
public void setPhysEd(byte physEd) {
mPhysEd = physEd;
}
public byte getMusic() {
return mMusic;
}
public void setMusic(byte music) {
mMusic = music;
}
#Override
public String toString() {
return "Student Name: " + getStudentName() + "\nYear: " + getYear() + "German: "
+ getGerman() + "\nEnglish: " + getEnglish() + "\nMathematics: " +
getMathematics() + "\nGeography: " + getGeography() +
"\nSocialSciencesAndEconomics: " + getSocialSciencesAndEconomics() +
"\nPhysics: " + getPhysics() + "\nReligion: " + getReligion() +
"\nPhysical Education: " + getPhysEd() + "\nMusic: " + getMusic();
}
}
What I want to do now, is to store the class attributes initialized at the very beginning (mGerman, mEnglish, etc.) in an ArrayList. How do I do that?! I am extremely struggling as I don't want to set any values just yet, but simply initialize the byte values (grading system in Germany goes from 0 to 15 points).
Please help me, thank you very much in advance!
If you know how many grades there are going to be you can use the following to initialize an ArrayList with null values:
List<Byte> bytes = new ArrayList<Byte>(Arrays.asList(new Byte[9]));
To update values in the List you can use for example
bytes.set(3, (byte) 12);
Try this
ArrayList<ReportCard> mList=new ArrayList<>();
ReportCard reportCard=new ReportCard();
reportCard.setStudentName("student name");
//fill all the details like this
reportCard.setYear("2017");
.
.
mList.add(reportCard);
And when you want to get the details do like this
String studentName=mList.get(position).getStudentName();
I suggest you to use an EnumSet instead of a list to store the grades, for the following reasons:
It provides a more compact representation in memory
It only accepts values of well-defined grades thanks to enum
It prevents duplicates
It allows to check if a grade is present with O(1) complexity.
First define an enum with the grades:
public enum Grade {
GERMAN, ENGLISH, MATHEMATICS, GEOGRAPHIC, SOCIAL_SCIENCES_AND_ECONOMICS,
PHYSICS, RELIGION, PHYSICAL_EDUCATION, MUSIC
}
Then you can expose methods to add or remove a grade for example, that will delegate to the EnumSet methods:
private final EnumSet<Grade> grades = EnumSet.noneOf(Grade.class);
public boolean add(Grade grade) {
return grades.add(grade);
}
public boolean remove(Grade grade) {
return grades.remove(grade);
}
It seems that 20 regiments were in a continuous process of formation. The first had 1000 men, the second had 950, the third 900, and so on down to the twentieth regiment, which garrisoned only 50. During each week, 100 men were added to each regiment, and at week's end, the largest regiment was sent off to the front.This lasted for a total of 20 weeks.
For this program I have already managed to print out the original number of men for each regiment. But I am having difficult adding 100 men to each regiment.The adding men must be a method in the army class. I am getting the regiment objects using a .txt file. All this files contains is the names of regiments numbered 1-20.
public class Regiment {
private String name; //name of regiment
private int regNumber; //regiment number
private int men; // regiment men
/**
* Creates a Regiment object.
*
* #param regNumber the regiment number
* #param name the name of the regiment
* #param men the number of men in a regiment
*/
public Regiment(int regNumber, String name, int men) {
this.name = name;
this.regNumber = regNumber;
this.men = men;
}
/**
* Returns the name of the regiment.
*
* #return the regiment name
*/
public String getName() {
return name;
}
/**
* Returns the number of the regiment.
*
* #return regiment number
*/
public int getregNumber() {
return regNumber;
}
/**
* Returns the number of men in a regiment.
*
* #return men in regiment
*/
public int getMen() {
return men;
}
/**
* Computes the number of men in a regiment
*/
public int addMen2(int RegNumber) {
int men = 1050 - (regNumber * 50);
return men;
}
}
class ArmyDataList {
public ArrayList<Regiment> list; // list of regiment objects
/**
* Creates an empty list
*/
public ArmyDataList() {
list = new ArrayList<Regiment>();
}
/**
* Appends a regiment object to the list.
*
* #param current the object to be appended to the list
*/
public void AddToList(Regiment current) {
list.add(current);
}
/**
* Removes a regiment object to the list.
*
* #param current the object to be removed from the list
*/
public void RemoveFromList(Regiment current) {
list.remove(current);
}
/**
* Gets the largest regiment based on men.
*/
public Regiment getLargest() {
if (list.isEmpty()) {
return null;
}
Regiment Reg1 = list.get(0);
for (int i = 1; i < list.size(); i++) {
Regiment current = list.get(i); // get next regiment
// is current regiment > largest
if (current.getMen() > Reg1.getMen()) {
Reg1 = current;
}
}
return Reg1;
}
/**
* Adds men to each regiment.
*/
public void addMen() {
}
/**
* Converts the list to a multi-line string, with each line containing the
* data for one regiment.
*
* #return the String containing all the data on the list
*/
public String toString() {
String out
= String.format("%28s%12s%n", "Regiments", " Men")
+ String.format("%12s%n", "Number")
+ String.format("%12s%16s%14s%n", "=======", "===============",
"=========");
for (int i = 0; i < list.size(); i++) {
Regiment regim = list.get(i);
int regNumber = regim.getregNumber();
String name = regim.getName();
int men = regim.addMen2(regNumber);
out = out + String.format("%12s", regNumber)
+ String.format("%16s", name)
+ String.format("%10s", men)
+ "\n";
}
return out + "\n";
}
}
public class RegimentTest {
public static void main(String[] args) throws IOException
{
ArmyDataList army = new ArmyDataList();
// create Scanner object to read each line of file until eof
Scanner fileScan = new Scanner(new File("regiments.txt"));
System.out.println("Report Summary:\n");
while (fileScan.hasNext()) // while not eof...
{
// read next line
String line = fileScan.nextLine();
// "echo print" data entered
System.out.println(line);
// 1. create a Scanner object
Scanner in = new Scanner(line) ;
// 2. extract tokens from current line
int regNumber = in.nextInt();
String name = in.next();
int men = 0 ; //men is set to 0 only because I havent add the men yet
// 3. create Regiment object passing the tokens to the constructor
Regiment adder = new Regiment(regNumber, name, men );
// 4. add object to list
army.AddToList(adder) ;
}
System.out.println(army.toString());
}
You can write addNewMen() method in Regiment Class where you can add 100 more men as men is the property of regiment.
I had a project for school that I could just not get to compile correctly.
The instructions can be found at this link.
I believe I have the class created correctly in Product.java. My code is below:
import java.util.*;
public class Product {
// Private member variables go here - you will need to add them yourself.
private String name;
private String code;
private int quantity;
private double price;
private String type;
private ArrayList<Integer> userRatings;
/*
* Product constructor
*/
public Product() {
name = "";
code = "";
quantity = 0;
price = 0;
type = "";
userRatings = new ArrayList<Integer>();
}
/*
* setName
* #param name - new name for the product
*/
public void setName(String name) {
this.name = name;
}
/*
* getName
* #return the name of the product
*/
public String getName() {
return name;
}
/*
* setType
* #param type - the type of the product
*/
public void setType(String type) {
this.type = type;
}
/*
* getType
* #return - the product type
*/
public String getType() {
return type;
}
/*
* setPrice
* #param price - the price of the product
*/
public void setPrice(double price) {
this.price = price;
}
/*
* getPrice
* #return the price of the product
*/
public double getPrice() {
return price;
}
/*
* setQuantity
* #param quantity - the number of this product in inventory
*/
public void setQuantity(int quantity) {
this.quantity = quantity;
}
/*
* getQuantity
* #return the number of this product in inventory
*/
public int getQuantity() {
return quantity;
}
/*
* setInventoryCode
* #param code - the new inventory code for the product
*/
public void setInventoryCode(String code) {
this.code = code;
}
/*
* getInventoryCode
* #return the inventory code of the product
*/
public String getInventoryCode() {
return code;
}
/*
* addUserRating
* NOTE: Each individual rating is stored with the product, so you need to maintain a list
* of user ratings. This method should append a new rating to the end of that list
* #param rating - the new rating to add to this product
*/
public void addUserRating(int rating) {
userRatings.add(rating);
}
/*
* getUserRating
* NOTE: See note on addUserRating above. This method should be written to allow you
* to access an individual value from the list of user ratings
* #param index - the index of the rating we want to see
* #return the rating indexed by the value index
*/
public int getUserRating(int index) {
return userRatings.get(index);
}
/*
* getUserRatingCount
* NOTE: See note on addUserRating above. This method should be written to return
* the total number of ratings this product has associated with it
* #return the number of ratings associated with this product
*/
public int getUserRatingCount() {
return userRatings.size();
}
/*
* getAvgUserRating
* NOTE: see note on addUserRating above. This method should be written to compute
* the average user rating on demand from a stored list of ratings.
* #return the average rating for this product as a whole integer value (use integer math)
*/
public int getAvgUserRating() {
int sum = 0;
if(userRatings.size() > 0){
for (int i = 0; i < userRatings.size(); i++){
sum += userRatings.get(i);
}
return sum / userRatings.size();
}
else return 0;
}
}
But the problem lies within the test code. I have tried multiple ways and keep getting the same InputMismatchException error. I will need an ArrayList of Product objects for part 2 so I tried to incorporate that into the test code. Below is ProductTest.java:
import java.util.*;
import java.io.*;
public class ProductTest {
/*
* A simple main loop to load product objects from a file
* and then display them to the console
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter an inventory filename: ");
String fname = keyboard.nextLine();
ArrayList<Product> products = loadProducts (fname);
displayProducts(products);
}
/*
* loadProducts
* Given a filename, opens the file and reads Products from
* the file into an ArrayList of Product objects. Returns the
* Arraylist.
*
* #param fname - String containing the input file name
* #return - An ArrayList of Product objects
*/
public static ArrayList<Product> loadProducts(String fname) {
ArrayList<Product> products = new ArrayList<Product>();
try {
Scanner inFile = new Scanner(new File(fname));
while (inFile.hasNext()) {
Product pr = new Product();
pr.setName(inFile.next());
pr.setInventoryCode(inFile.next());
pr.setQuantity(inFile.nextInt());
pr.setPrice(inFile.nextDouble());
pr.setType(inFile.next());
while(inFile.nextInt() != -1){
pr.addUserRating(inFile.nextInt());
}
products.add(pr);
}
inFile.close();
}
catch(IOException e) {
System.out.println("ERROR: "+e);
}
return products;
}
/*
* displayProducts
* Given an ArrayList of Product objects, outputs them
* to the console in the specified format.
*
* The format for this method is:
* NAME, INVENTORY_CODE, QUANTITY, PRICE, TYPE, RATING
*
* #param products - ArrayList of Product objects
*/
public static void displayProducts(ArrayList<Product> products) {
for(int i = 0; i<products.size(); i++) {
Product tmpProduct = products.get(i);
System.out.println(tmpProduct.getName());
System.out.println(tmpProduct.getInventoryCode());
System.out.println(tmpProduct.getQuantity());
System.out.println(tmpProduct.getPrice());
System.out.println(tmpProduct.getType());
System.out.println(tmpProduct.getAvgUserRating());
System.out.println();
}
}
}
This is the error message that results from running the current ProductTest:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at osu.cse2123.ProductTest.loadProducts(ProductTest.java:46)
at osu.cse2123.ProductTest.main(ProductTest.java:23)
The text file I'm using contains the following:
The Shawshank Redemption
C0000001
100
19.95
DVD
4
5
3
1
-1
The Dark Knight
C0000003
50
19.95
DVD
5
2
3
-1
Casablanca
C0000007
137
9.95
DVD
5
4
5
3
-1
The Girl With The Dragon Tattoo
C0000015
150
14.95
Book
4
4
2
-1
Vertigo
C0000023
55
9.95
DVD
5
5
3
5
2
4
-1
A Game of Thrones
C0000019
100
8.95
Book
-1
Any help on the issues would be much appreciated.
You are reading one word at a time. Currently your file is being read by the Scanner like this:
inFile.next() = The
inFile.next() = Shawshank
Tip: inFile.nextLine() = The Shawshank Redeption
You problem is in the while loop reading ratings:
while(inFile.nextInt() != -1){
pr.addUserRating(inFile.nextInt());
}
Each round of the loop reads two items - one in the while condition, and another one inside the loop. Since there's a String (the next title) after the ratings end, if there was an even number of ratings you'd fail here when trying to interpret it as an int (and if it doesn't fail you'd just get the wrong result, since you're skipping half the ratings). One way to fix this is to extract the rating to a local variable:
int rating;
while(rating = inFile.nextInt() != -1){
pr.addUserRating(rating);
}
I suggest you realise how many times you are invoking readInt consecutively. Imagine an alternative way to read a value, check it, and reuse it without re-reading.
Without a better formating of your file (no end of line), you need to use a regex matching :
Something like this :
public static ArrayList<Product> loadProducts(String fname) {
ArrayList<Product> products = new ArrayList<Product>();
Pattern p = Pattern.compile("([\\w ]*) (C[0-9]*) (\\d*) ([\\d\\.]*) (\\w*) ([\\d -]*)");
Matcher m = p.matcher(fname);
while (m.find()) {
Product pr = new Product();
pr.setName(m.group(1));
pr.setInventoryCode(m.group(2));
pr.setQuantity(Integer.parseInt(m.group(3)));
pr.setPrice(Double.parseDouble(m.group(4)));
pr.setType(m.group(5));
for (String rate : m.group(6).split(" ")) {
pr.addUserRating(Integer.parseInt(rate));
}
products.add(pr);
System.out.println(pr);
}
return products;
}
The InputMismatchException occurs when you call nextDouble() or nextInt() from a Scanner instance while instead you enter something other than a number. The error message shows that the flaw lies within the loadProducts method.
In that method you make a call to next() to get product name and inventory code. However, since your product name contains spaces, you should call nextLine() instead.
What happens in your program is this: Calling next() on "The Shawshank Redemption" will return "The". By the time you reach pr.setQuantity(inFile.nextInt()); your program will throw the InputMismatchException because it tries to read an integer from "Redemption".
Also take into account the advice from mureinik:
https://stackoverflow.com/a/25936439/4056420
I have a class that implements the Comparable interface. In this class I need to override compareTo method in order to sort objects by String values.
If you scroll down to the bottom I'm attempting to make my method & I need to in the main method sort an array of Courses (using the compareTo method I'm making) by first Department type and then by course number, etc. but this requires comparing 2 strings.
import java.io.Serializable;
import java.io.*;
import java.util.*;
public class Course implements Comparable<Course>, Serializable {
private String prefix;
private int number;
private String Department;
private String grade;
/**
* Constructs the course with the specified information.
*
* #param prefix the prefix of the course designation
* #param number the number of the course designation
* #param Department the Department of the course
* #param grade the grade received for the course
*/
public Course(String prefix, int number, String Department, String grade)
{
this.prefix = prefix;
this.number = number;
this.Department = Department;
if (grade == null)
this.grade = "";
else
this.grade = grade;
}
/**
* Constructs the course with the specified information, with no grade
* established.
*
* #param prefix the prefix of the course designation
* #param number the number of the course designation
* #param Department the Department of the course
*/
public Course(String prefix, int number, String Department)
{
this(prefix, number, Department, "");
}
public String getPrefix()
{
return prefix;
}
/**
* Returns the number of the course designation.
*
* #return the number of the course designation
*/
public int getNumber()
{
return number;
}
/**
* Returns the Department of this course.
*
* #return the prefix of the course
*/
public String getDepartment()
{
return Department;
}
/**
* Returns the grade for this course.
*
* #return the grade for this course
*/
public String getGrade()
{
return grade;
}
/**
* Sets the grade for this course to the one specified.
*
* #param grade the new grade for the course
*/
public void setGrade(String grade)
{
this.grade = grade;
}
/**
* Returns true if this course has been taken (if a grade has been received).
*
* #return true if this course has been taken and false otherwise
*/
public boolean taken()
{
return !grade.equals("");
}
* Determines if this course is equal to the one specified, based on the
* course designation (prefix and number).
*
* #return true if this course is equal to the parameter
*/
public boolean equals(Object other)
{
boolean result = false;
if (other instanceof Course)
{
Course otherCourse = (Course) other;
if (prefix.equals(otherCourse.getPrefix()) &&
number == otherCourse.getNumber())
result = true;
}
return result;
}
The compareTo function:
public int compareTo(Course o)
{
if(getDepartment().equals(o.getDepartment()))
{
return 0;
}
else if()
{
return -1;
}
else
{
return 1;
}
}
/**
* Creates and returns a string representation of this course.
*
* #return a string representation of the course
*/
public String toString()
{
String result = prefix + " " + number + ": " + Department;
if (!grade.equals(""))
result += " [" + grade + "]";
return result;
}
}
Main class thus far:
import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import java.*;
public class StackCourse
{
public static void main(String[] args)
{
Course a = new Course("EEE", 230, "Engineering");
Course b = new Course("MAT", 150, "Liberal Arts");
Course c = new Course("PHY", 150, "Liberal Arts");
Course d = new Course("PHI", 304, "Liberal Arts");
Course e = new Course("ECN", 214, "W.P. Carey");
Course f = new Course("EEE", 120, "Engineering");
Course[] courses = {a,b,c,d,e,f};
for(int i=0; i<courses.length; i++)
System.out.println(courses[i].getDepartment());
}
}
public int compareTo(Course o)
{
if(getDepartment().compareTo(o.getDepartment()) ==0){
if(getNumber() < o.getNumber()) return -1;
else if(getNumber() > o.getNumber()) return 1;
else return 0;
}
return getDepartment().compareTo(o.getDepartment());
}
Output:
EEE 120: Engineering
EEE 230: Engineering
MAT 150: Liberal Arts
PHY 150: Liberal Arts
PHI 304: Liberal Arts
ECN 214: W.P. Carey
If I follow your question, I believe you wanted something like this
public int compareTo(Course o)
{
int a = getDepartment().compareTo(o.getDepartment());
if(a != 0)
{
return a;
}
return Integer.valueOf(getNumber()).compareTo(o.getNumber());
}
Note: You can return when the fields you are comparing aren't 0, because those fields aren't equal.
Just use String's built-in compareTo method:
#Override
public int compareTo(Course o) {
return this.Department.compareTo(o.Department);
}