Finding everything that affects a variable - java

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

Related

Variable initialized but not recognized?

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.

Junit did not show any results using IntelliJ for UCB cs61B (org.junit.Assert.assertArrayEquals() )

I am studying CS61B - UCB on my own, and I am a beginner in using IntelliJ and Junit4.12. I found there is no result for my org.junit.Assert.assertArrayEquals()
while in the video there is something shows like this
in the Run Window.
Here is the code for TestSort.java
import static org.junit.Assert.*;
import org.junit.Test;
/** Tests the the Sort class. */
public class TestSort {
/** Test the Sort.sort method. */
#Test
public void testSort() {
String[] input = {"i", "have", "an", "egg"};
String[] expected = {"an", "egg", "have", "i"};
Sort.sort(input);
if (input != expected)
{
System.out.println("something wrong!");
}
org.junit.Assert.assertArrayEquals(expected, input);
}
#Test
public void testFindSmallest() {
String[] input = {"i", "have", "an", "egg"};
int expected = 2;
int actual = Sort.findSmallest(input, 0);
assertEquals(expected, actual);
String[] input2 = {"there", "are", "many", "pigs"};
int expected2 = 2;
int actual2 = Sort.findSmallest(input2, 2);
assertEquals(expected2, actual2);
}
#Test
public void testSwap() {
String[] input = {"i", "have", "an", "egg"};
int a = 0;
int b = 2;
String[] expected = {"an", "have", "i", "egg"};
Sort.swap(input, a, b);
assertArrayEquals(expected, input);
}
}
Here is the code for Sort.java
public class Sort {
public static void sort(String[] x) {
sort(x, 0);
}
private static void sort(String[] x, int start) {
if (start == x.length) {
return;
}
int smallestIndex = findSmallest(x, start);
swap(x, start, smallestIndex);
sort(x, start + 1);
}
public static void swap(String[] x, int a, int b) {
String temp = x[a];
x[a] = x[b];
x[b] = temp;
}
public static int findSmallest(String[] x, int start) {
int smallestIndex = start;
for (int i = start; i < x.length; i += 1) {
int cmp = x[i].compareTo(x[smallestIndex]);
if (cmp < 0) {
smallestIndex = i;
}
}
return smallestIndex;
}
}
I think the function for Junit is to get the green part which shows how my codes work and get the result of whether two of my Strings are equal or not.
Another question about the IntelliJ is whether there is any difference between I RUN it and using the terminal to compile and operate it? Because when I use terminal, it will show something like this
enter image description here
I have googled a lot about this, it always said like I did not applied the Junit.jar into classpath. I have checked I have added the library.enter image description here
fyi, the you can get the library here enter link description here
I debugged the testSort function and it goes well for the input part and the sort functions part. while it gives me the hint that enter image description here, I chosed Download, it showed sources not found enter image description here, and when I chose sources from exist files enter image description here, it keeps attaching....How can I solve this problem?
You're code may not be running as you expected, but it is running exactly as a more experienced Java dev would expect. Let me explain...
You've discovered the behavior of the = operator (or more precisely in this case, !=) that often trips up less experienced Java engineers. The = operator doesn't know how to work with arrays so it falls back to comparing references. In your case it is comparing input and expected to see if they reference the exact same object. In your code both input and expected are declared as new arrays and therefor are different, individual objects; they do not reference the same object.
As for assertArrayEquals it likely doesn't use the = operator at all. While I haven't looked at the source code for that method I'd venture to guess that it first checks reference equality (are they both referencing the same object, then checks to see if they are both arrays and then checks to see whether each element of expected is also in input.
Arrays can add to the equality confusion because there are many definitions of equality. Equality could be defined as...
both arrays having the same number of elements in the same order
both arrays having the same number of elements, but different order
one array having 5 elements while the other having 10 elements where all 5 elements of the first array are also in the second array
etc.
One suggestion I have that might help you better understand this issue (as well as many more issues you are likely to face in the future) is to look at the source code of the method that's not working as you expect it to work, assertArrayEquals in this case. IntelliJ allows you to navigate to the source code, or if the source code is not available, look at the decompiled byte code. On a Mac just Command-click on the method. In Windows it might be Control-click??? (sorry, IntelliJ has so many different shortcut sets I can't be more specific.)
Further info on this topic...
What is the difference between == vs equals() in Java?
https://javabeginnerstutorial.com/core-java-tutorial/java-equals-method-vs-operator/

Why are variable not recognised from inside for-statements?

What I am trying to do is create an array that pulls even numbers from another array. I'm not sure if I have gone about it the right way. I've look for ways of returning from statements like you would functions/methods and I can't find anything, not even sure if it is possible.
Anyway, the issue I am having here is the 'return evenArray' below 'cannot find symbol.' I am not sure what this means?
public static int[] getEvenArray(int[] array)
{
int dividedBy = 2;
int evenElement;
int evenCount = 0;
for(int i = 0; i < array.length; i++)
{
int[] evenArray;
evenElement = array[i] % dividedBy;
if(evenElement == 0)
{
evenCount++;
}
else
{
array[i] = 0;
}
evenArray = new int[evenCount];
for(int x = 0; x < evenArray.length; x++)
{
if(array[i] != 0)
{
evenArray[x] = array[i];
}
}
}
return evenArray;
}
This is for a tutorial from one of my lectures, it's a little bit challenging to say the least :-)0
evenArray is defined within the scope of the for loop. (Actually a little worse than that; you're redeclaring it on each iteration so discarding the previous contents).
So once you're outside the for loop you can't refer to it.
Quickest fix is to use a std::vector<int> for this type, and declare it at the start of the function. Also change the return type of the function to the same. Don't forget to size the vector appropriately.
(Moving on, a smart lecturer will ask you about returning a std::vector which could potentially take a deep copy of that vector. Pre C++11 you'd mention return value optimisation, now you can talk about r-value references. No deep copy will be taken since the move constructor will be used).
Variable declared inside a block is not visible outside of it; move this int[] evenArray; to very start of function.

Checking Left/Right in an int array for Tetris, Android/Java

I'm trying to make a tetris game for android to help learn game programming for android. My goLeft/Rights break right when the button is pressed, the code for going left is in a class separate of the fields int array, and the list parts array. The fields array is accessed by a referenced variable (TetrisWorld tetrisworld;). While part list array is public so accessed through a variable(part) code for which is in the goLeft() code. It breaks at: if(tetrisworld.fields[x][part.y] != 0) Code for left:
public void goLeft() {
int x = 0;
for(int i = 0; i < 4; i++) {
TetrisParts part = parts.get(i);
x = part.x - 1;
if(tetrisworld.fields[x][part.y] != 0) {
noleft = true;
break;
}
}
if(noleft == false) {
for(int i = 0; i < 4; i++) {
TetrisParts part = parts.get(i);
part.x--;
}
}
}
The code for the fields int array:
int fields[][] = new int[WORLD_WIDTH][WORLD_HEIGHT];
WORLD_WIDTH and WORLD_HEIGHT are both static final ints, width being 9 and height being 19
I've tried putting if(tetrisworld.fields[0][0] == 0) and it still crashes so I don't think it has to do with the variables. Also It doesn't go out of bound even if I haven't added the code to check for that yet because I have the teroid spawning around x = 5 and since I can't go left/right once there's not a chance of that happening
I've tried moving the goLeft/Right methods to the gamescreen class which has a "world = TetrisWorld();" and it still bugs out at the same spot
UPDATE:
Ok just adding:
tetrisworld != null
to the first if statement fixed it, my question now is, why did it fix it? Why can't I move without this check? It clearly isn't null cause as far as I know; it's fully responsive now.
But an easier way to have solved this which is SOOOO easy is changing fields to static... then access it lika so: TetrisWorld.fields so my updated code is:
public void goLeft()
{
noleft = false;
for (int i = 0; i < 4; i++)
{
part = parts.get(i);
if (part.x - 1 < 0 || TetrisWorld.fields[part.x - 1][part.y] != 0)
{
noleft = true;
break;
}
}
if (noleft == false)
{
for (int i = 0; i < 4; i++)
{
part = parts.get(i);
part.x--;
}
}
}
Looks like you are hitting IndexOutOfBoundsException.
When you are doing x = part.x - 1;, your x variable can become lesser tan zero, thus your code will act like if(tetrisworld.fields[-1][part.y] != 0
It looks like you're getting a java.lang.NullPointerException when trying to access the array in tetrisworld. In the line you mention there are several ways that this could occur:
if(tetrisworld.fields[x][part.y] != 0) {
tetrisworld could be null.
The fields member of tetrisworld could be null.
The second array that you're looking up by using tetrisworld.fields[x].
The value of part could be null.
Having a quick look through your source code it looks to me like you never initialise tetrisworld, either at declaration using:
TetrisWorld tetrisworld = new TetrisWorld();
Or at some other point which is certain to have happened before your goLeft() method is called.
Ok I believe I found the answer, referencing: http://en.wikipedia.org/wiki/Null_Object_pattern
Apparently java will throw an NPE if you don't check for it first if you have a null reference? Is there any way to initialize it without doing a TetrisWorld tetrisworld = new TetrisWorld(); because it's already created in a different class so i get a thousand errors, an actual stack overflow! lul... Still not 100% positive. Please comment to verify and possibly suggest a better way to go about this.

Why do I get this compile error in Java?

I get the following error:
quicksort(int[],int,int)cannot be applied to(int[])
When I compile this:
import java.util.*;
public class Sort {
public static void main(String[] args){
Random rand = new Random();
int[] tab = new int[10];
for(int i = 0; i < tab.length; i++) {
tab[i] = rand.nextInt(100);
System.out.println("Before: ");
show(tab);
quicksort (tab);
System.out.println("After: ");
show(tab);
}
}
static void quicksort(int tab[], int x, int y) {
int i,j,v,temp;
i=x;
j=y;
v=tab[(x+y) / 2];
do {
while (tab[i]<v)
i++;
while (v<tab[j])
j--;
if (i<=j) {
temp=tab[i];
tab[i]=tab[j];
tab[j]=temp;
i++;
j--;
}
}
while (i<=j);
if (x<j)
quicksort(tab,x,j);
if (i<y)
quicksort(tab,i,y);
}
static void show (int tab[]) {
for (int i = 0; i <tab.length; i++) {
System.out.println(tab[i]);
}
}
}
What am I doing wrong?
Just after the line to print out "before", you have:
quicksort (tab);
The function you designed needs three arguments. You can either add the extra arguments:
quicksort (tab, 0, tab.length - 1)
Or add a new function such as:
public quicksort(int[]) {
quicksort(tab, 0, tab.length - 1);
}
the function "quicksort" that you define asks for 3 parameters, but you are only providing one.
Because your quicksort function has 3 parameters, but your call gives only one.
Edit: second :(
your code should call
quicksort (tab,0,10);
In your outer calll, so you can sort the list.
Without knowing what you're writing code in, I strongly recommend using an IDE if you haven't adopted one already. Particularly Eclipse for Java.
Eclipse would underline the offending line of code and make some suggestions to you, (in addition to offering code completion). A text editor, like JEdit does not.
Note: I've been told IntelliJ is good, but you can't beat Eclipse's price (free).
BTW: You could just use Arrays.sort() which is a built in function. You wouldn't write a function like this in real life. (only as homework)

Categories