I am writing a Java code with displays a histogram of rainfall (in millimeter) on days 0 to 6, ie. day0 is Monday and day6 is Sunday. The code is I have written for the average rainfall over 7 days is the following:
public float averageRain() {
int d;
float total = 0.0f;
for (d = 0; d < days; d++)
total=total + rain[d];
return(total / days);
}
But I am stymied on how to solve the following: If you enter a day number which is less than 0 or greater than 6, you get an error message. My task is to modify a method called "addRain" to check whether the day is in range (i.e. 0 or greater, but less than constant days). If the day is valid, add RAINFALL to the total for the day and return true. Otherwise return false. By doing so, when I run the program, the invalid days are ignored. Also, I have to modify the code so that NEGATIVE rainfall values (eg. -3 mm) are NOT accepted. Could anyone tell me how to solve this matter? All I have done so far is this:
public boolean addRain(int day, float rainfall) {
rain[day] += rainfall;
return(true);
}
I assume days is a constant with value 7. Replace it with:
private static final int DAYS_IN_WEEK = 7;
Do you want to simply ignore invalid day numbers or rain values? Is this an interactive program? And, do you want to let people enter rain values twice for a single day? I can see someone entering 10mm for Wednesday and then trying to correct it and enter 5mm. Currently, there is no way to do so. If you know how to use exceptions, you can have your method throw java.lang.IllegalArgumentException and report it to the user so he can try again:
public void setRainForDay(int day, float rainfall) {
if (day < 0 || day >= DAYS_IN_WEEK) {
// Throw an IAE.
}
if (rainfall < 0.0f) {
// Throw an IAE.
}
rain[day] = rainfall; // Set, not add.
}
The calling routine catches the IAE, reports it to the user, and the user can try again.
Swing
I had not realized that the application was supposed to be a Swing application. In that case, throwing exceptions is not the appropriate method. Instead, one wants to have a model class, one that holds the data, and one wants to have the view classes, and one wants to have controller classes that do the actual work. And, one wants to use PropertyChangeListeners and VetoableChangeListeners. When you type -10 into the rainfall JFormattedTextField, it sends a property change event to the controller, whig must then refuse to set the model class, instead vetoing the change. Actually, it will be simpler to write and apply an InputValidator. It's best not to give the user the opportunity to err.
Related
i understand what they do and what their purpose is and i've used them successfully many times. but there seems to be some things i don't yet understand that keep getting in the way. for instance, im assigned to create a program to prompt the user to input their birthday then calculate the number of days until their birthday. The main should not have any print statements, just methods. here is a method i wrote:
public static int inputUser () {
Scanner console = new Scanner(System.in);
System.out.println("Please enter your birthday: ");
System.out.print("What is the month (1-12)? ");
int month1 = console.nextInt();
if (month1 == 4 || month1 == 6 || month1 == 9 || month1 == 11) {
System.out.print("What is the day (1-30)? ");
} else if (month1 == 1 || month1 == 3 || month1 == 5 || month1 == 7 || month1 == 8 || month1 == 10 || month1 == 12) {
System.out.print("What is the day (1-31)? ");
} else if (month1 == 2) {
System.out.print("What is the day (1-28)? ");
}
int day1 = console.nextInt();
int absBday = daysInMonth(month1, day1);
System.out.println(month1 + "/" + day1 + " is day #" + absBday + " of 365.");
return absBday;
i want to use the returned value in another method i'm writing but i can't figure out how to access this returned value for the new method. the other method will basically calculate how many days from today until the user's inputted birthday, which i have another method already successfully written for determining how many days into the year any given day is, i just need this returned "day #" to do one last tiny little method. anybody got any pointers?
i basically just tried things my intuition already knew wouldnt work, like trying to call absDays in the new method i'm writing, trying to define the userInput method with a declared type and variable in the parameters, with AND without matching it to the absDay variable name...just basically a bunch of things i already pretty much knew were not going to work, but sometimes when i'm experimenting i'll have an AHA! moment even if i'm trying something that obviously won't work, but the AHA! moment never came :(
I am not sure if I understand your question fully. But I think the following might work.
public static int inputUser(){
// Your code in question
}
public static int theOtherMethod(int n){
// already working method
}
You just have to call
int nDays = theOtherMethod(inputUser());
i just wanted to post what i ended up doing, for anyone browsing for help.
all i needed was to declare a variable in main and initialize it to the method i illustrated above that holds my desired return value, which would then hold that returned value as well, allowing me to pass that new declared variable as an argument to another method, which i actually needed to do this twice, two new variables in main/2 return values from 2 different methods, to achieve my desired results.
i actually solved my own issue before checking my answers here. i dont know if yall have heard of the rubber duck method? if youre stuck, ask a detailed version of your question out loud to a rubber duck, or anything really, or a friend whether they know anything about what youre asking or not, because the process of illustrating the question thoroughly activates additional useful resources in your analysis. basically, after i emailed my professor then posted this question here, i returned back to my program and suddenly had a much more clear and almost zen like perspective, and started connecting dots more efficiently which led me to discovering the answer to my own question. thanks for your time guys! this website has helped tremendously
I've been writing a program that requires the input of a number between 1 and 4. In order to prevent input of numbers outside the range. However the variable keeps passing to another piece of code and causing the program to fail.
This is the do while loop:
do
{
System.out.println("Please enter a quarter number 1-4: ");
quarter = scanIn.nextInt();
}while((quarter > 5 ) && (quarter < 0));
This is the piece of code that runs the variable:
for (int n = ((quarter * 3)-3); n < (quarter*3); n++)
{
String sum = fmt.format(monthSales[n]);
System.out.printf("Sales for month %d: %s\n", n+1, sum);
}
This is the error that returns when incorrect input is entered:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -6
at lab4.Lab4.main(Lab4.java:57)
I have tried limiting the scope of "quarter" to only within the loop but then the while clause does not function. How can I prevent the variable from passing until the loop has closed?
p.s. This problem is part of an assignment and therefore I must use a do while loop.
I see one thing in your code:
The "do/while" condition seems to be wrong. If your intention is, as I understood, keep asking the user until s/he informs a valid quarter between 1 and 4, the condition should be something like
do {
// ...
} while (quarterNum < 1 || quarterNum > 4);
If I suppose that quarter receives the value of quarterNum in some code in between, the second part seems to be correct and the exception should only occurs if quarter is not a valid value (-1 to be exact). Fixing the do/while condition it will not be possible any more.
I don't see where limiting variable scopes could have anything with your issue. (and I don't even see what you mean by "prevent[ing] the variable from passing until the loop has closed").
I hope I could help you.
I've created a program that allows a user to enter in Journal entries (up to 7 days) and then allows a person to call up one of those days after they enter in an entry. Unfortunately, this has left me with some weird string error that I'm not familiar with.
Code as follows:
public class eDiary{
public static void main (String args[]){
int[] days = new int[7];//get our days
days[0] = 1;//start with 1 and not 0
days[1] = 2;
days[2] = 3;
days[3] = 4;
days[4] = 5;
days[5] = 6;
days[6] = 7;
String [] events = new String[7];//events for the days
int i = 0;
//asks for input and counts
for(i=0; i<7; i++){
String event = Console.readString("Tell me the major event of day " + days[i] + "\n");
events[i] = event;
}
int journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
while (journal_entry != 0) {
System.out.println(events);
journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
//get r dun!
The input and output:
Tell me the major event of day 1
one
Tell me the major event of day 2
two
Tell me the major event of day 3
thre
Tell me the major event of day 4
four
Tell me the major event of day 5
five
Tell me the major event of day 6
six
Tell me the major event of day 7
seven
Enter what day you want to hear or Enter 0 to stop
1
[Ljava.lang.String;#10181f5b
Enter what day you want to hear or Enter 0 to stop
0
Howdy y'all!
Thanks a lot for the quick responses. One thing it seems to be doing now is when replacing
System.out.println(events);
with
System.out.println(events[journal_entry]);
Now gives me input such as this:
Tell me the major event of day 1
first day
Tell me the major event of day 2
second day
Tell me the major event of day 3
third day
Tell me the major event of day 4
fourth day
Tell me the major event of day 5
fifth day
Tell me the major event of day 6
sixth day
Tell me the major event of day 7
seventh day
Enter what day you want to hear or Enter 0 to stop
1//the day im asking for
second day//spitting out the next day's entry instead of the first day's entry
Enter what day you want to hear or Enter 0 to stop
0//this is me stopping it
It's not an error.
System.out.println(events);
In this line you are trying to print the array, but that statement doesn't print the array contents, it only prints the object class name followed by its hashcode.
To print the array content you have to use
System.out.println(Arrays.toString(events));
Or, if you want, loop through the array and print its values
The [Ljava.lang.String;#10181f5b stuff is what you get when you explicitly or implicitly call Object.toString() and the target object's class doesn't override toString(). In this case, the issue is that Java array types do not override toString().
If you want to output an array, use java.util.Arrays.toString(...) to convert it to a String, then output that.
But in this case, you actually need to output a specific entry, not the entire array. The fix is to change
System.out.println(events);
to
System.out.println(events[journal_entry]);
For the record, the stuff above consists of the classes internal name ("[Ljava.lang.String;") and the object's identity hashcode (in hexadecimal).
This is not a "weird error string".
The output you are getting is because:
In Java, each object has toString() method, the default is displaying the class name representation, then adding # and then the hashcode.
You should use Arrays#toString(), which is implemented this way:
3860 public static String toString(int[] a) { {
3861 if (a == null)
3862 return "null";
3863 int iMax = a.length - 1;
3864 if (iMax == -1)
3865 return "[]";
3866
3867 StringBuilder b = new StringBuilder();
3868 b.append('[');
3869 for (int i = 0; ; i++) {
3870 b.append(a[i]);
3871 if (i == iMax)
3872 return b.append(']').toString();
3873 b.append(", ");
3874 }
3875 }
This will help you to better understand arrays.
Of course you can manually loop on the array and print it:
for(String event: events) {
System.out.println(event);
}
There is nothing wrong and that's not an error message.
Instead, it's the string representation of an array. Consider this line:
System.out.println(events);
You are printing the whole array, so you get that representation -- which happens to be a bit ugly, indeed. You want to print only one element, the one corresponding to the selected day. Use:
System.out.println(events[journal_entry]);
And perform bound checks.
This is not an error. You want to print the value of variable events. [Ljava.lang.String;#10181f5b means that events is an array of type java.lang.String and 10181f5b is hashcode of this variable. What you want to println is event[i] where i is the number of a day.
In java array's are consider as object. you are printing the event array object that's not what you want.
You need to print name of the day in a week. You need to replace
System.out.println(events);
to
System.out.println(events[journal_entry]);
It won't print out the answer correctly because you just pointed System.out.println() to events which is supposed to be an array pointer and not the actual variable. You should just replace this line with
System.out.println(events[journal_entry]);
For it to make sense. Run it with the conmmand and see if it will run properly.
Thanks for all the responses! I was able to resolve the issue. Here's the code if anyone is curious:
public static void main (String args[]){
int[] days = new int[7];//get our days
days[0] = 1;//start with 1 and not 0
days[1] = 2;
days[2] = 3;
days[3] = 4;
days[4] = 5;
days[5] = 6;
days[6] = 7;
String [] events = new String[7];//events for the days
int i = 0;
//asks for input and counts
for(i=0; i<7; i++){
String event = Console.readString("Tell me the major event of day " + days[i] + "\n");
events[i] = event;
int journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
while (journal_entry != 0) {
System.out.println("On day " + days[i = 0] + " " + events[journal_entry - 1]);
journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
public class Balance {
public static void main(String[] args) {
System.out.printf("%.2f\n", balance(0.0, 0.0, 0.0));
}
/**
* #param principal
* #param rate
* #param years
* #return
*/
public static double balance(double principal, double rate, double years) {
double amount = 0;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the initial investment amount: ");
principal = sc.nextDouble();
System.out.print("Enter the interest rate: ");
rate = sc.nextDouble();
System.out.print("Enter the number of years: ");
years = sc.nextDouble();
for (int i = 1; i < years; i++) {
amount = principal * Math.pow(1.0 + rate, years);
amount += principal;
}
return amount - principal;
}
}
My problem is with the printf line that I am using within the main method. Eclipse wants me to change the method balance from void to Object[]. When I do this I must return a value from balance. So I guess my question is, how would I return the proper value? Am I on the right track? Thank you for your time and constructive criticism. :)
EDIT - Thanks for the help everyone, much appreciated :) My math is off. I end up with 1000 more than I should have. hmmm.
So should I just take a 1000 from amount like so:
return amount - 1000;
Or this:
return amount - principal;
EDIT this is what I am going with since it is due tonight. Thanks to all for the assistance. :)
A few points:
balance() cannot be void, because you use its return value in S.out.printf(). Do you want balance to print to the screen, or do you want it to yield a number?
Your loop for (years = 0; years > 10; years++) won't run. Think about why. It might help to convert the for into a while, to visualize why.
You read in years as a double, but then use it as a counter in your loop. What type should it actually be?
Your balance() function takes three parameters, then immediately gets input and obliterates them. Do you want balance() to be provided these numbers, or do you want it to fetch them?
Otherwise, you seem to be on the right track.
The problem is that balance doesn't return anything, (it's a void function). Change it to:
public static double balance(double principal, double rate, double years) {
...
And inside that function, return the balance.
Java is telling you it wants an Object[] because printf is defined like this:
public static void printf(String format, Object ... params) {
// params is an Object[]
}
What this lets you do is pass parameters like this:
printf("some string", first, second, etc);
It lets you pass as many parameters as you want, and the function can handle them as if you passed an array.
It's exactly the same as if it was defined like this:
public static void printf(String format, Object[] params);
And you used it like this:
printf("some string", new Object[] { first, second, etc});
It's just easier to use.
EDIT:
The other option is to not print anything in main, but I would definitely advise returning the result and printing it in main. This follows the principle of making each function do as little as possible. balance should just calculate the balance. Printing it is unrelated.
Please consider a more drastic re-working of your code; as it is, your balance() function is doing all the work of your program (and your printf() line feels like an afterthought). If you break apart your code based on what the code does, I think you can do much better:
create a function that prompts the user and then reads in their input
create a function that calls the previous function three times for principal, rate, and years
create a function that computes and populates a payment schedule. Keep track of year, balance, payment, principal payment, and interest payment. (Or just the variables you're interested in -- but be aware that programs tend to grow new features, and these variables are often the second thing that users (or professors) ask to know when paying down a loan.)
create a function that prints the selected columns from your payment schedule.
create a function that orchestrates the previous functions.
When you re-write your program to use a GUI or webservice in three weeks, you'll definitely thank yourself for having written each function to do one task, and do it well. You'll also find it far easier to test smaller pieces of code that do only one task.
There is the risk of over engineering a too-generic solution -- what I'm really trying to suggest is a functional decomposition of your code into multiple smaller routines that do exactly what their name says. You might never move the program into a GUI or webservice or whatever, but you'll definitely be happier when someone reports that your amortization schedule is wrong, that you can control it via simpler programming, rather than having to re-type inputs all day long.
Yours is wrong, do this:
public static void main(String[] args) {
balance(1000.0, .05, 8.5);
}
Ok so for a big lab I have to do the first part is to write a calendar class just like the one I've written here. This was pretty simple because we got really direct instructions on how to do this. I'll show it in case that helps with the problem:
import java.util.Scanner;
public class Calendar
{
static final int FEBRUARY = 2;
static final int MONTHS_PER_YEAR = 12;
static int [] daysPerMonth =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static String [] months =
{"", " Januray", "February", " March", " April",
" May", " June", " July", " August",
"September", " October", "November", "December"};
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter the year? (yyyy): ");
int year = in.nextInt();
int firstDay = firstDayOfYear(year);
// February: Check for leap year
daysPerMonth [FEBRUARY] = isLeapYear(year) ? 29 : 28;
for (int i=1; i <= MONTHS_PER_YEAR; i++) {
Month month = new Month(daysPerMonth[i], firstDay);
System.out.println("\n\n "+months[i]+" "+year);
month.printMonth();
firstDay = month.getFirstDayOfNextMonth();
}
}
private static boolean isLeapYear(int year) {
return ((year%4 == 0) && (year%100 != 0)) || (year%400 == 0);
}
private static int firstDayOfYear(int year) {
return (2 * (13) + (3 * (13+1)/5) + (year-1) + ((year-1)/4)
- ((year-1)/100) + ((year-1)/400) + 2) % 7;
}
}
Ok so that's the first class. The part I'm really having trouble even getting started with is writing a "months" class. I've created the class and I keep trying to start setting up different methods and doing things like that but I really just can't seem to grasp the concept of how exactly to set up something in one class, so that it works for another class.
Here's the exact thing the months class has to do: The Month class that you have to define must contain the following state and behavior:
STATE
the number of days in the month (an integer between 28-31)
the first day of the month (an integer between 0-6, Sun=0, Mon=1, Tues=2, Wed=3, Thurs=4, Fri=5, Sat=6)
BEHAVIOR
A standard constructor with two parameters to set the state of the Month directly.
A method that returns the day that the NEXT month should start on.
A method that prints out the calendar for that month using a loop. That is, you should not just have 28 different sets of println() statements that print the calendar out directly.
I have a really hard time doing some things in java just because I'm just learning the language. Please don't suggest that I go read a java book or something like that because I've done that and this is still just a foreign language to me. ANY help with this would be greatly appreciated, I'm not saying answer it for me by any means, just maybe give me suggestions on how to do it.
Here's what my months class is so far
import java.util.*;
public class Month {
Scanner sc = new Scanner(System.in);
public static void Month(int daysPerMonth, int firstDay) {
daysPerMonth = MONTHS_PER_YEAR
}
}
And that's just completely wrong. I keep trying different things with the month method like static int, no static, and different things on the inside, but nothing will allow me to NOT get an error which is very frustrating. Sometimes java is very annoying because my professor is awful and doesn't actually teach how to write code at all, just things about how computers work.
Here is an example of a layout of a class, in this case the Month Class
Month <--------------- Class
daysPerMonth <---- State
firstDay <------------- State
Month <-------------- Behaviour
startDay <------------ Behaviour
printCal <------------ Behaviour
So from the definition we need,
two states
three behaviours (including the constructor)
This is all this class sees and knows about. So you must tell the class what it needs to know.
Currently you have the following
Month <----------- Class
sc <-- State
Month <----------- Behaviour
You made a Scanner object sc, as a state as it not held in any of the behaviours. Let's leave this out for now, so delete this. The states we need are above in the diagram. Let's try adding a state
public int daysPerMonth;
You can try adding the next one. And think of the above (should it be static or not ?)
Now your constructor does not need to be static, it is a modifier but we do not need it right now
A static modifier on a method means that we want to access a method without instantiating an object. But you do not want to do right ? We want to instantiate an object. So let's remove these identifiers. For now, let's say all constructors only need the following
public CLASSNAME , where CLASSNAME is the class that holds this method/constructor. So just remember for now that a constructor initializes an object upon creation and all it needs is to have the same name as the class and be public. So this is how your constructor should look.
public Month(){
}
How about we try adding the parameters they asked for ?
public Month(int numDaysPerMonth, int firstDay){
}
Okay so now we need to set the variables we made earlier on, left side gets assigned the value, right does the assigning
public Month(int daysPerMonth, int firstDay){
this.daysPerMonth = daysPerMonth;
// I will let you do the next one
// Hmm what does the "this" do here?
}
This should get you on the right start for the first line
Month month = new Month(daysPerMonth[i], firstDay);
Now to take a break, look back over this section you should know how to use the following
constructors
static, final, public identifiers
this
On to the next stage, the first behaviour to match the method of this object
month.printMonth();
Things to notice,
This is a method of the month instance, so it should not be a static method
It does not take any parameters, so the behaviour in the class should have no parameters as well
It is not assigned to anything, so the behaviour in the class should return void
Here is what it should look like knowing this information
public void printMonth() {
}
Pretty empty, so it's up to you to fill up inside. Some hints for this method.
Helping variables
static String [] day = {"Sun","Mon","Tues","Wed","Thurs","Fri","Sat"};
int nextDay;
Loop
Your loop should start from 1 and end on daysPerMonth
Changing the day
Just add 1 to traverse the helping variable above, you should use a local variable instead of firstDay to keep track of the current day
Resetting the days
There many ways to do this, I just used a conditional that checked if the current checked day reached "Sat" and then reset to "Sun"
Now when you are done the whole loop the last day should be your next day of the next month, yes ! we killed two behaviours with one. Assign the value to nextDay
So your next method just needs to return nextDay and since it needs to be assigned to an int (noted in the Calendar class) we need to match this within out class as well
public int getFirstDayOfNextMonth() {
return nextDay;
}
And there you go, Java demystified.
Here is something to get you started. In particular notice the 2 parameters to the constructor (as specified). I've also tried to follow the style of your existing Calendar class.
public class Month {
int numDays, startDay;
String[] days {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
public Month(int numDays, int startDay) {
this.numDays = numDays;
this.startDay = startDays;
}
//There will likely be a quicker way of doing this (and I haven't tested it, so this might not even work. But then again, I shouldn't do everything for you!
public int getStartDayOfNextMonth() {
int nextDay = startDay;
for(int i = 0; i < numDays; i++) {
if(nextDay + 1 > days.getLength() - 1) nextDay = 0;
else nextDay++;
}
return nextDay;
}
}