I am a student who has just started getting touched with coding. I was trying to code a cashback calculation, but I got the wrong output. The calculation is based on which category user chooses; petrol, groceries, ewallet, etc. Once I get the categories, the list will get the amount based on the categories and calculate with the bonus cash back and cash back on eligible spend. If the amount calculated is more than or equal to 15, it will return 15.
The cashback calculation code:
private void function1() {
double amountGet, cashback = 0;
for (int i = 0; i< dataList.size(); i++) {
if(dataList.get(i).getCategory() == "Petrol Spend") {
amountGet = dataList.get(i).getAmount();
cashback = amountGet * 0.08;
if(cashback > 15) {
cashback = 15.00;
}
} else if(dataList.get(i).getCategory() == "Groceries Spend") {
amountGet = dataList.get(i).getAmount();
cashback = (amountGet * 0.078) + (amountGet * 0.002);
if(cashback > 15) {
cashback = 15.00;
}
} else if(dataList.get(i).getCategory() == "eWallet Transaction") {
amountGet = dataList.get(i).getAmount();
cashback = (amountGet * 0.078) + (amountGet*0.002);
if(cashback > 15) {
cashback = 15.00;
}
} else if (dataList.get(i).getCategory() == "Other Eligible Spend") {
amountGet = dataList.get(i).getAmount();
cashback = amountGet * 0.002;
if (cashback > 15) {
cashback = 15.00;
}
}
list.add(cashback);
}
}
This button for invoking the calculation code:
calculateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
calculateCashBack();
}
});
private void calculateCashBack() {
if (totalAmount >=2000) {
function1();
} else {
function2();
}
for (int i =0; i< list.size(); i++) {
Log.d(TAG, "Item with ID :" + dataList.get(i).getId() + "with the amount of : RM" + dataList.get(i).getAmount() + "get Cashback of : RM" + list.get(i));
}
}
This is my output:
I would very much appreciate any the help from the experts...
As #GhostCat said, you should use String.equals() to compare strings. Here is an example of a more optimize, and prettier, code
// Init static values here
private Map<String, Float> cashbacks; // HashMap linking Category to dedicated cashback
static {
cashbacks = new HashMap<>();
cashbacks.put("Petrol Spend", 0.08f);
cashbacks.put("Groceries Spend", 0.08f);
cashbacks.put("eWallet Transaction", 0.08f);
cashbacks.put("Other Eligible Spend", 0.002f);
}
/**
* Compute cashbacks for a list of data
* #param dataList List of data
* #return List of corresponding cashbacks
*/
private List<Float> function1(List<Data> dataList) {
List<Float> results = new ArrayList<>();
for (Data data : dataList) {
// Find the category in the map
Float cash = cashbacks.get(data.category());
if (cash == null) {
cash = 0f; // default value here if no category found
}
// compute the total amount and limit the result to 15
results.add(Math.min(data.getAmount() * cash, 15));
}
return results;
}
How to use it? Simple:
private void calculateCashBack() {
List<Float> cashbacks;
if (totalAmount >=2000) {
cashbacks = function1(dataList);
} else {
cashbacks = function2(dataList); // I suppose that this function has the same signature
}
for (int i =0; i< cashbacks.size(); i++) {
Log.d(TAG, "Item with ID :" + dataList.get(i).getId() + " with the amount of : RM " + dataList.get(i).getAmount() + " get Cashback of : RM " + cashbacks.get(i));
}
}
Related
So, I'm trying to figure out how to get values of an array list from another class and print certain values depending on user input.
For example, firstly a user is asked to provide a location, once they enter a location, it has to read the user input and output the results according to the location.an image is provided about the output.
For some reason it doesn't output the correct values from array list.
Could you please help me out?
This is my code for reading values from array list.
public class Program {
ArrayList<Properties> property = Properties.getMelbnbProperty();
int i = 1;
for(i = 1; i < (property.size());) {
System.out.println(property.get(i));
break;
}
ArrayList<Properties> output = Properties.getMelbnbProperty();
if(Properties.getMelbnbProperty().contains(choice)) {
output.addAll(Properties.getMelbnbProperty());
}
} }
This is my code for array list.
public class Properties {
public static ArrayList<Properties> getMelbnbProperty() {
// Below is an arraylist where I have stored the Melbnb data
ArrayList<Properties> property = new ArrayList<Properties>();
property.add(new Properties("Private room in the heart of Southbank"));
property.add(new Properties("Spacious bedroom in a cosy apartment in South Yarra\n"));
property.add(new Properties("Ensuite room with great views"));
property.add(new Properties("Single room next to Carlton Gardens"));
property.add(new Properties("Studio close to Melbourne CBD"));
property.add(new Properties("1-bedroom CBD view suite near Melbourne Central and RMIT"));
property.add(new Properties("Stylish two bedroom in CBD"));
property.add(new Properties("Sky high studio with amazing views"));
property.add(new Properties("Budget accommodation bunk beds"));
property.add(new Properties("A beautiful room near Marvel Stadium"));
return property;
}}
The code you have provided in your question post is incomplete and in a way doesn't make sense to what your image displays. I do however understand what you are trying to accomplish but the way I see it your properties class is somewhat under-nourished.
I don't know if this is the intentional purpose but your for loop:
int i = 1;
for(i = 1; i < (property.size());) {
System.out.println(property.get(i));
break;
}
is designed to pull out 1 object from the property ArrayList. This loop is completely unnecessary since just supplying an index value of 1 to the ArrayList#get() method does exactly the same thing and is only a single line of code, for example:
System.out.println(property.get(1));
I say this because your for loop initializer starts at index 1, there is no iterator for the loop, and you apply the break statement directly after the display of the object within the ArrayList.
To access all elements within the ArrayList (your post indicates) you would need to do something like this:
for (int i = 0; i < properties.size(); i++) {
System.out.println(properties.get(i));
}
Or you can use:
for (String props: properties) {
System.out.println(props);
}
To be honest, what you are showing for code in grossly underdeveloped. I don't want to come across as insulting but it's obvious that you are not showing as much as you should be and therefore it is extremely difficult to provide you with any concrete solution to your problem. For this reason, I think it is just easier to provide you with a working demo console application which would allow you to perhaps grasp some concepts from.
The runnable code below consists of two specific classes, the start up class named SimpleBNBDemo which contains the main() method and the Properties class which allows you to instantiate instances of different BNB properties. As you can see, the Properties class is somewhat more fulfilled than the class you provided in your question post. Take the time to read through the code and try to follow its flow. Do keep in mind, although runnable this is only a Demo application and is in now way a complete works. I personally would never hard-code fill an ArrayList with Object data. This data should come from and or saved to a file system or database. However, for demo purposes this will suffice.
The SimpleBNBDemo class:
public class SimpleBNBDemo {
// Field variables
public final static String LS = System.lineSeparator();
public final static java.util.Scanner USER_INPUT = new java.util.Scanner(System.in);
// class member variable
private Properties prop = new Properties();
private final String line = "------------------------------------------------";
private int pwAttempts = 0;
public static void main(String[] args) {
// Started this way to avoid the need for statics
new SimpleBNBDemo().startApp(args);
}
private void startApp(String[] args) {
/* Create Properties instances...
You can do this with whatever means you like. */
java.util.List<Properties> properties = prop.getProperties();
properties.add(new Properties("Southbank Mannor", "Room", "Private room in the heart of Southbank.", "South", 86.00d, true));
properties.add(new Properties("Yarra House", "Room", "Spacious bedroom in a cosy apartment in South Yarra.", "South", 74.00d, true));
properties.add(new Properties("Ensuite Haven", "Room", "Ensuite room with great views.", "West", 65.50d, true));
properties.add(new Properties("Carlton Place", "Room", "Single room next to Carlton Gardens.", "South", 78.00d, true));
properties.add(new Properties("Melbourne Studio", "Studio", "Studio close to Melbourne CBD.", "East", 78.00d, true));
properties.add(new Properties("Melbourne Delight", "Room", "1-bedroom CBD view suite near Melbourne Central and RMIT.", "North", 135.00d, true));
properties.add(new Properties("CBD House", "Suit", "Stylish two bedroom in CBD.", "West", 100.00d, true));
properties.add(new Properties("Sky-High", "Studio", "Sky high studio with amazing views.", "North", 95.00d, true));
properties.add(new Properties("Budgeteer", "Room", "Budget accommodation bunk beds.", "South", 65.00d, true));
properties.add(new Properties("Stadium House", "Room", "A beautiful room near Marvel Stadium.", "East", 95.00d, true));
println("Welcome to MelBNB" + LS + line);
println();
// Menu 1 - Main Menu
String choice = "";
String[] locations = prop.getAllLocations();
if (locations.length == 0) {
printErr("No BNB's with Location in database yet!");
return;
}
while (choice.isEmpty()) {
println("Select from Main Menu:");
println(" 1) List all Accomodations");
println(" 2) Search by location");
println(" 3) Browse by type of accomodation");
println(" 4) Filter by rating");
println(" 5) Rate an accomodation");
println(" 6) Exit (quit)");
print("Please choose: -> ");
choice = USER_INPUT.nextLine().trim();
// Validate Entry...switch/case works great for input validation.
switch (choice) {
case "1":
listAllAccomodations();
break;
case "2":
searchByLocation();
break;
case "3":
searchByAccomodationType();
break;
case "4":
searchByRating();
break;
case "5":
rateAnAccomodation();
break;
case "6":
break;
case "~admin~":
adminMenu();
break;
case "~admin attempts reset~":
pwAttempts = 0;
println();
break;
default:
println("Invalid Entry (" + choice + ")! Try again..." + LS);
}
// Was 'Exit' (4) selected?
if (choice.equals("6")) {
// Break out of loop to end application.
println(LS + "Thank you for visiting MelBNB, Bye-Bye." + LS);
break;
}
choice = ""; // Reset 'choice' to be empty in order to loop again..
}
}
private void adminMenu() {
String pwrd = "";
while (pwrd.isEmpty()) {
if (pwAttempts >= 3) {
println(LS + "Admin Menu is NOT Available!" + LS + "To many failed "
+ "consecutive password attempts!" + LS + "Only " + pwAttempts
+ " consecutive attempts are allowed." + LS);
return;
}
print(LS + "Please enter Admin Password (c to cancel): --> ");
pwrd = USER_INPUT.nextLine().trim();
if (pwrd.equalsIgnoreCase("c")) {
println();
return;
}
int psum = 0;
for (int i = 0; i < pwrd.length(); i++) {
psum += pwrd.charAt(i);
}
if (psum != 624) {
pwAttempts++;
println("Invalid Password! Try again...");
pwrd = "";
}
}
pwAttempts = 0;
println();
println("***********************************************");
println("*** Administrative options would go here! ***");
println("*** Press Enter To Continue ***");
println("***********************************************");
String nothing = USER_INPUT.nextLine().trim();
}
private void listAllAccomodations() {
println(LS + "All Available Accomodations:");
println("----------------------------");
int cntr = 0;
String underline = "";
for (Properties pp : prop.getProperties()) {
cntr++;
String str = pp.toStringTable(pp, cntr == 1);
underline = String.join("", java.util.Collections.nCopies(str.length(), "="));
println(str);
if (cntr == 15) {
println("<- Press Enter To Continue ->");
String nuthin = USER_INPUT.nextLine().trim();
cntr = 0;
}
}
println(underline + LS);
}
private void searchByLocation() {
String[] locationTypes = prop.getAllLocations();
java.util.Arrays.sort(locationTypes);
String locationChoice = "";
while (locationChoice.isEmpty()) {
println();
println("Select the desired location:");
int i = 0;
for ( ; i < locationTypes.length; i++) {
println(" " + (i + 1) + ") " + locationTypes[i]);
}
println(" " + (i + 1) + ") Cancel");
print("Please choose: -> ");
locationChoice = USER_INPUT.nextLine().trim();
// Validate Entry...
if (!locationChoice.matches("[1-" + (locationTypes.length + 1) + "]")) {
println("Invalid Entry (" + locationChoice + ")! Try again..." + LS);
locationChoice = "";
}
}
if (locationChoice.equals(String.valueOf(locationTypes.length + 1))) {
println();
return;
}
String location = locationTypes[Integer.valueOf(locationChoice)-1];
java.util.List<Properties> p = prop.getPropertiesByLocation(location);
if (p.isEmpty()) {
println("No accomodations available in the " + location + " area!" + LS);
return;
}
String str = "Available accomodation within the " + location + " area:";
println(LS + str);
println(String.join("", java.util.Collections.nCopies(str.length(), "-")));
int cntr = 0;
for (Properties pp : p) {
cntr++;
println(pp.toStringTable(pp, cntr == 1));
}
println(line + LS);
}
private void searchByAccomodationType() {
String[] accTypes = prop.getAllAccomodationTypes();
java.util.Arrays.sort(accTypes);
String accChoice = "";
while (accChoice.isEmpty()) {
println();
println("Select the desired accomodation type:");
int i = 0;
for ( ; i < accTypes.length; i++) {
println(" " + (i + 1) + ") " + accTypes[i]);
}
println(" " + (i + 1) + ") Cancel");
print("Please choose: -> ");
accChoice = USER_INPUT.nextLine().trim();
// Validate Entry...
if (!accChoice.matches("[1-" + (accTypes.length + 1) + "]")) {
println("Invalid Entry (" + accChoice + ")! Try again..." + LS);
accChoice = "";
}
}
if (accChoice.equals(String.valueOf(accTypes.length + 1))) {
println();
return;
}
String acc = accTypes[Integer.valueOf(accChoice)-1];
java.util.List<Properties> p = prop.getPropertiesByAccomodationType(acc);
if (p.isEmpty()) {
println("No accomodation type of " + acc + " is available!" + LS);
return;
}
String str = "Available accomodation that are of type '" + acc + "':";
println(LS + str);
println(String.join("", java.util.Collections.nCopies(str.length(), "-")));
int cntr = 0;
for (Properties pp : p) {
cntr++;
println(pp.toStringTable(pp, cntr == 1));
}
println(line + LS);
}
private void searchByRating() {
String rateChoice = "";
while (rateChoice.isEmpty()) {
println();
println("Enter the desired accomodation rating (1 to 5);");
print( "Enter c to cancel. Desired Rating: --> ");
rateChoice = USER_INPUT.nextLine().trim();
if (rateChoice.equalsIgnoreCase("c")) {
return;
}
// Validate Entry...
if (!rateChoice.matches("[1-5]")) {
println("Invalid Entry (" + rateChoice + ")! Try again..." + LS);
rateChoice = "";
}
}
int rating = Integer.valueOf(rateChoice);
java.util.List<Properties> p = prop.getPropertiesByRating(rating);
if (p.isEmpty()) {
println("No accomodation available with the rating of " + rating + "!" + LS);
return;
}
String str = "Available accomodation with a rating of '" + rating + "':";
println(LS + str);
println(String.join("", java.util.Collections.nCopies(str.length(), "-")));
int cntr = 0;
for (Properties pp : p) {
cntr++;
println(pp.toStringTable(pp, cntr == 1));
}
println(line + LS);
}
private void rateAnAccomodation() {
/* Displayed ratings are always the AVERAGE of all ratings
provided for that particular propety. This is done within
the 'Properties.addRating()' method. For this reason and
for other obvious reasons the Properties List should be
saved to either a file or a database. If this is not done
then all added or modified data will be lost when the
application closes. The Properties List data should NOT
be hard-coded. It should be loaded in when the application
starts and saved to storage when data is added or modified.
*/
String[] pNames = prop.getAllPropertyNames();
String nameToRate = "";
while (nameToRate.isEmpty()) {
println(LS + "Enter the name of the accomodation you want to rate:");
print( "Enter 'c' to cancel. Rating: --> ");
nameToRate = USER_INPUT.nextLine().trim();
if (nameToRate.equalsIgnoreCase("c")) {
return;
}
// Validate Entry............................
if (nameToRate.isEmpty()) {
println("Invalid Entry! You must enter a Name! Try again...");
nameToRate = "";
continue;
}
// Does the name exist in List?
boolean found = false;
for (String name : pNames) {
if (name.equalsIgnoreCase(nameToRate)) {
// Yes it does...
found = true;
break; // Break out of this loop.
}
}
if (!found) {
println("Invalid Entry (" + nameToRate + ")!" + LS
+ "Can not find the name supplied! Try again..." + LS);
nameToRate = "";
}
}
//.................................................
/* If we get to here then the name supplied
(regarless of letter case) is in the List. */
String rateNum = "";
while (rateNum.isEmpty()) {
println();
print("Enter your rating (1 to 5 or 'c' to cancel): --> ");
rateNum = USER_INPUT.nextLine().trim();
if (rateNum.equalsIgnoreCase("c")) {
return;
}
// Validate Entry...
if (!rateNum.matches("[1-5]")) {
println("Invalid Entry (" + rateNum + ")! Try again..." + LS);
rateNum = "";
}
println();
}
// Set the rating.
int rating = Integer.valueOf(rateNum);
for (Properties p : prop.getProperties()) {
if (p.getPropertyName().equalsIgnoreCase(nameToRate)) {
int avgRating = p.getAverageRating();
p.addRating(rating);
println("Your rating of " + rating + " has been added to the accomodation" + LS
+ "named '" + nameToRate + "' which has moved its overall rating" + LS
+ "average from " + avgRating + " to an overall average rating of " +
p.getAverageRating() + "." + LS + "This is based on " +
p.getTotalNumberOfRatingsDone() + " rating(s) on the accomodation." + LS);
}
}
}
public static void println(Object... obj) {
if (obj.length > 0) {
System.out.println(obj[0]);
}
else {
System.out.println();
}
}
public static void printErr(Object... obj) {
if (obj.length > 0) {
System.err.println(obj[0]);
}
else {
System.err.println();
}
}
public static void print(Object... obj) {
if (obj.length > 0) {
System.out.print(obj[0]);
}
else {
System.out.print("");
}
}
}
The Properties class:
public class Properties {
public static java.util.List<Properties> properties = new java.util.ArrayList<>();
private String propertyName;
private String accomodationType;
private String description;
private String location;
private double pricePerDay;
private int averageRating = 0;
private int totalNumberOfRatings;
private boolean available;
// Constructor #1
public Properties() { }
// Constructor #2
public Properties(String propertyName, String accomodationType, String description,
String location, double pricePerDay, boolean available) {
this.propertyName = propertyName;
this.accomodationType = accomodationType;
this.description = description;
this.location = location;
this.pricePerDay = pricePerDay;
this.available = available;
}
// Getters & Setters
public java.util.List<Properties> getProperties() {
return properties;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public String getAccomodationType() {
return accomodationType;
}
public void setAccomodationType(String accomodationType) {
this.accomodationType = accomodationType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public double getPricePerDay() {
return pricePerDay;
}
public void setPricePerDay(double pricePerDay) {
this.pricePerDay = pricePerDay;
}
public int getAverageRating() {
return this.averageRating;
}
public void addRating(int rating) {
// Rateing is an integer value from 1 to 5.
// Where 1 is Bad and 5 Excellent.
if (rating < 1) { rating = 1; }
else if (rating > 5) { rating = 5; }
int sum = 0, r = 0;
for (Properties p : properties) {
if (p.propertyName.equalsIgnoreCase(this.propertyName)) {
r++;
sum += rating;
}
}
if (sum > 0 && r > 0) {
this.averageRating = sum / r;
}
else {
this.averageRating = rating;
}
this.totalNumberOfRatings++;
}
public boolean isAvailable() {
return available;
}
public void setAvailable(boolean available) {
this.available = available;
}
#Override
public String toString() {
return propertyName + ", " + accomodationType + ", " + description + ", "
+ location + ", " + pricePerDay + ", " + averageRating + ", "
+ available;
}
public String toStringTable(Properties p, boolean... addHeader) {
boolean applyHeader = false;
if (addHeader.length > 0) {
applyHeader = addHeader[0];
}
String symbol = java.util.Currency.getInstance(java.util.Locale.getDefault()).getSymbol();
String header = "", underline = "", ls = System.lineSeparator();
StringBuilder sb = new StringBuilder("");
header = String.format("%-18s %-10s %-50s %-10s %-10s %-8s %-6s%n", "BNB Name",
"BNB Type", "BNB Description", "Location", "Price/Day", "Rating", "Avail.");
underline = String.join("", java.util.Collections.nCopies(header.length(), "=")) + ls;
if (applyHeader) {
sb.append(header).append(underline);
}
String[] desc = p.description.split("\\s+");
java.util.List<String> descTmp = new java.util.ArrayList<>();
StringBuilder sb2 = new StringBuilder("");
for (String str : desc) {
if ((sb2.toString() + " " + str).length() > 50) {
descTmp.add(sb2.toString());
sb2.setLength(0);
}
if (!sb2.toString().isEmpty()) {
sb2.append(" ");
}
sb2.append(str);
}
if (!sb2.toString().isEmpty()) {
descTmp.add(sb2.toString());
}
sb.append(String.format("%-18s %-10s %-50s %-12s " + symbol + "%-10.2f %-7s %-6s",
p.propertyName, p.accomodationType, descTmp.get(0), p.location,
p.pricePerDay, p.averageRating, (p.available ? "Yes" : "No")));
if (descTmp.size() > 1) {
for (int i = 1; i < descTmp.size(); i++) {
sb.append(ls).append(String.format("%-18s %-10s %-50s %-12s %-10s %-7s %-6s",
" "," ", descTmp.get(i), " ", " ", " ", " "));
}
}
return sb.toString();
}
public String[] getAllPropertyNames() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure names retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.propertyName)) {
tmp.add(prop.propertyName);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public String[] getAllAccomodationTypes() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure accomodations retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.accomodationType)) {
tmp.add(prop.accomodationType);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public java.util.List<Properties> getPropertiesByLocation(String location) {
java.util.List<Properties> tmp = new java.util.ArrayList<>();
for (Properties p : Properties.properties) {
if (p.location.equalsIgnoreCase(location) && !tmp.contains(p)) {
tmp.add(p);
}
}
return tmp;
}
public java.util.List<Properties> getPropertiesByAccomodationType(String accomodationType) {
java.util.List<Properties> tmp = new java.util.ArrayList<>();
for (Properties p : Properties.properties) {
if (p.accomodationType.equalsIgnoreCase(accomodationType) && !tmp.contains(p)) {
tmp.add(p);
}
}
return tmp;
}
public java.util.List<Properties> getPropertiesByRating(int rating) {
java.util.List<Properties> tmp = new java.util.ArrayList<>();
for (Properties p : Properties.properties) {
if (p.averageRating == rating && !tmp.contains(p)) {
tmp.add(p);
}
}
return tmp;
}
public int getTotalNumberOfRatingsDone() {
return this.totalNumberOfRatings;
}
public String[] getAllDescriptions() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure descriptions retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.description)) {
tmp.add(prop.description);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public String[] getAllLocations() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure locations retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.location)) {
tmp.add(prop.location);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public double[] getAllPerDayPrices() {
java.util.List<Double> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure locations retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.pricePerDay)) {
tmp.add(prop.pricePerDay);
}
}
// Convert List<Double> to double[]...
double[] prices = new double[tmp.size()];
for (int i = 0; i < tmp.size(); i++) {
prices[i] = tmp.get(i);
}
return prices;
}
}
Assuming that the array is populated with 20 shipments, calculate the total cost of local shipments in the array.
I tried to create a for loop and then call out the method calcCost() and += it to the variable local so it would save the values I guess
I'm pretty sure the way I wrote the code is wrong so if someone could help me with it that would be great!
package question;
public class TestShipment {
public static void main(String[] args) {
Shipment r1 = new Shipment(
new Parcel("scientific calculator " , 250),
new Address("Dubai","05512345678"),
new Address("Dubai","0505432123"),
"Salim"
);
System.out.println(r1);
Shipment[] arr = new Shipment[100];
arr[5] = r1;
Shipment[] a = new Shipment[20];
double local = 0;
for (int i = 0; i < a.length; i++) {
if (a[i].isLocalShipment()) {
System.out.println(a[i].calcCost());
}
}
}
}
public class Shipment {
public Parcel item;
private Address fromAddress;
private Address toAddress;
public String senderName;
public Shipment(Parcel i, Address f, Address t, String name) {
item = i;
fromAddress = f;
toAddress = t;
senderName = name;
}
//setter
public void setFromAddress(String c, String p) {
c = fromAddress.getCity();
p = fromAddress.getPhone();
}
public boolean isLocalShipment() {
boolean v = false;
if (fromAddress.getCity() == toAddress.getCity()) {
v = true;
} else {
v = false;
}
return v;
}
public double calcCost() {
double cost = 0;
if (fromAddress.getCity() == toAddress.getCity()) {
cost = 5;
} else {
cost = 15;
}
if(item.weight > 0 && item.weight <= 200) {
cost += 5.5;
}
if(item.weight > 200) {
cost += 10.5;
}
return cost = cost * (1 + 0.5); //fix the tax
}
public String toString() {
return "From: " + senderName + "\nTo: " + toAddress
+ "\nParcel: " + item.desc+item.weight + "\ncost: " + calcCost();
}
}
I am trying to set up my Java code to parse whether an element of my array attended either Disneyland or Universal studios. My array has 7 elements for 7 attendees. The attendees receive discounts specific to which park they attended, and I have created two for loops to represent the two parks.
How can I set up my code in the main method to determine which attendees went where?
public class Visitor
{
public static void main( String args[] )
{
double totalAttendeeCost = 0.0;
//Using 1 array
VisitorPackage[] attendee = new VisitorPackage[7];
attendee[0] = new VisitorPackage("Mickey", 'S', "weekday",
"Disneyland", 75.0);
attendee[1] = new VisitorPackage("Donald", 'C', "weekday",
"Disneyland", 75.0);
attendee[2] = new VisitorPackage("Minnie", 'E', "weekend",
"Disneyland", 75.0);
attendee[3] = new VisitorPackage("Goofie", 'E', "weekend",
"Disneyland", 75.0);
attendee[4] = new VisitorPackage("Harry", 'C', "weekend", "Universal
Studios", 60.0);
attendee[5] = new VisitorPackage("Hermoine", 'S', "weekend",
"Universal Studios", 60.0);
attendee[6] = new VisitorPackage("Ron", 'E', "weekday", "Universal
Studios", 60.0);
//This is where I am looking for help
//if attendee == disneyland
for(int i=0; i < attendee.length; i++)
{
{
attendee[i].applyDiscount(attendee[i], 5.0, 10.0);
attendee[i].applyWeekdayRate(attendee[i], 15.0);
attendee[i].printInfo(attendee[i]);
totalAttendeeCost += attendee[i].getTotalCost();
}
}
//else if attendee == universal
for(int i=0; i < attendee.length; i++)
{
attendee[i].applyDiscount(attendee[i], 10.0, 15.0);
attendee[i].applyWeekdayRate(attendee[i], 20.0);
attendee[i].printInfo(attendee[i]);
totalAttendeeCost += attendee[i].getTotalCost();
}
//System.out.println("Total: $" + totalCostDisney + "\n");
System.out.println("--------------");
System.out.printf("Total: $%.2f\n", totalAttendeeCost);
}
}
Here is the other class containing the methods:
public class VisitorPackage
{
private String visitorName;
private char visitorType;
private String visitDay;
private String destination;
private double totalCost;
public VisitorPackage()
{
visitorName ="N/A";
visitorType = '-';
visitDay = "-";
destination = "N/A";
totalCost = 0.0;
}
public VisitorPackage(String newVisitorName, char newVisitorType,
String newVisitDay, String newDestination, double newTotalCost)
{
visitorName = newVisitorName;
visitorType = newVisitorType;
visitDay = newVisitDay;
totalCost = newTotalCost;
destination = newDestination;
}
public String getDestinationPark(VisitorPackage arrayInstance)
{
if (arrayInstance.destination.equalsIgnoreCase("disneyland"))
return destination;
else
return destination;
}
public double getTotalCost()
{
return totalCost;
}
public void applyDiscount(VisitorPackage arrayInstance, double
childRate, double seniorRate)
{
if (arrayInstance.visitorType == 'C')
totalCost -= ((totalCost * childRate) / 100);
else if (arrayInstance.visitorType == 'S')
totalCost -= ((totalCost * seniorRate) / 100);
}
public void applyWeekdayRate(VisitorPackage arrayInstance, double
weekdayDiscount)
{
if (arrayInstance.visitDay.equalsIgnoreCase("weekday"))
totalCost -= weekdayDiscount;
}
public void printInfo(VisitorPackage arrayInstance)
{
System.out.print(arrayInstance.visitorName + " - ");
System.out.print(arrayInstance.destination + " - ");
System.out.print("$");
System.out.printf("%.2f", arrayInstance.totalCost);
if (arrayInstance.visitorType == 'E')
System.out.print(" ***** Discount cannot be applied to " +
arrayInstance.visitorName);
System.out.println();
}
}
Keep in mind, each element of your attendee array is a specific instance of VisitorPackage. So, utilize your Getter methods within the VisitorPackage Class, but first get rid of the parameter for that method and simplify it like this:
public String getDestinationPark() {
return this.destination;
}
Do the same for all your other methods within the VisitorPackage Class, get rid of the VisitorPackage arrayInstance parameter and any relation to it within your class methods, like this:
public void applyDiscount(double childRate, double seniorRate) {
if (visitorType == 'C') {
totalCost -= ((totalCost * childRate) / 100);
}
else if (visitorType == 'S')
totalCost -= ((totalCost * seniorRate) / 100);
}
public void applyWeekdayRate(double weekdayDiscount) {
if (visitDay.equalsIgnoreCase("weekday")) {
totalCost -= weekdayDiscount;
}
}
public void printInfo() {
System.out.print(visitorName + " - ");
System.out.print(destination + " - ");
System.out.print("$");
System.out.printf("%.2f", totalCost);
if (visitorType == 'E') {
System.out.print(" ***** Discount cannot be applied to " + visitorName);
}
System.out.println();
}
Because each element of the attendee array is an instance of the VisitorPackage Class you don't need to send that instance to your class methods. It already knows which instance you are referring to (Mickey, Donald, Ron, etc) when you supply the Index number. Since Minnie is at index 2 of the attendee array any calls to the VisitorPackage class like attendee[2].applyWeekdayRate(15.0) will only ever apply to Minnie.
Now, when you want to process the attendee's Array:
// iterate through each attendee and
// apply necessary discounts, etc.
for (int i = 0; i < attendee.length; i++) {
// Disneyland
if (attendee[i].getDestinationPark().equalsIgnoreCase("disneyland")) {
attendee[i].applyDiscount(5.0, 10.0);
attendee[i].applyWeekdayRate(15.0);
attendee[i].printInfo();
totalAttendeeCost += attendee[i].getTotalCost();
}
// Universal Studios
else if (attendee[i].getDestinationPark().equalsIgnoreCase("universal studios")) {
attendee[i].applyDiscount(10.0, 15.0);
attendee[i].applyWeekdayRate(20.0);
attendee[i].printInfo();
totalAttendeeCost += attendee[i].getTotalCost();
}
}
Or you could do it like this:
for (int i = 0; i < attendee.length; i++) {
String dest = attendee[i].getDestinationPark();
if (dest.equalsIgnoreCase("disneyland")) {
attendee[i].applyDiscount(5.0, 10.0);
attendee[i].applyWeekdayRate(15.0);
attendee[i].printInfo();
totalAttendeeCost += attendee[i].getTotalCost();
}
else if (dest.equalsIgnoreCase("universal studios")) {
attendee[i].applyDiscount(10.0, 15.0);
attendee[i].applyWeekdayRate(20.0);
attendee[i].printInfo();
totalAttendeeCost += attendee[i].getTotalCost();
}
}
Or you could do it like this:
for (int i = 0; i < attendee.length; i++) {
String dest = attendee[i].getDestinationPark();
switch (dest.toLowerCase()) {
case "disneyland":
attendee[i].applyDiscount(5.0, 10.0);
attendee[i].applyWeekdayRate(15.0);
attendee[i].printInfo();
totalAttendeeCost += attendee[i].getTotalCost();
break;
case "universal studios": // if the string has a space
case "universalstudios": // OR if the string has no space
attendee[i].applyDiscount(10.0, 15.0);
attendee[i].applyWeekdayRate(20.0);
attendee[i].printInfo();
totalAttendeeCost += attendee[i].getTotalCost();
break;
}
}
In addition to the code issues pointed out by DevilsHnd, I wanted to steer you in a different direction.
Using streams to get the reporting you were looking for, and
Instead of using strings to represent things like Destination, Visitor Type and Visit Day, using enums to represent these concepts can clean up your code quite a bit and make it very clear how the discounting scheme works.
I've refactored your code accordingly
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingDouble;
public class Visitor {
public enum VisitorType {
Child, Senior, Other
}
public enum VisitType {
Weekday,Weekend
}
// represents each Destination as well as all related discount rates.
public enum Destination {
Disneyland {
{
visitorDiscount.put(VisitorType.Child, 5.0);
visitorDiscount.put(VisitorType.Senior, 10.0);
visitTypeDiscount.put(VisitType.Weekday, 15.0);
}
}
, UniversalStudios {
{
visitorDiscount.put(VisitorType.Child, 10.0);
visitorDiscount.put(VisitorType.Senior, 15.0);
visitTypeDiscount.put(VisitType.Weekday, 20.0);
}
};
protected Map<VisitorType,Double> visitorDiscount= new HashMap();
protected Map<VisitType,Double> visitTypeDiscount= new HashMap();
public double getVisitorTypeDiscount(VisitorType visitorType) {
Double discount = visitorDiscount.get(visitorType);
return discount == null ? 0.0 : discount;
}
public double getVisitTypeDiscount(VisitType visitType) {
Double discount = visitTypeDiscount.get(visitType);
return discount == null ? 0.0 : discount;
}
};
public static class VisitorPackage {
private final String visitorName;
private final VisitorType visitorType;
private final VisitType visitDay;
private final Destination destination;
private final double totalCost;
public VisitorPackage(String newVisitorName, VisitorType newVisitorType,
VisitType newVisitDay, Destination newDestination, double newTotalCost) {
visitorName = newVisitorName;
visitorType = newVisitorType;
visitDay = newVisitDay;
totalCost = newTotalCost;
destination = newDestination;
}
public String getDestinationPark() {
return destination.toString();
}
public double getTotalCost() {
return totalCost;
}
public double getDiscountedCost() {
double visitorTypeDiscount = totalCost * destination.getVisitorTypeDiscount(visitorType)/100;
return totalCost - visitorTypeDiscount - destination.getVisitTypeDiscount(visitDay);
}
public Destination getDestination() { return destination; }
public void printInfo() {
System.out.print(visitorName + " - ");
System.out.print(destination + " - ");
System.out.printf("$%.2f -> ", getTotalCost());
System.out.print("$");
System.out.printf("%.2f", getDiscountedCost());
if (visitorType == VisitorType.Other) {
System.out.print(" ***** Discount cannot be applied to "
+ visitorName);
}
System.out.println();
}
}
public static void main(String args[]) {
double totalAttendeeCost = 0.0;
//Using 1 array
VisitorPackage[] attendee = new VisitorPackage[7];
attendee[0] = new VisitorPackage("Mickey", VisitorType.Senior, VisitType.Weekday,
Destination.Disneyland, 75.0);
attendee[1] = new VisitorPackage("Donald", VisitorType.Child, VisitType.Weekday,
Destination.Disneyland, 75.0);
attendee[2] = new VisitorPackage("Minnie", VisitorType.Other, VisitType.Weekend,
Destination.Disneyland, 75.0);
attendee[3] = new VisitorPackage("Goofie", VisitorType.Other, VisitType.Weekend,
Destination.Disneyland, 75.0);
attendee[4] = new VisitorPackage("Harry", VisitorType.Child, VisitType.Weekend, Destination.UniversalStudios, 60.0);
attendee[5] = new VisitorPackage("Hermoine", VisitorType.Senior, VisitType.Weekend,
Destination.UniversalStudios, 60.0);
attendee[6] = new VisitorPackage("Ron", VisitorType.Other, VisitType.Weekday, Destination.UniversalStudios, 60.0);
// Print a report grouped by Destination showing all VisitoerPackages and their discounted costs with subtotals
Arrays.stream(attendee)
.collect(groupingBy(VisitorPackage::getDestination))
.entrySet().stream()
.forEach(e->{
System.out.println("Summary for "+e.getKey());
e.getValue().stream().forEach(VisitorPackage::printInfo);
Double total = e.getValue().stream().collect(summingDouble(VisitorPackage::getDiscountedCost));
System.out.printf("Total Discounted Cost for %s = $%.2f\n",e.getKey(),total);
System.out.println("------------------------------------------------------------");
});
// Here's a way to reduce the dataset to map of sub-totals keyed by destination.
Map<Destination,Double> discountedCostByDest = Arrays.stream(attendee)
.collect(groupingBy(
VisitorPackage::getDestination,
summingDouble(VisitorPackage::getDiscountedCost)));
System.out.println(discountedCostByDest);
// compute and display the total cost.
Double totalDiscountedCost = Arrays.stream(attendee)
.collect(summingDouble(VisitorPackage::getDiscountedCost));
System.out.printf("Grand Total = $%.2f\n", totalDiscountedCost);
}
}
This code produces the following output:
Summary for UniversalStudios
Harry - UniversalStudios - $60.00 -> $54.00
Hermoine - UniversalStudios - $60.00 -> $51.00
Ron - UniversalStudios - $60.00 -> $40.00 ***** Discount cannot be applied to Ron
Total Discounted Cost for UniversalStudios = $145.00
------------------------------------------------------------
Summary for Disneyland
Mickey - Disneyland - $75.00 -> $52.50
Donald - Disneyland - $75.00 -> $56.25
Minnie - Disneyland - $75.00 -> $75.00 ***** Discount cannot be applied to Minnie
Goofie - Disneyland - $75.00 -> $75.00 ***** Discount cannot be applied to Goofie
Total Discounted Cost for Disneyland = $258.75
------------------------------------------------------------
{UniversalStudios=145.0, Disneyland=258.75}
Grand Total = $403.75
Here is the full code for it:
public void trackAll() {
int north = count(Direction.North) * 25;
int east = count(Direction.East) * 25;
int south = count(Direction.South) * 25;
int west = count(Direction.West) * 25;
if ((north == 0) && (east == 0) && (south == 0) && (west == 0)) {
this.player.sendMessage(ChatColor.RED + "Not a valid tracking compass.");
return;
}
for (Direction direction : Direction.values()) {
int length = count(direction) * 25;
if (length != 0) {
#SuppressWarnings("rawtypes")
Set players = new TreeSet();
for (Player player : Bukkit.getOnlinePlayers()) {
if (this.player.canSee(player)) if ((on(player, direction) & !player.equals(this.player))) {
players.add(player.getDisplayName());
}
}
FancyMessage message = new FancyMessage(direction + " (" + length + "): ").color(ChatColor.DARK_AQUA);
int i = 0;
for (String str : players) {
if (i == players.size() - 1)
message.then(str).color(ChatColor.GRAY).tooltip(ChatColor.GREEN + "Click here to track " + ChatColor.RESET + str + ChatColor.GREEN + ".").command("/track " + ChatColor.stripColor(str));
else {
message.then(str).color(ChatColor.GRAY).tooltip(ChatColor.GREEN + "Click here to track " + ChatColor.RESET + str + ChatColor.GREEN + ".").command("/track " + ChatColor.stripColor(str)).then(", ");
}
i++;
}
message.send(this.player);
}
}
}
And I also have another issue "Type mismatch: cannot convert from element type Object to Block"
public int count(Direction direction, boolean b) {
int length = 0;
#SuppressWarnings("rawtypes")
Set toDelete = new HashSet();
for (int i = 1; i < 10000; i++) {
Block next = this.middle.getRelative(BlockFace.valueOf(direction.toString().toUpperCase()), i);
if (next.getType() == Material.COBBLESTONE) {
length++;
toDelete.add(next); } else {
if (next.getType() == Material.STONE) {
length++;
toDelete.add(next);
toDelete.add(this.middle);
break;
}
length = 0;
toDelete.clear();
break;
}
}
if (b) {
for (Block block : toDelete) {
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
block.setType(Material.AIR);
}
}
return length;
}
I currently don't have someone that can look over the code I personally do not see the issue but I've been working on it for hours so yeah ;/ Thanks. This code is to do with a Minecraft plugin it's tracking a players location and sending the information to the player that executed the command.
Use
Set<String> players = new TreeSet<>();
and
Set<Block> toDelete = new HashSet<>();
I've got some input files from my teacher wich we are supposed to test the program with. The task is to read from file, create a directed graph and print out the output. But if there is a cycle we are supposed to terminate the program.
I've got some files named house1 and house2. in the file house1 there isn't any cycles, but in house2 there is. But I can't figure out why my program can't find that cycle.
Here I have all the code, and any help saying where I should be looking at is preciated :)
import java.util.*;
import java.io.*;
import java.lang.*;
class Input {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("enter a filename!");
System.exit(1);
} else if (args.length == 1) {
String fil = args[0]+".txt";
LesFraFil(fil);
// skrivUt();
topSort();
} else {
System.out.println("too many parameters, try again...");
}
}
static int antTask;
static Task[] ids;
static int tTid;
static void LesFraFil(String fil) {
int i = 0;
int j;
try {
String lest;
Scanner in = new Scanner(new FileReader(fil));
Edge til;
int counter = 0;
antTask = in.nextInt();
ids = new Task[antTask];
System.out.println(antTask);
while (in.hasNextLine()) {
lest = in.nextLine();
// hvis tom linje, så hopper den over
if(lest.trim().length() == 0) continue;
String split[] = lest.split("\\s+");
int id = Integer.parseInt(split[0]);
String act = split[1];
int tid = Integer.parseInt(split[2]);
int staff = Integer.parseInt(split[3]);
int depA = Integer.parseInt(split[4]);
tTid += tid;
ids[i] = new Task(id, act, tid, staff);
j = 4;
/*
* Lesingen av inputen skal avbrytes når den leser 0.
* j er den som holder på hvor langt vi er i split arrayet
* når den møter på 0
*/
while(split[j].compareTo("0") != 0) {
int tmp = Integer.parseInt(split[j])-1;
// System.out.println(tmp+1 + " Aktivitetens navn : " + act); //+ " tiden aktiviteten tar tid: " + tid + " avhengihet: " + split[j]);
j++;
if (ids[tmp] == null) {
ids[tmp] = new Task(id, act, tid, staff);
ids[tmp].visited = true;
}
ids[i].cntPredecessors++;
if(ids[tmp].outEdge == null) {
ids[tmp].outEdge = new Edge(ids[tmp], ids[i]);
} else {
til = ids[tmp].outEdge;
while(til.neste != null) {
til = til.neste;
}
// til.neste = new Edge(ids[tmp], ids[i]);
}
}
counter++;
i++;
}
if (antTask == counter) {
System.out.println("Lesinga gikk som planlagt av fil: " + fil);
System.out.println("Total arbeidstid: " + tTid);// + antTask + " == " + counter );
} else {
System.out.println("Noe gikk galt avslutter!");
System.out.println(antTask + " || " + counter);
System.exit(2);
}
in.close();
} catch (Exception e) {
System.err.println("Dette gikk galt med lesinga: " + e.getMessage());
}
}
static void topSort() {
LinkedList<Task> list = new LinkedList<Task>();
ArrayList<Task> array = new ArrayList<Task>();
Task temp;
int totalTime = 0;
int counter = 0;
for(Task t : ids) {
if (t.cntPredecessors == 0) {
list.add(t);
}
}
while (!list.isEmpty()) {
temp = list.pop();
counter++;
array.add(temp);
System.out.println("Time " + totalTime + "\t Started task " + temp.id + "\t Staff: " + temp.staff + ", Task done " + temp.id);
totalTime += temp.time;
for (Task t : ids) {
if (--t.cntPredecessors == 0)
list.add(t);
}
}
if(counter < antTask) { // checking for loop
System.out.println(counter + " != " + antTask);
System.out.println("En løkke er funnet i grafen. Avslutter...");
System.exit(0);
}
System.out.println("Topological sort: " + Arrays.toString(array.toArray()));// den sorterte "arraylisten"
System.out.println("Total tid brukt er: " + totalTime);
}
}
class Task {
int id, time, staff;
int depA, depB;
String name;
int eStart, lStart;
Edge outEdge;
int cntPredecessors;
boolean visited;
Task(int id, String name, int time, int staff) {
this.id = id;
this.name = name;
this.time = time;
this.staff = staff;
visited = false;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}
class Edge {
Task fra, til;
Task id, name, time, staff;
Edge neste;
// Task fra, til;
Edge(Task fra, Task til) { //, Task fra, Task til) {//, Task name, Task time, Task staff) {
this.fra = fra;
this.til = til;
// this.id = id;
// this.fra = fra;
// this.til = til;
/* this.name = name;
this.time = time;
this.staff = staff;*/
}
public Task getTil() {
return til;
}
}
I'll write here some kind of simple algorithm, what you are doing is a topological sort
Important thing is that topological sort is using DFS algorithm O(V+E)
What you should do is to create some kind of additional attribute for each Node (let's call it String color and set it's initial value to white.
As you'll iterate through your nodes, set it's color to gray, and continue doing a DFS, after it's done, set it's color to black.
The point is - if you visit a node with color == gray or color == black you found a cycle
I recommend reading a Topological sort chapter from Introduction to Algorithms
And let's see your code!
You read something from input file and important part is here:
while (!list.isEmpty()) {
temp = list.pop();
counter++;
array.add(temp);
System.out.println("Time " + totalTime + "\t Started task " + temp.id + "\t Staff: " + temp.staff + ", Task done " + temp.id);
totalTime += temp.time;
for (Task t : ids) {
if (--t.cntPredecessors == 0) {
list.add(t);
}
}
}
well sorry for saying it like this, but your code is little messy, without english documentation, etc. but I think you are missing the part of coloring your nodes, that can be the reason why you can't find a cycle ( and I suppose you never end ) , because you miss to "color" your nodes, so nobody knows that you have already visited them
btw my "color" attribute is called visited in your code (you can use boolean but then you can't color it to gray/black/white as in the book I posted here)
I guess you set it to true during initialization (you should set it to false and set it to true if you have already processed/visited the node)
// Sorry if I'm wrong but it's 1A.M. here, I just think this might be the issue
// + if you do this on directed graph, and exit if you detect cycle, you get and cycle detection algorithm in O(V) time :)