Cost Calculator - java

My code needs to calculate the cost of ISP service via 3 different questions.
choice of package (1,2,3)
Which month it is: (1-12)
How many hours used:(x)
I broke the months into 3 separate arrays. One for Feb. with 28 days, one for months with 30 days and one with months that have 31 days. I need to check the number of hours entered and make sure that it does not exceed the amount of hours that are in whichever month they have chosen. I have started to with this:
import java.util.Scanner; //Needed for the scanner class
public class ISP_Cost_Calc
{
public static void main(String[] args)
{
String input; //To hold users input.
char selectPackage; //To hold Internet Package
double hourUsage, totalCharges, addCharges; //Variables
Scanner keyboard = new Scanner(System.in); //Create a Scanner object to collect keyboard input.
int[] twentyeightArray; //List of months with 28 days (that's what the te is for)
twentyeightArray = new int[1]; //Make room for one integer in list
twentyeightArray[0] = 2; //Set the one integer in this list to month number 2
int[] thirtyArray; //List of months with 30 days.
thirtyArray = new int[4];
thirtyArray[0] = 4;
thirtyArray[1] = 6;
thirtyArray[2] = 9;
thirtyArray[3] = 11;
int[] thiryoneArray; //List of months with 31 days.
thiryoneArray = new int[7];
thiryoneArray[0] = 1;
thiryoneArray[1] = 3;
thiryoneArray[2] = 5;
thiryoneArray[3] = 7;
thiryoneArray[4] = 8;
thiryoneArray[5] = 10;
thiryoneArray[6] = 12;
//Prompt the user to select a Internet Package.
System.out.print("Enter your plan (1, 2, 3):");
input = keyboard.nextLine();
selectPackage = input.charAt(0);
//Prompt the user for the month.
System.out.print("Enter your month number (1-12):");
input = keyboard.nextLine();
char monthNum = input.charAt(0);
//Prompt the user for how many hours used.
System.out.print("Enter your hours:");
input = keyboard.nextLine();
hourUsage = Double.parseDouble(input);
//Display pricing for selected package...
switch (selectPackage)
{
case '1':
if (hourUsage > 10)
{
addCharges = hourUsage - 10;
totalCharges = (addCharges * 2.0) + 9.95;
System.out.println("You have used " + hourUsage + " hours and your total is $" + totalCharges + " per month. ");
}
else
{
System.out.println("Your total is $9.95 per month.");
}
break;
case '2':
if (hourUsage > 20 )
{
addCharges = hourUsage - 20;
totalCharges = (addCharges * 1.0) + 13.95;
System.out.println("You have used " + hourUsage + " and your total is $" + totalCharges + " per month.");
}
else
{
System.out.println("Your total is $13.95 per month.");
}
break;
case '3':
System.out.println("Your total is $19.95 per month.");
break;
default:
System.out.println("Invalid Choice.");
}
}
}
So I just need advice with how to incorporate this into my if statements.
Thank you

Instead of using separate arrays to implement your month. You can do this:
int[] month = {31,28,31,30,31,30,31,31,30,31,30,31};
int[] monthLeapYear = {31,29,31,30,31,30,31,31,30,31,30,31};
You can check whether a given year is a leap year first, then choose the right array to use for the month. This way you only need 2 arrays - ever.
and you may have something like this to help you. I also advise you to create some methods in your implementation to modularize your program.
public static Boolean isLeapYear(int year)
{
if(year % 4 == 0 && year % 100 != 0)
return true;
return false;
}
The array is by index 0 - 11. That be can be over come by doing this:
//Let say your current month is 1-12
month[currentMonth-1]
Alternatively add 1 element to your array (so that the elements tally now):
int[] month = {0,31,28,31,30,31,30,31,31,30,31,30,31};

It may be easier if instead of using seperatre arrays for different numbers of days, you use an enum of Months which contains the number of days and the number of hours.
public enum Month {
JANUARY(31),FEBRUARY(28),MARCH(31),APRIL(30),MAY(31),JUNE(30),JULY(31),AUGUST(30),SEPTEMBER(30),OCTOBER(31),
NOVEMBER(30),DECEMBER(31);
private int hours;
private Month(int days){
hours = days*24;
}
public int getHours(){
return hours;
}
}
Using something like that would cut down on the unnecessary array use and combine everything into a single class. This would make it a lot easier to get the number of days and hours in each month.

Instead of creating multiple arrays, just use one array like:
month[0] = 31;
month[1] = 28;//what if leap year?
month[2] = 31;
//and so on
Then you could do something like:
int monthNumber = monthNum - 48;
if (hours > month[monthNumber - 1] * 24) {
//do something
} else {
//else do another thing
}

This is insane.
What is going to happen in 2016 when February will have 29 days instead of 28 days?
Stop using integers to represent hours. Use proper data types like DateTime and TimeSpan.
Get the DateTime at 00:00 of the 1st day of the selected month,
then get the DateTime at 00:00 of the 1st day of the next month,
then calculate the difference of these two to obtain a TimeSpan holding the duration of the selected month.
Then convert your hours to a TimeSpan and compare this against the duration of the selected month.
This will tell you whether the entered number of hours fits within the selected month.

To check conditions based on your months.You can use contains method of arraylist by converting array into arraylist as
Arrays.asList(your1stArray).contains(yourChar)
in your char just add the input no of the month
for eg:
switch (monthNum )
{
case '1':
if (Arrays.asList(your1stArray).contains(yourChar)){
//code goes here
}
case '1':
if (Arrays.asList(your2ndArray).contains(yourChar)){
//code goes here
}
)
)

Related

For loop to iterate through user input to calculate cost?

I'm working in Java. So what I'm trying to do is, take the user input from subscriberPackage
public static String subscriberPackage() { //Method to get the customers name
Scanner sc = new Scanner(System.in);
System.out.println("\nPlease choose a package the customer would like:");
System.out.println("Enter Bronze, Silver or Gold to select a package.");
String subscriptionPackage = sc.nextLine(); //Get subscription package from the user
while (!(subscriptionPackage.equalsIgnoreCase("Bronze") || subscriptionPackage.equalsIgnoreCase("Silver") || subscriptionPackage.equalsIgnoreCase("Gold"))) {
System.err.println("This is not a valid package!");
System.err.println("Please try again!");
System.out.println("Please choose a package the customer would like:");
System.out.println("Bronze, Silver or Gold.");
subscriptionPackage = sc.nextLine();
//If the package entered is not Bronze, Silver or Gold, the user is asked to re-enter till the while condition is met
}
return subscriptionPackage; //Returns the subscription package to the newSubscription method
}
and subscriberDuration
public static int subscriberDuration() { //Method to get the subscription duration
Scanner sc = new Scanner(System.in);
System.out.println("\nPlease choose the subscription duration");
System.out.println("It must be either 1, 3, 6 or 12 months.");
System.out.println("Please now enter the subscription duration the customer would like");
int subscriptionDuration = sc.nextInt(); //Get the subscription duration from the user
while (subscriptionDuration != 1 && subscriptionDuration != 3 && subscriptionDuration != 6 && subscriptionDuration != 12) {
System.err.println("This is not a valid duration, please try again!");
System.err.println("It must be either 1, 3, 6 or 12 months.");
subscriptionDuration = sc.nextInt();
//If the duration entered is not 1, 3, 6 or 12, the user is asked to re-enter till the while condition is met
}
return subscriptionDuration; //Returns the subscription duration to the newSubscription method
}
and calculate a cost in subscriberBill.
private static int subscriberBill(String subscriptionPackage, int subscriptionDuration) {
int subscriptionCost = 0;
int[] subsBronzePackageCosts = new int[1000];
subsBronzePackageCosts[0] = 600;
subsBronzePackageCosts[1] = 500;
subsBronzePackageCosts[2] = 400;
subsBronzePackageCosts[3] = 300;
int count = 0;
for(int i = 1; i <= 12; i+=3){
if (subscriptionPackage.equals(subscriptionPackage) && (subscriptionDuration == subscriptionDuration)) {
subscriptionCost = (subsBronzePackageCosts[i] + i + count);
count++;
System.out.println("\nThe cost of this subscription is: " + subscriptionCost);
return subscriptionCost;
}
}
return subscriptionCost;
}
}
I have managed to pass through this information and started adding the costs of the Bronze tier subscriptionPackage. I have done this using an array:
int[] subsBronzePackageCosts = new int[1000];
subsBronzePackageCosts[0] = 600;
subsBronzePackageCosts[1] = 500;
subsBronzePackageCosts[2] = 400;
subsBronzePackageCosts[3] = 300;
I'm trying to loop through said array so that for example, a user has set the duration as 3, it'll iterate using the for loop through my array and set subscriptionCost to the appropriate value. In this instance, that being 400.
The part I'm stuck with, is iterating through the array with the for loop. I have it so it's only adding + 1 and reporting 500 every time. I did have a solution working for if else statements for each different package type and duration, but obviously, this isn't ideal practice and causes repetitive code, which I'm trying to avoid.
Thanks in advance!
EDIT: To add a bit more context. I have three tiers of subscriptionPackage to work with: Bronze, Silver and Gold.
All of these packages have different pricings and the pricings change with the length of subscriptionDuration that the user enters.
The packages/pricings are:
Bronze prices are 600 for 1 month, 500 for 3 months, 400 for 6 months and 300 for 12 months.
Silver prices are 800 for 1 month, 700 for 3 months, 600 for 6 months and 500 for 12 months.
Gold prices are 999 for 1 month, 899 for 3 months, 799 for 6 months and 699 for 12 months.
Your code here is a bit of a mess to look at. But I guess I would point you to the logic in your if statement ...
subscriptionPackage.equals(subscriptionPackage) ... this is always true, right? So you can just delete this.
subscriptionDuraction == suscriptionDuration ... thius is also always true, right? So your whole if statement disappears.
So this if statement ALWAYS evaluates to true, which means you will always hit the return statement in the if block, with i=1, and in your array, [1] = 500.
I would suggest attempting to work with classes, for example:
// Going this far could be up for debate
public enum SubscriptionType { GOLD, SILVER, BRONZE }
public enum SubscriptionDuration { MONTHLY, QUARTERLY, BI_ANNUALLY, ANNUALLY }
public class SubscriptionFee {
SubscriptionType type; // Replace with String
SubscriptionDuration duration; // Replace with Integer
int cost;
}
Both type and duration are up for debate if you'd rather use String and Integer respectively.
You can try to implement these in your current code and see if it's easier to loop through all the options comparing:
subscriptionFee.type
subscriptionFee.duration
to the information you've collected from the "user".

What is wrong with the formatting in my Java code? [duplicate]

This question already has an answer here:
Why am I getting an exception?
(1 answer)
Closed 6 years ago.
I've been told that there are problems with my formatting, at the end. However, I can't figure out what that would be...The error messages are at the end of the code.
PLEASE DON'T BE AMBIGUOUS WITH YOUR ANSWERS AND TELL ME WHAT TO FOCUS ON OR REVIEW (LIKE FORMATTING).I NEED CONCRETE THINGS TO CHANGE. Thank you!!
Here's the code:
public static void main(String[] args)
{
double pennies = 0.01; //number of pennies
double totalPennies = 0.01; //the variable that is added to
int maxDays; //number of days the loop will double the pennies to
int day = 0; //the variable used to count each day in the loop
//Create a String variable for user input with a console window.
String input;
//Create a scanner object for keyboard input into the console.
Scanner keyboard = new Scanner(System.in);
//Ask user for the number of days to count.
input = JOptionPane.showInputDialog("Enter the maximum number of days worked in your pay period"
+ " and I will tell you how much money you made. Please enter at least 1.");
maxDays = Integer.parseInt(input); //this makes the user's string input into
//an integer data type
//Input Validation
while(maxDays < 1)
{
System.out.println("You have entered a number that "
+ "is less than 1. \nPlease enter a number that is at"
+ " least 1 or more:");
maxDays = keyboard.nextInt();
}
//next we have the first loop that will only execute if the user enters at least 1
while(maxDays >= 1)
{
//here's the chart
System.out.println("Day Day's Income Total "); //titles for the chart
System.out.println("----------------------------------"); //34 dashes/spaces
System.out.println("1 $0.01 $0.01 "); //the first day
//this next nested loop will do the actual counting and add to the chart with
//each iteration
for(day = 2; day <= maxDays; day++)
{
pennies = pennies * 2; //double pennies
totalPennies += pennies; //add the new value of pennies to the running total
//add information from each iteration to the chart
System.out.printf("%10.0d" + "$%18.0f" + "$%6.0f", day, pennies, totalPennies );
}
}
}
Here are the error messages:
Exception in thread "main" java.util.IllegalFormatPrecisionException: 0
at java.util.Formatter$FormatSpecifier.checkInteger(Formatter.java:2984)
at java.util.Formatter$FormatSpecifier.<init>(Formatter.java:2729)
at java.util.Formatter.parse(Formatter.java:2560)
at java.util.Formatter.format(Formatter.java:2501)
at java.io.PrintStream.format(PrintStream.java:970)
at java.io.PrintStream.printf(PrintStream.java:871)
at assignment4PenniesForPay.assignment4PenniesForPay.main(assignment4PenniesForPay.java:65)
Line 65 is the formatting line.
%10.0dis expecting an integer, but you're adding a decimal place in there.

How to have int input correlate to a substring?

I am trying to write a program that takes input from a user. The enter a number 1-12 and it returns the month January-December. I have to have all the months in one long string and then use a substring to return the corresponding month.
I am very confused as to how to get an int to correlate to a substring. I would appreciate some general guidelines for doing this. I'm not looking to have the whole program done for me.
Don't use substring(). If you have a csv of month names, use split() to turn the string into an array:
String months = "January,February,etc";
int choice; // 1-12
String monthName = months.split(",")[choice - 1];
Note that java arrays are zero-based, so you must subtract 1 from a 1-12 ranged number when used as an index.
Easier to read would be:
static String[] monthNames = "January,February,etc".split("");
then in your method:
String monthName = monthNames[choice - 1];
When you get the values of the month using your substring, store it in your array of String. And then get the 1 - 12 value by their indexes + 1.
Beside using Split you can use StringTokenizer to parse your string as well.
My Code:
int i = 1;
int month = 0;
while (i == 1) {
System.out.println("Enter your number ");
Scanner input = new Scanner(System.in);
month = input.nextInt();
if (month > 13 || month < 0) {
System.out.println("your number has to be between 1 and 12");
} else {
i = 2;
}
}
List<String> monthList = new ArrayList<>();
StringTokenizer st = new StringTokenizer("January February March April"
+ " May June July August September October November December");
while (st.hasMoreTokens()) {
monthList.add(st.nextToken(" "));
}
System.out.println("the month is " + monthList.get(month - 1));
My Output:
Enter your number
333
your number has to be between 1 and 12
Enter your number
3
the month is March

How to get last two digit from a year which a user inputs

I Have been playing with this for while, and I can not seem to get my mind around how I can get this task accomplished.
My task :
I need get the last two digits of a year that a user has entered.
Example :
A user enters the July 2 , 2014; I need to get the last two digits of year 2014 which is "14" and divide it by 4. This will give me 3.5; however I will disregard the ".5" and just keep the 3.
Research :
I have been reading my Textbook, and seen one approach that I may be able to use which includes the string builder class. However my book has a very brief description and shows no example which I can constructively use to accomplish me task.
Progress:
This is what I have so far, it is basically a template of how I want my program; I just need some help getting the last 2 digits of a year.
public class DateCalc
{
public static void main (String[] args)
{
String month;
int day;
int year;
Scanner keyboard = new Scanner(System.in);
// receiving input
System.out.print( "Please Enter The Month Of The Date : ");
month = keyboard.nextLine();
// receiving input
System.out.print( "Please Enter The Day Of The Date : ");
day = keyboard.nextInt();
// receiving input
System.out.print( "Please Enter The Year OF The Date : ");
year = keyboard.nextInt();
switch(month)
{
// keys are numbered indexes that I need for this, please disregard
case "January" :
int janKey = 1;
break;
case "February":
int febKey = 4;
break;
case "March":
int marKey = 4;
break;
case "April":
int aprKey = 0;
break;
case "May":
int maykey = 2;
break;
case "June":
int junKey = 5;
break;
case "July":
int julKey = 0;
break;
case "August":
int augKey = 3;
break;
case "September":
int septKey = 6;
break;
case "October":
int octKey = 1;
break;
case "November":
int novKey = 4;
break;
case "December":
int decKey = 4;
break;
// IN MY DEFUALT CASE " inputValidation " WILL BE EXECUTED
default:
JOptionPane.showMessageDialog(null," Invalid Entry Please Try Again " );
}
}
}
You could do something like String yearString = Integer.toString(year).substring(2), which will first convert the integer to a string, then get the substring consisting of everything after the second character. Then to turn it back into an integer, try int yearInt = Integer.parseInt(yearString)
IMHO the cleaner option would be to convert the day,month and year into a Calendar. And then get the two digit year from the calendar.
Something like this:
Calendar cal = Calendar.getInstance();
cal.set(year, month, day);
SimpleDateFormat sdf = new SimpleDateFormat("yy"); // Just the year, with 2 digits
String formattedDate = sdf.format(Calendar.getInstance().getTime());
System.out.println(formattedDate);
One thing you can do is mod the year by 100 to get the last 2 digits. Then you can do whatever math you want with it.
This can be extended to get an arbitrary number of digits; modding a number by 10^n yields the last n digits of the number.
Edit because I was stupid and thought year was a String
String date = "July 2 , 2013";
String year = ""+ date.charAt(date.length()-2) + date.charAt(date.length()-1);
System.out.println(year);
int year2 = Integer.parseInt(year);
System.out.println(year2);

The code isn't working for some reason [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm making a thingy that takes 3 inputs like "1500, 1 and 1" or "1500, January and 1" and returns "January 1st, 1500" or "1/1/1500", i had some problems on the day part but someone already told me how to fix it, and now I'm having problems with the month part, i made this kinda fast and i haven't figured out why it isn't working, it SHOULD see if the input is a valid month, if it is then it outputs the month(this part is just for testing), and if it isn't then it should say "please use a valid month or a number between 1 and 12", but when i write anything that isn't a month it just stops, and doesn't output anything, even if i put a month after it just doesn't do anything, i tried to see if there was any errors but i didn't found any, this is the code that i used:
Scanner scan = new Scanner(System.in);
String mx;
System.out.println("Insert Month");
String[] mm = {"january","february","march","april","may","june","july","august","september","october","november","december"};
int mz = 0;
while (0 < 1){
mx = scan.nextLine();
mx = mx.toLowerCase();
for(int i = 0; i < 11; i++){
if (mx.equals(mm[i])){
mz = i + 1;
break;
}
else {
if(i == 11){
System.out.println("please use a valid month or a number between 1 and 12");
}
else{
}
}
}
//}
if(mz > 0){
break;
}
else {}
}
System.out.println(mx);
The reason your program just "stops" is that you only print the statement "please enter a valid month..." if i == 11 and you have your for loop break if i >= 11. Thus, this condition will never be met. The while loop keeps running, even though this statement isnt printed. You could have entered a non-month string on the first try, and then a month string on the second and your while loop would have been broken.
Here is how I have improved your code to work for taking in the month. Pay attention to subtle changes of highlighted. These are important for writing better, more readable code:
Scanner scan = new Scanner(System.in);
//initialize to empty string
String mx = "";
System.out.println("Insert Month");
//use good naming conventions for easier code readability
String[] validMonths = {"january","february","march","april","may","june","july","august","september","october","november","december"};
//using a boolean to break makes much more sense than the way you have written it with an infinite loop and a manual break statement
boolean noMonth = true;
while (noMonth){
mx = scan.nextLine();
for(int i = 0; i < 12; i++){
//rather than convert to lowercase, use this handy String method
//also compares for valid number entries
if (mx.equalsIgnoreCase(validMonths[i]) || mx.equals(Integer.toString(i+1))){
noMonth = false;
break;
}
}
if(noMonth){
System.out.println("please use a valid month or a number between 1 and 12");
}
}
System.out.println(mx);
Create a new while loop to take in the day and a new one to take in the year after these, checking for valid input. Also, every if does not require an else in Java.
You're not using meaningful variable names, making your code a little bit hard to read and maintain. So, I had to create you the following code from scratch:
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
String month = getMonthName(getInt("Enter Month: ", keyboard) - 1);
int day = getInt("Enter Day: ", keyboard);
int year = getInt("Enter Year: ", keyboard);
System.out.printf("%s %d, %d\n", month, day, year);
}
public static String getMonthName(final int monthNo)
{
String[] months = {"january","february","march","april","may","june","july","august","september","october","november","december"};
return months[monthNo];
}
public static int getInt(final String msg, Scanner keyboard)
{
System.out.print(msg);
return keyboard.nextInt();
}
The code above does NOT perform and input validation, as you may have noticed already. If you want to validate month input for example, your if condition may look something like this:
if (month < 0 || month < 12)
{
System.out.println("Invalid month number entered");
System.exit(0);
}

Categories