Variable initialized but not recognized? - java

Hey I am a high school and I found the solution to my problem but confused on why it's doing what it's doing can someone explain? Also I tried looking for the answer but couldn't find it so sorry if someone's already answered this.
So at getAverage() I state int i; and initialize it in the foreach loop but when it runs it says "variable i might not have been initialized"? I found the solution to this was just make int i = 0; but i'm confused because I know you can state a variable and not initialize it at that time as long as you initialize it later. So what makes this so special?
public class ArrayAverage
{
private int[] values;
public ArrayAverage(int[] theValues)
{
values = theValues;
}
public double getAverage()
{
// Problem here
int i; // Solution: int i = 0;
for(int value : values){
i += value;
}
double avg = (double)i / values.length;
return avg;
}
}
// This pseudo code code has nothing to do with above code
// but is example of what I know can be done but isn't
int i;
i = 10;
System.out.println(i);
//Output would be 10

The issue is that the you're adding the variable i to itself, and another value. However, the initial value for i has not been defined in the previous code. This is the reason that i = 0 would make the code work, as the program now understands that for the first loop, it has to add the value to 0, then the second loop will know to add the previous value, to the new value.
Hope this helped.

Related

Cant find the mistake

The task was to write a method to return the least value of an array.
Would someone quickly look over my code?
public static int findMinimum (int [] array) {
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
for (int zwiebel= 0; zwiebel < array.length; zwiebel ++) {
if (array [zwiebel] < array [kohlrabi]) {
kohlrabi = zwiebel -1;
break;
}
int spinat = array [kohlrabi];
if (zwiebel == array.length-1) {
return spinat;
}
}
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: This method must return a result of type int
at Abgabe7.ArrayExercises.findMinimum(ArrayExercises.java:38)
It's a homework for my school and I definitely understood the logic behind it but cannot find my fault.
Thanks Max
I don't think you need to have two loops. One loop would work.
Simply loop though the array keeping a variable which is the lowest you've found.
You should declare a global variable before the loop then use only one for loop in your code as follows:
int zwiebel= 0;
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
if (kohlrabi == 0){
zwiebel = array[kohlrabi];
}
if (array[kohlrabi] < zwiebel) {
zwiebel = array[kohlrabi];
}
}
The lowest value in your array is now stored in the variable zwiebel.
The real mistake is that you are not taking the possibility of an empty array into account. One thing to learn in programming is to think of all possibilities (maybe you’ve discovered that already). An array in Java (and most other languages) can have length 0, that is, have no elements in it. When array.length is 0, your outer for loop doesn’t execute, so we get down to the bottom of the method without having returned anything and without having anything to return.
Java is dumb, but nevertheless smart enough to discover this problem for you. When your method is declared to return an int, it insists that it too can see that it will return an int in all cases. In your method it cannot, which is what the following message is trying to tell you:
This method must return a result of type int
One possible fix — and I may be showing you something that you haven’t learned in school yet — is to insert the following statement in the end of your method:
throw new IllegalArgumentException("Cannot find the minimum of an empty array");
Throwing an exception is an alternative to returning a value, so this statement will make Java happy. If you actually try to find the minimum of an empty array, your program will crash and give you the message “Cannot find the minimum of an empty array”. But finding the minimum of an array that has numbers in it should work now.
That said the others are correct: Your way of finding the minimum is overly complex. I have been staring at your code and still have not understood how it works. Such code is not good. In real life you will be writing code that others will need to read and change after you, and no one can change code they don’t understand, so your code would not be useful. More important than writing code that works correctly is writing readable code.
Edit: There are variations on how to do this in a simple way. For a school exercise using a for loop I would write:
public static int findMinimum (int [] array) {
if (array.length == 0) {
return 42; // or whichever value is desired in this case
}
int niedrichsteSoWeit = array[0];
for (int index = 1; index < array.length; index++) {
if (array[index] < niedrichsteSoWeit) {
niedrichsteSoWeit = array[index];
}
}
return niedrichsteSoWeit;
}
For production code I probably would not write a method but use the built-in functionality, for example:
IntStream.of(myIntArray)
.min()
.ifPresentOrElse(min -> {
// do something with min
}, () -> {
// do whatever you want to do when the array is empty
});
Don’t worry if you don’t understand a bit of this snippet. It’s mostly for more experienced programmers who might happen to read this answer.

Finding everything that affects a variable

I'm trying to make a program that will read in a class file and if you give it a variable for example you give it "i" in the following example:
public class Example {
public static void main( String[] args) {
int i = 1;
int j = 5;
int k = 2;
i = i + k;
System.out.println(i);
}
}
Then my program will return
int i = 1;
int k = 2;
i = i + k;
System.out.println(i);
Since these are variables that affect i.
I'm not sure how to do this. So far I've tried using javaparser which takes in the file and finds all the VariableDeclarationExpr using a visitor pattern. However, this won't print out the bottom two cases in the code above.
Can anyone give me any hints to how to find them?
The VariableDeclarationExpr represents only declarations (like in your case int i = 1;). But the other two statements in your code are not declarations. They are assignments (probably AssignmentExpr) and a method call (probably MethodCallExpr). So I would first think about where the variable i can appear and then cover all the cases individually. I hope that helps

Accessing array in a return method

Good evening people,
I have a method that creates, populates, and returns an array to the function call as so:
public double[] getTotalDistances(){
double[] distance;
distance = new double[3];
for(Activity r: diary ){
if(r instanceof Run){
distance[0] += r.getDistance();
}
}
return distance;
}
and i can't seem to find a way to access this returned array to print it out in the main method, i have tried this: (where m is the object i have instantiated)
for(int i = 0; i< m.getTotalDistances().length; i++){
System.out.println(m.getTotalDistances().distance[i]);
}
this says it cannot find the variable distance.
i am aware that i can do something like:
for(double i: m.getTotalDistances()){
System.out.println(i);
}
this will print out the returned array, however, i would like to know how to do it in the "classic" way.I know that this must be extremely novice, but i couldn't find an answer. Any kind of help will be greatly appreciated.
It should be m.getTotalDistances()[i] and not m.getTotalDistances().distance[i]
Use a variable to store it before iterating.
double[] distance = m.getTotalDistances();
for(int i = 0; i < distance.length; i++){
System.out.println(distance[i]);
}
Your approach would call your getTotalDistances() method over and over inside the loop. You only need it once to work with.
You get this error
this says it cannot find the variable distance.
because the variable distance is only known in the scope of your method getTotalDistances() and thus you cannot use it outside of that (and it wouldn't make sense either).
The way it is written, distance is not defined. You will need to create a pointer the the returned value if you want to reference it.
double[] distance = getTotalDistances();
for(int i = 0; i < distance.length; i++) {
System.out.println(distance[i]);
}
Also, as it is written, any values other than the first will always be 0, and an accumulator makes more sense.
Another thing to note is that, as it is written, getTotalDistances() will run twice on each iteration of your for loop; once for the condition and again for the println(). If you were to scale this concept to a larger use case, the performance implications would be huge.

I know I am getting a stackoverflow because I am using recursion but is there an easy way to get round this?

I want to add an image to an ImageButton depending on a number between 0 and 10. My getNumber method is:
public int getNumber(){
// get a random number between 0 and 10
Random randomNumber = new Random();
num = randomNumber.nextInt(10);
return num;
}
I want every image to be unique but the problem I was having was that if numList did contain num it just would leave the button blank. I've tried to call permuteButton again recursively until num is not contained within my list but this does not seem to work.
public void permuteButton(ImageButton btn){
getNumber();
for(int i=0; i<=numList.size(); i++){
//check if the number is already being used
if( numList.contains(num) ){
permuteButton(btn);
}
// else the list doesnt have the number so assign the picture and add number to list
else{
numList.add(num);
assignPictures(btn);
}
}
}
Any help would be appreciated. I'm sorry if this is a simple question.
There are various things wrong with this code:
It would be better to have a single instance of Random instead of creating a new instance on each call to getNumber()
Rather than changing an instance variable within getNumber(), it would be sensible to just return the value and assign that to a local variable in permuteButton
Instead of recursion, you could use a while loop in permuteButton:
int num = getNumber();
while (numList.contains(num)) {
num = getNumber();
}
numList.add(num);
assignPictures(btn); // Presumably you'd now want to pass in num too
It would probably be a better idea to just shuffle the list to start with, create a Queue from it, then you can just take an item from the queue each time you need one. (This would also make it very easy to spot when you've used them all)
My answer is similar to the last suggestion from Jon Skeet.
// might be more than 10 ImageButtons, with only 10 images
for (ImageButton imageButton : imageButtons)
imageButton.putImage(randomImage.next());
...
public class RandomImage {
private final List<Image> shuffledImages;
private int currentIndex;
public RandomImage(List<Image> images) {
shuffledImages = new ArrayList<>(images.size());
shuffledImages.addAll(images);
currentIndex = -1;
}
public Image next() {
currentIndex++;
if (currentIndex % shuffledImages.size() == 0) {
currentIndex = 0;
Collections.shuffle(shuffledImages);
}
return shuffledImages[currentIndex];
}
}

Removing a chromosome from a population?

I am trying to write a method to remove a chromosome from my population. The method I have written is below. I am getting an out of bounds error when I run the code. Population is constructed with an ArrayList. The getChromosomeFitness method returns an int value score. Can someone spot my error?
void removeWorst()
{
int worst = population.get(0).getChromosomeFitness();
int temp = 0;
for(int i = 1; i < population.size(); i++)
{
if (population.get(i).getChromosomeFitness() < population.get(worst).getChromosomeFitness())
{
worst = population.get(i).getChromosomeFitness();
temp = i;
}
}
Chromosome x = population.get(temp);
population.remove(x);
}
You should probably change
if (population.get(i).getChromosomeFitness() < population.get(worst).getChromosomeFitness())
to
if (population.get(i).getChromosomeFitness() < worst)
You don't assure that in this line population has an element with the index 0:
int worst= population.get(0).getChromosomeFitness();
Try to add this to your method:
void removeWorst() {
if (population.isEmpty()) {
return;
}
...
There are several potential problems in your code:
int worst= population.get(0).getChromosomeFitness();
you need to make sure that population.isEmpty() is false
population.get(worst).getChromosomeFitness()
same thing, you need to make sure that (worst >= 0 && worst < population.size()).
The issue seems that you are getting the actual fitness rather than the object itself. The issue is with this line: int worst= population.get(0).getChromosomeFitness();. This is returning an integer value which is not related to the List's dimensions, as you said, it is the fitness of the chromozome, which could be well over the size of the list.
This should solve the problem:
void removeWorst()
{
int temp=0;
for(int i=1; i <population.size();i++)
{
if (population.get(i).getChromosomeFitness() < population.get(temp).getChromosomeFitness())
{
temp=i;
}
}
Chromosome x= population.get(temp);
population.remove(x);
}
That being said, a probably neater way of doing this would be to use a custom comparator to sort the list and then simply remove the last element.
Make sure population has something in it before trying to remove something from it?

Categories