Reputation: 43
I'm trying to make a program that will read the high temperatures for 5 days in city A and city B. I've got to make a method for the cities that will take in all 10 values and return them to the main method. I originally had a single method that would count [0]-[4] as cityA and [5]-[9] as cityB, but my professor said that isn't what he wants (even though the answer is technically right).
It's hard to read his handwriting but this seems to be what he was saying to do.
EDIT- I turned it into a variable-length parameter as per suggestions. still working on getting the return statement right but other than that it looks how I would think it should.
EDIT#2 - i just realized that string cities was named city in the main method. fixed that but now i'm getting another error. Return value missing? I'm doing pretty much what the book says now - example in book...
printMax(new double[] {1, 2, 3});
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
________ lastest code
public static double[] getHighTemperatures(String cityName, int numberOfDays) {
Scanner keyboard = new Scanner(System.in);
double[] highsForNewYork = getHighTemperatures("New York", 5);
for (int i = 0; i < numberOfDays; i++)
highsForNewYork[i] = keyboard.nextDouble();
return(highsForNewYork);
}
________ new code
package program10a;
import java.util.Scanner;
public class compareCities {
public static void main(String[] args) {
double[] temp = new double[5];
String[] cities = new String[]{"Miami", "Dallas";
getCityTemp(temp, cities);
}
public static double[] getCityTemp(double[] temp, String... cities) {
Scanner keyboard = new Scanner(System.in);
if (cities.length == 0) {
System.out.println("No argument passed.");
return;
}
String cityA = cities[0];
for (int i = 0; i < temp.length; i++) {
System.out.print("Enter 5 temperatures for City A. ");
temp[i] = keyboard.nextDouble();
if (i < cities.length) {
cityA = cities[i];
}
}
String cityB = cities[0];
for (int i = 0; i < temp.length; i++) {
System.out.print("Enter 5 temperatures for City B. ");
temp[i] = keyboard.nextDouble();
if (i < cities.length) {
cityB = cities[i];
}
}
}
}
________ below is old code
public static double[] getCityHighA(double[] cityA) {
Scanner keyboard = new Scanner(System.in);
for (int i = 0; i < cityA.length; i++) {
System.out.print("Enter 5 temperatures for City A. ");
cityA[0] = keyboard.nextDouble();
cityA[1] = keyboard.nextDouble();
cityA[2] = keyboard.nextDouble();
cityA[3] = keyboard.nextDouble();
cityA[4] = keyboard.nextDouble();
break;
}
return cityA;
}
public static double[] getCityHighB(double[] cityB) {
Scanner keyboard = new Scanner(System.in);
for (int i = 0; i < cityB.length; i++) {
System.out.print("Enter 5 temperatures for City B. ");
cityB[0] = keyboard.nextDouble();
cityB[1] = keyboard.nextDouble();
cityB[2] = keyboard.nextDouble();
cityB[3] = keyboard.nextDouble();
cityB[4] = keyboard.nextDouble();
break;
}
return cityB;
}
Is this the most sensible option, or is it possible to use the same method to pass both cityA and cityB back to the main method? Please note that I have not gotten to Objects yet (I've seen similar topics where Object is used and I do not understand how to go about that). Thanks!
Upvotes: 1
Views: 5796
Reputation: 104080
First, this is pretty ugly:
for (int i = 0; i < cityA.length; i++) {
System.out.print("Enter 5 temperatures for City A. ");
cityA[0] = keyboard.nextDouble();
cityA[1] = keyboard.nextDouble();
/* ... */
break;
Either use the loop (hint: move the for
line down a bit and then make the cityA[]
assignments more generic) or don't use the loop and keep the hardcoded array references. (I prefer the for
loop.)
There are very few cases where putting a break
statement into the body of a for
loop makes sense. It certainly shouldn't be used here. (You might never see a reasonable case while you're in school.)
Now, onto the meat of your question: returning two arrays from a single function.
I think what the professor is suggesting that you should modify the two methods you have here, into a single method that you call twice. Make your function generic enough to handle the arrays of both cities. (This should not be hard. Locate what is actually different between the functions and figure out how to pass the different data in a parameter.)
Your professor might also have wanted you to return a multidimensional array:
/* pseudo-code! */
city[][];
city[0][0] = 1; city[0][1] = 2; /* ... */
city[1][0] = 10; city[1][1] = 5; /* ... */
But this seems unlikely at this point. (It also doesn't seem worth it for only two cities. Think about this when you need to handle three or more cities.)
Update
Your new code is looking significantly better; you're nearly there.
public static double[] getHighTemperatures(String cityName, int numberOfDays)
{
Scanner keyboard = new Scanner(System.in);
double[] highsForNewYork = getHighTemperatures("New York", 5);
for (int i = 0; i < numberOfDays; i++)
highsForNewYork[i] = keyboard.nextDouble();
return (highsForNewYork);
}
getHighTemperatures()
is calling itself recursively here. While
recursive functions are a very useful technique, it doesn't really help
here. You're calling what is essentially a "helper routine" that could be
used to retrieve data about any city, and have hard coded the cities
you're interested in within the routine. Close. :)
public static void main(String[]args)
{
double[] temp = new double[5];
String[]cities = new String[] {
"Miami", "Dallas";
getCityTemp(temp, cities);
}
}
main()
has the list of cities, yay, but your array initialization is a
little off. Also, I'd like to suggest that your getCityTemp()
function
is trying to do too much -- your main()
should describe, at a very high
level, what you're trying to accomplish with the program as a whole. (The
main()
function should almost read like an outline.)
public static double[] getCityTemp(double[]temp, String ... cities)
{
Scanner keyboard = new Scanner(System.in);
if (cities.length == 0) {
System.out.println("No argument passed.");
return;
}
String cityA = cities[0];
for (int i = 0; i < temp.length; i++) {
System.out.print("Enter 5 temperatures for City A. ");
temp[i] = keyboard.nextDouble();
if (i < cities.length) {
cityA = cities[i];
}
}
/* ... */
}
I generally like this kind of defensive programming -- to see that
something has been passed in before relying on it -- but sometimes a
simple Exception
when things blow up is just fine. It's a nuanced
position between how much "internal APIs" should protect themselves and
what kind of error return values make sense from "external APIs". (These
terms are grand and pompous when applied to a program that very nearly
fits on one screen -- but keep this in mind as you see and build larger
programs.)
But note that you've got keyboard input in this function too. (This might just be a function of iterative development and me coming back to the question quite late.) It would be best to confine all keyboard input and display output into a small set of functions and do the computing (I assume you'll need to sort the arrays in the next iteration of your program, so you can find the minimum, maximum, median, average, standard deviation, etc.) in another set of routines. Try to keep each function doing as little as possible: make sure each function does one thing.
Here's a suggested re-write:
public static void main(String[]args)
{
String[] cities = {
"Miami", "Dallas"
};
for (String city : cities) {
double[] highs = getCityTemp(city, 5);
printCityTemp(city, highs);
}
}
I'm using a newer style of for
loop
that avoids all the int i=0; i<array.length; i++
boilerplate code that
is common to a lot of for
loops. (A great many for
loops iterate over
all elements of an array.)
public static double[] getCityTemp(String city, int days)
{
Scanner keyboard = new Scanner(System.in);
double[] highs = new double[days];
System.out.print("Enter " + days + " temperatures for " + city + ": ");
for (int i = 0; i < days; i++) {
highs[i] = keyboard.nextDouble();
}
return highs;
}
All the input is confined to getCityTemp()
, which is called multiple
times with different parameters to select which city will be displayed.
public static void printCityTemp(String city, double[] highs)
{
System.out.print("Highs for " + city + " were: ");
for (double high : highs) {
System.out.print(high + " ");
}
System.out.println("");
return;
}
This simple output routine is there to make sure the input was properly performed. I don't know if it is ideal for your application, but it ought to be useful when debugging.
Note that I haven't tested this -- it may or may not compile. Probably not. Consider it more pseudocode than actual code.
Upvotes: 2
Reputation: 126864
Instead of trying to get 2 arrays returned from one method, consider how you can use the same method twice.
Perhaps make it parameterized, a la
public double[] getHighTemperatures(String cityName, int numberOfDays)
So instead of a having a method hardcoded for city A and another hardcoded for city B, and instead of it being hardcoded to fill in a 5 element array, you can pass any number of cities, any number of days. You simply capture the results each time.
double[] highsForNewYork = ...
double[] highsForLosAngeles = ...
Upvotes: 3
Reputation: 12613
You should use a two dimensional array where the first dimension is the city
, and the second dimension is the temperature
. Like this:
public static double[][] getHighs() {
Scanner keyboard = new Scanner(System.in);
double[][] temps = new double[2][5];
for(int i = 0; i < temps.length; i++) {
for(int j = 0; j < temps[i].length; i++) {
System.out.println("Enter city "+i+"'s temperature #"+j);
temps[i][j] = keyboard.nextDouble();
}
}
return temps;
}
Otherwise, you can parameterize the method as @AnthonyPegram said.
Upvotes: 2
Reputation: 1054
Your for
loops are pretty loopy. :)
i
variable is there for a reason. Instead of what you're doing now, do this:
for (int i = 0; i < cityB.length; ++i) {
System.out.printf("Enter temperature #%d for City B: ", (i + 1)); // I _think_ there's printf() in Java and it works like C's...
cityB[i] = keyboard.nextDouble(); // note the use of `i`
}
Upvotes: 2
Reputation: 4885
You could make a two dimensional array:
public static double[][] getCityHighs(...) {
double[] cityA = new double[5];
//....
double[] cityB = new double[5];
//....
return new double[][]{cityA, cityB};
}
double[0] will equal cityA and double[1] will equal cityB. So if you want to get the first value of cityA, then you would do array[0][0];
Or you could create a class that stores the two cities:
class cities {
double[] cityA;
double[] cityB;
}
Upvotes: 3