I was doing a java exercise the other day and in the exercise we had to get input from the user and then figure out what the max value was and what the average was. We then had to print out those values. Values could only be positive integers and when the user enters a negative integer the program should stop taking in values and not account for that negative integer into the average calculation. My problem was I couldn't figure out a way to compare the current integer entered by the user to the max value.
I just made it's own if statement for it and I was expecting a compile error that the max variable didn't have a value or something like that, but the code worked just fine. So my question is do if statements have their own scope or not? What even has scope in programming and what doesn't.
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
//Create Scanner.
Scanner inp = new Scanner(System.in);
//Declare and initialize variables.
double average;
int sum = 0;
int num;
int counter = 0;
int max = 0;
//Process.
do
{
num = inp.nextInt();
sum += num;
if(num > max)
{
max = num;
}
if(num < 0)
{
sum -= num;
System.out.print(max);
average = sum/(double)counter;
System.out.printf(" %.2f\n", average);
}
++counter;
}while(num >= 0);
}
}
Do if statements have their own scope?
No, in Java if statements do not by themselves create a new scope (until Java 14, that is!). However, braced statement blocks (i.e. {…}) do create a new, nested scope.
However, this is unrelated with your issue, because nested scopes can access variables from their parent scope (otherwise most code wouldn’t work). So the following works:
int x = 1;
{
System.out.println(x);
}
If {…} didn’t inherit the parent scope, that code wouldn’t work.
As noted by Ivar in the comments, your code works because you did initialise the max variable to 0 outside the loop.
That said, the code can be made simpler and more logical. In particular, the calculation of the average and the output should not be part of the loop but instead happen afterwards:
Scanner inp = new Scanner(System.in);
int sum = 0;
int count = 0;
int max = 0;
int num;
do {
sum += num;
num = inp.nextInt();
if (num > max) {
max = num;
}
++count;
} while (num >= 0);
double average = sum / (double) (count - 1);
System.out.printf("%d %.2f\n", max, average);
A commonly used alternative way of writing this loop is using for(;;) with break;. This variant has the alternative that we can limit the scope to num to the loop: it is generally desirable to make variable scope as small as possible, and to initialise a variable at the site of its declaration.
…
for (;;) {
int num = inp.nextInt();
if (num < 0) break;
sum += num;
if (num > max) {
max = num;
}
++count;
}
…
Related
I'm trying to write a code which will show the highest, lowest, the difference of them and the average of inputted 30 numbers.
But its not working and is showing the same result for both min and max numbers. Here is the code.
public class aa {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] daystemp = new int[30];
int i = 0;
int dayHot = 0;
int dayCold = 0;
while(i < daystemp.length){
daystemp[i] = input.nextInt();
i++;
}
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
i++;
}
}
System.out.println(maxTemp);
int minTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] < minTemp) {
minTemp = daystemp[i];
dayCold = i + 1;
i++;
}
}
System.out.println(minTemp);
int diff = maxTemp - minTemp;
System.out.println("The difference between them is"+diff);
double sum = 0;
while(i < daystemp.length) {
sum += daystemp[i];
i++;
}
double average = sum / daystemp.length;
System.out.println("Average was"+average);
}
}
After the first loop (the input loop), i value is daystemp.length (i.e. 30).
It's never reset to 0. So each while loop condition is false.
Add i=0 before the loops and do i++outside the ifblocks or your code will never end.
example:
i=0;
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
}
i++;
}
A few notes about this solution:
By declaring the cumulative total double, no casting is required.
Because Java knows you want to convert int to double automatically if you assign an int to a declared double. Similary the fact that you want to express a result as double is implied when dividing a double by an int, such as when the average is taken. That avoids a cast also. If you had two ints and you wanted to produce a double you'd need to cast one or more of them, or in cases like a print statement where the compiler can't deduce the optimal type for the parameter, you'd need to explicitly cast to covert an int value to a double.
Not sure what OS you're running this on. The ideal situation would be to make it work on all platforms without requiring people type a magic word to end input (because how tacky). The easiest way to end input is to use the OS-specific end of input (end of file) key combination, and for Linux it's CTRL/D, which is how I explained it in the prompt. On another OS with a different end of input sequence you could just change the prompt. The trickiest would be if it is supposed to be truly portable Java. In that case I'd personally investigate how I could figure out the OS and/or End of File character or key combination on the current OS and modify the prompt to indicate to end input with whatever that is. That would be a bit of and advanced assignment but a very cool result.
Example illustrates use of a named constant to determine the array and is used limit the amount of input (and could be used to limit loop count of for loops accessing the array).
By setting the min and max to very high and low values respectively (notice the LOW value assigned to max and HIGH value assigned to min, those ensure the first legit temp entered will set the min and max and things will go from there).
Temperature Maximum, Minimum, Average and Difference Calculator
import java.util.Scanner;
public class TemperatureStats {
final static int MAX_DAYS = 31;
public static void main(String[] args) {
int[] dayTemps = new int[MAX_DAYS];
double cumulativeTemp = 0.0;
int minTemp = 1000, maxTemp = -1000;
Scanner input = new Scanner(System.in);
System.out.println("Enter temps for up to 1 month of days (end with CTRL/D):");
int entryCount = 0;
while (input.hasNextInt() && entryCount < MAX_DAYS)
dayTemps[entryCount++] = input.nextInt();
/* Find min, max, cumulative total */
for (int i = 0; i < entryCount; i++) {
int temp = dayTemps[i];
if (temp < minTemp)
minTemp = temp;
if (temp > maxTemp)
maxTemp = temp;
cumulativeTemp += temp;
}
System.out.println("High temp. = " + maxTemp);
System.out.println("Low temp. = " + minTemp);
System.out.println("Difference = " + (maxTemp - minTemp));
System.out.println("Avg temp. = " + cumulativeTemp / entryCount);
}
}
This is regarding some homework and I tried to make a range which is 10 to 40.
The code would accept two inputs within the range. The method will then check if both numbers are within the range and then if they are it would give me the product of both numbers, if not it is suppose to show me a message.
I have been working on this for quite a long time and I cant get it to work I am a complete beginner.
public class testing
{
public static int computeProduct(int first , int second)
{ int max = 40;
int min = 10;
int total = first * second;
if (min <= first) {
if (first <= max) {
if (min <= second) {
if (second <= max) {
total = first * second;
} else {
System.out.println("Number is not in range, please try again");
}
}
}
}
return total;
}
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a number between 10 to 40:");
int x = scanner.nextInt();
System.out.println("Enter another number between 10 to 40:");
int y = scanner.nextInt();
int total = computeProduct(x, y);
System.out.print("Product of x and y = " + total);
}
}
Expected result is to show me if the numbers are not in range but it is not doing so currently.
It gives me the product of both numbers regardless whether it is in the range.
Here:
int total = first * second;
followed by an if, follewed by:
return total;
Meaning: every time when your if evaluates to false, your method simply returns the value that you assigned initially!
What you could do: have an else block that prints the error message. Or that throws an exception.
But ideally, you should separate concerns here. Meaning:
write a method like boolean inRange(int first, int second). That method returns true or false, depending on first / second matching your criteria
if that method returns true, call compute(), otherwise print your message
In other words: your compute() method maybe shouldn't have that if block at all. Let that method compute the result, and have another method tell you whether you want to invoke compute() or not.
A "ladder" built from ifs behaves as a logical and relation. The first if passes when a condition applies, then the second if passes when both the previous condition applies and its own condition, and so on.
However for checking if something is off, violating any (even a single one) of the rules is enough, that is a logical or relation.
While it is not the best coding style, you could mechanically rewrite that structure into this via flipping the comparisions and dismantling the ladder:
public static int computeProduct(int first , int second)
{
int max = 40;
int min = 10;
if (first < min) {
System.out.println("Number is not in range, please try again");
return 0;
}
if (first > max) {
System.out.println("Number is not in range, please try again");
return 0;
}
if (second < min) {
System.out.println("Number is not in range, please try again");
return 0;
}
if (second > max) {
System.out.println("Number is not in range, please try again");
return 0;
}
return first*second;
}
This method displays the message and returns with 0 if the input is not valid, and returns the product if everything is fine.
Then it could become an actual logical or, which is denoted as || in Java:
public static int computeProduct(int first , int second)
{
int max = 40;
int min = 10;
if (first < min
|| first > max
|| second < min
|| second > max) {
System.out.println("Number is not in range, please try again");
return 0;
}
return first*second;
}
Now as I think of it, there is nothing wrong with your original condition either, just the result has to be flipped: when the code reaches the innermost block, everything is fine, so that is the place where you could return first*second;. And if any of the if fails, you need the message and return 0;:
public static int computeProduct(int first , int second)
{
int max = 40;
int min = 10;
if (min <= first) {
if (first <= max) {
if (min <= second) {
if (second <= max) {
return first*second;
}
}
}
}
System.out.println("Number is not in range, please try again");
return 0;
}
Now I am not so sure if this helps or not...
There you go :
public static int computeProduct(int first , int second)
{ int max = 40;
int min = 10;
if(first<=min || second<=min ||first>=max||second>=max)
{
System.out.println("Number is not in range, please try again");
return 0; //or return whatever you like
}
return first *second ;
}
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a number between 10 to 40:");
int x = scanner.nextInt();
System.out.println("Enter another number between 10 to 40:");
int y = scanner.nextInt();
int total = computeProduct(x, y);
if(total!=0){
System.out.print("Product of x and y = " + total);
}
else {
System.out.print("cannot compute as numbers are not in range");
}
}
I need to be able to input a list of numbers the last being -1 and have it print the reverse(not including -1) and then find the average. I have to use a function for finding the reverse. Im stuck because it cannot resolve my average which means I cannot run the program to see if there are other problems.
import java.util.Scanner;
public class Reverse {
public static void inReverse (int a) {
int number;
int[] value;
for (a = number - 2; a >= 0; a--) {
System.out.print(value[a] + " ");
}
}
public static double findAverage (int p, double average) {
int number;
for (p = number - 2; p >= 0; p--) {
average += value[p];
}
average = average / (number - 1);
return average;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] value;
int i, number, size;
size = 20;
System.out.println("Please enter the integers: ");
while (value[i - 1] != -1 && number < size) {
value[i] = input.nextInt();
i += 1;
number = i;
}
System.out.println("The values in reverse order are: ");
inReverse(i);
System.out.println(" ");
System.out.println("The average is " + average);
}
}
Your problem is that you have confused "local variables" with "fields".
Local variables are variables that you declare inside the body of a method. They can't be used before the declaration, and they can't be used once the method stops running - their values have ceased to exist.
Fields are variables that you declare inside your class, but outside any methods. These live inside each object of the class (or inside the class itself if you declare them as static), which means they keep their values from one method call to the next.
You have int number; and int[] value; declared inside different methods, which means they are local variables, and they are recreated each time those methods run. This isn't what you want. You either want to pass them from one method to the next, as parameters; or to have them as fields of your class.
UPDATED
How can you by using this method (Collatz conjecture) to find the number with the highest number of operations between, say 4 and 230.
Any guidance appreciated.
public static void main(String[] args) {
System.out.print("Enter a low integer ");
Scanner input = new Scanner(System.in);
int low = input.nextInt();
System.out.print("Enter a high integer ");
int number = input.nextInt();
maxendurance(number);
}
public static int maxendurance(int number) {
int count = 0;
System.out.print("The number " + number);
// need to loop this i suppose in relative to user input
while (number != 1) {
number = (number & 1) != 0 ? number * 3 + 1 : number >> 1;
count++;
}
System.out.println(" has endurance: " + count);
return number;
}
You will have to loop through all the numbers between low and high. Look into for-loops:
for(int number = low; number <= high; number++)
{
// do something with number
}
Somehow you will need to execute a for every number within the loop (hint: pass it in as a parameter). Then keep track of the number with the highest count.
Oh, and please name your methods more clearly than a and b - nobody will understand what they do without going through the code.
First of all, move the input out of method a:
public static void main(String[] args) {
System.out.print("Enter an integer to be checked: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
a(number);
b();
}
public static int a(int number) {
int count = 0;
System.out.print("The number " + number);
[...]
Then you can use a simple for loop to iterate between low and high:
int bestNumber = -1;
int bestScore = -1;
for (int i = low; i <= high; i++) {
int score = a(i);
if (score < bestScore) {
bestNumber = i;
bestScore = score;
}
}
The result can then be found in bestNumber.
I am going to suggest a more advanced approach, in case relevant and incase anyone comes upon this. If you are concerned about time efficiency, Memoization or Dynamic Programming can help you, especially inverse dragon recursion.
I'll give you a hint. If you need more, just comment.
Take 3 for example. One transformation T has T(3)=10. If prior you had found it takes v transformations to take 10 to 1 and you stored (10,v) in a map, then instantly you know that it takes (v+1) steps to get 3 to 1.
Write a class called Average that can be used to calculate average of several integers. It should contain the following methods:
A method that accepts two integer parameters and returns their average.
A method that accepts three integer parameters and returns their average.
A method that accepts two integer parameters that represent a range.
Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive).
Implement the class and write a program to test its methods and submit your source code (.java files).
I am stuck on part three, I don't even really understand the stipulation. Will I be using a floating point / double? Here is the program I have thus far:
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int numb1, numb2, numb3, userInput;
System.out.println("Enter '2' if you wish to average two numbers enter '3' if you wish to average 3.");
Scanner keyboard = new Scanner(System.in);
userInput = keyboard.nextInt();
if (userInput == 2){
System.out.println("Enter two numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2));
System.exit(1);
}
if(userInput == 3){
System.out.println("Enter three numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
numb3 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2, numb3));
System.exit(1);
}
}
public static int average (int num1, int num2) {
return (num1 + num2) / 2;
}
public static int average (int numb1, int numb2, int numb3){
return (numb1 + numb2 + numb3) / 3;
}
}
Please don't re-ask the same question as you just asked here: http://stackoverflow.com/questions/19507108/java-averaging-program
Rather update your other post to reflect your new code / questions.
Now onto your question:
A method that accepts two integer parameters that represent a range. Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive). Implement the class and write a program to test its methods and submit your source code (.java files).
Lets start by declaring our method and we'll declare it as static to conform to your program (since you're not creating your own objects). Then we want to check if the parameters follow the assignment instructions and return values accordingly.
public static int getRange(int firstValue, int secondValue)
{
int range;
if (firstValue > secondValue)
range = firstValue - secondValue;
else
{
range = 0;
System.out.println("Error!");
}
return range;
}
**To promote your understanding it's up to you to find the average of the integers in the range!
Not really here to do your homework, but since I'm already here, the range is the difference between the largest and smallest number.
public int returnRange(int first, int second) {
if(first > second)
return first-second;
else
return second-first;
}
To make things easier though...
public double returnAverage(int...numbers) {
for(int i = 0; i < numbers.length(); i++) {
total += numbers;
}
return total/numbers.length();
}
public int returnRange(int...numbers) {
int holder = 0;
int highest;
int lowest;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] > holder) {
holder = numbers[i];
}
highest = holder;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] < holder) {
holder = numbers[i];
}
}
lowest = holder;
return highest-lowest;
}
Last 2 methods are un-tested, but from experience, should work fine. These methods have arrays for the parameters, so you can do as many numbers as you'd like.
In your main method check for -1 and return error when first value is greater than second
public double avgRange(int a, int b){
if(a>b){
return -1;
}
else{
double total=0;
for(int x=a; x<=b; x++){
total = total + x;
}
return total/(b-a+1);
}
}
the method should return the average of the integers in that range (inclusive).
You're asked to return the average of all integers in the range bounded by the two parameters.
For example, if parameters were 5 and 10, the method should return the average of 5, 6, 7, 8, 9, and 10, which is 7.5. (5 and 10 are included because the question says the range should be "inclusive".)
To find the average, use a for loop to sum each integer in the range, then divide by the number of integers.
Will I be using a floating point / double?
The return value should be a float or double, since the average isn't always a whole number.