Calculate total number of if-else clauses(including nested) - java

Need to calculate the number of if-else clauses. I'm using java parser to do it.
What I've done till now:
I've obtained the count of all if and else-if clauses by using the function
node.getChildNodesByType(IfStmt.class))
Problem:
How do I count the else clauses?
This function ignores the "else" clause.
Example:
if(condition)
{
if(condition 2)
//
else
}
else if(condition 3)
{
if (condition 4)
//
else
}
else
{
if(condition 5)
//
}
In this case, I'd want the answer to be 8 but the size of the call will return 5 because it encounters only 5 "if's" and ignores the else clauses. Is there any function that can directly help me count the else clauses?
My code:
public void visit(IfStmt n, Void arg)
{
System.out.println("Found an if statement # " + n.getBegin());
}
void process(Node node)
{
count=0;
for (Node child : node.getChildNodesByType(IfStmt.class))
{
count++;
visit((IfStmt)child,null);
}
}

This answer has been solved on the following github thread.
The in-built methods of the java parser are more than sufficient to help out.
Answer:
static int process(Node node) {
int complexity = 0;
for (IfStmt ifStmt : node.getChildNodesByType(IfStmt.class)) {
// We found an "if" - cool, add one.
complexity++;
printLine(ifStmt);
if (ifStmt.getElseStmt().isPresent()) {
// This "if" has an "else"
Statement elseStmt = ifStmt.getElseStmt().get();
if (elseStmt instanceof IfStmt) {
// it's an "else-if". We already count that by counting the "if" above.
} else {
// it's an "else-something". Add it.
complexity++;
printLine(elseStmt);
}
}
}
return complexity;
}

Related

Trying to get the code to check if there are even brackets

I am currently trying to come up with a code that will scan a string
and check to see if there is an even number of open and closing brackets on each line. If so, it would return true. (Excuse me for the incorrectness in formatting but I could not get the examples to properly take shape unless I identified it as code)
{} // The code would return true
{{}}
{}{}
{{{}{{}}}}
} // The code would return false
{}
}}{
{{{}{}
What I tried so far:
public boolean bracketsMatch(String brackets)
{
int lb = 0;
int rb = 0;
int i = 0;
while (brackets.charAt(i) == '{' || brackets.charAt(i) == '}' || brackets.charAt(i) == '')
{
if (brackets.charAt(i) == '{')
{
lb += 1;
}
if (brackets.charAt(i) == '}')
{
rb += 1;
}
if (brackets.charAt(i) == '')
{
if (lb / rb == 2)
{
// Is it possible to get the code scan the next line to next line?
// need an extra statement here for ^^ before I can place the if statement below
if (bracket.charAt(i + 1) == '')
{
return true;
}
}
else
{
return false;
}
}
i++
}
}
I apologize in advance for any experienced programmers as this would be an inefficient nightmare. I am relatively new to programming in general. I attempted to have the code check for the number of left brackets (lb) and right brackets (rb). Whenever the code came to an empty string, it would divide lb by rb. If the code did not equal 2, the code would return false. I probably have more than a dozen errors in this code, but I was wondering if there was any way to have the code go onto the next line to scan the next set of brackets. Thanks for any help in advance.
EDIT 1:
public boolean bracketsMatch(String brackets)
{
int balance = 0;
for (int i = 0; i < brackets.length(); i++)
{
char value = brackets.charAt(i);
if (value == '{')
{
balance += 1;
}
else if (value == '}')
{
balance -= 1;
}
}
if (balance != 0)
{
return false;
}
else
{
return true;
}
}
This won't compile, as '' is an invalid character literal:
if (brackets.charAt(i + 1) == '')
And your current approach of counting opening and closing brackets,
and checking the value of lb / rb won't yield the right result.
You don't need to count the right brackets. You only need to count the open brackets, and reduce that count as they get closed.
Here's a sketch of an algorithm you can use,
I hope to not spoil the exercise:
For each character in the string
If it's an open bracket, increment the count
If it's a close bracket
If the open count is 0, there's nothing to close, so they are not balanced, we can stop
Decrement the count
After all characters, if the open count is 0, the brackets are balanced
As an additional code review note, this is bad in many ways:
if (brackets.charAt(i) == '{') {
// ...
}
if (brackets.charAt(i) == '}') {
// ...
}
What's bad:
Calling brackets.charAt(i) repeatedly is unnecessary if the result will always be the same. Call it once and save the result in a variable.
The two if conditions are exclusive: if the first is true, the second won't be true, so it's pointless to evaluate it. The second condition should be if else instead of if. And instead of an if-else chain, a switch could be more interesting here.
Instead of calling the string brackets, it would be better to call it something more general. What if the actual input is "{something}"? Then it contains more than just brackets, but the algorithm would work just the same. Calling it brackets is misleading.
Alternative way to do
You can use Java Stack class [As it represent the List-In-First-Out stack of object].You can use the push and pop method of Stack class. Here is the implementation.
public class BracketMatching {
public static boolean bracketMatch(String input){
Stack<Character> st = new Stack<>();
for(char c : input.toCharArray()){
if( c == '{')
st.push(c);
else if(c == '}'){
if(st.isEmpty())
return false;
st.pop();
}
}
if(st.isEmpty())
return true;
return false;
}
public static void main(String[] args){
String input1 = "{}{{}}{}{}{{{}{{}}}}";
String input2 = "}{}}}{{{{}{}";
System.out.println(bracketMatch(input1));
System.out.println(bracketMatch(input2));
}
}

is this too much refactoring?

I try to refactor a code so that it will use separate methods to do some calculations. Just to make it clear.
What I want to know is, is it a good practice or a bad one to write a separate method to find out a simple thing like a number is odd or even ?
The original code is ,
int n = 11;
if (n % 2 == 0) {
System.out.println("Not selected");
} else {
boolean isPrime = true;
if (n == 0 || n == 1) {
isPrime = false;
} else {
int i = 2;
double a = Math.sqrt(Math.abs(n));
while (i <= a) {
if (n % i == 0) {
isPrime = false;
}
++i;
}
}
if(isPrime){
System.out.println("Prime it is");
}
}
The refactored code is,
int n = 11;
if (isEven(n)) {
System.out.println("Not selected");
} else {
if (isPrime(n)) {
System.out.println("Prime it is");
}
}
public static boolean isEven(int n) {
return n % 2 == 0 ? true : false;
}
public static boolean isPrime(int n){
if(n==0 || n==1)return false;
int i=2;
double a = Math.sqrt(Math.abs(n));
while(i<=a){
if(n%i==0){
return false;
}
++i;
}
return true;
}
It's generally considered good practice to break code down into separate methods for things like readability, length, or cyclomatic complexity, especially if you are not changing how the code works.
Boolean expressions, like what you have extracted, are often good choices for a quick extract function refactor. It allows a reader of the code base to know why a boolean expression is important or what it does by being able to read a descriptive function name versus complex domain related boolean math which they may not care to know the intricate details of.
A good book about commonly considered best practices in Java for code organization is a book called Clean Code. It's a pretty easy and enjoyable read, I would suggest it.
This is referred to as functional decomposition, and (in my opinion) is always good practice.
Not only is it easier to read, you can find problems in that code easier, since you can now easily test each section individually.
For example, you can now make sure isEven actually returns an even number. If a problem arises later on, you know that method is not the issue. This is called unit testing.
I suggest switching
if(isEven(n)) {
} else {
if(isPrime(n)) {
}
}
to
if(isEven(n)) {
} else if(isPrime(n)) {
}
Since it gives the same functionality, yet saves you a line.
Although, if you were counting 0 as being even, you wouldn't even need isPrime; if it's not even, it has to be prime. You wouldn't need to perform all the processing in isPrime:
if(isEven(n)) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
To make it a bit cleaner:
String result = isEven(n) ? "Even" : "Odd";
System.out.println(result);

Is it possible to write return statement in if block using java?

I want to return Vector according to if block but the code gives me the following error: Add return statement.
Is it possible to write return statement in if block?
public static int[] zeroVectorBinning1( ImageFloat32 angle,ImageFloat32 Magnitude )
{
for (int NumberOFChanks=0;NumberOFChanks<locations_original.size();NumberOFChanks++)
{
for(int i=0;i<angle.getHeight();i++)
for(int j=0;j<angle.getWidth();j++)
{
int orientaionVal=(int) angle.get(j, i);
if(orientaionVal<=0)
{int magnitudeVal=(int) Magnitude.get(j, i);
int[] Vector = new int[19];
Vector=zeroVector(19);
Vector[0]=magnitudeVal;
return Vector;
}
else if(orientaionVal<=20)
{int magnitudeVal=(int) Magnitude.get(j, i);
int[] Vector = new int[19];
Vector=zeroVector(19);
Vector[1]=magnitudeVal;
return Vector;
}
else(orientaionVal >= 0 && orientaionVal <=20)
{
int magnitudeVal=(int) Magnitude.get(j, i);
int[] Vector = new int[19];
Vector=zeroVector(19);
Vector[0]=magnitudeVal;
Vector[1]=magnitudeVal;
return Vector;
}
}
}
}
There's nothing wrong in having return statements in if blocks, but your method must have a return statement in any execution path.
Your for loops may never be executed (if, for example, locations_original.size() is 0), in which case none of the if blocks that contain the return statements will be reached. Therefore you must add a return statement following the loops.
Yes,
But your function still not return anything in the end, so you have to return something, even null.
So when you call this function, it should ne looking like this:
int[] fuctionResult = zeroVectorBinning1(....);
if (fuctionResult != null){
....
}
You could resolve this in two ways:
At the end either throw an exception just before completing the method.
Or at the end just return null.
Reason why compiler is complaining because, if locations_original.size() returns 0 then this method would never return anything which contradicts with what you said in your method that it will return an int array.
It is possible. But you need a return statement for every cases. Also if your for loop is never executed.
so add return null; at the end of your method.
Yes it is possible. Follow the code snippet for explanation.
public class TestSample {
public static void main(String... w){
int h = new TestSample().call();
System.out.println(h);
}
public int call(){
int j =0;
for(int i=0;i<10;i++){
if(i==5){
return i;
}
}
return j;
}
}
This prints 5.
public int getValue(){
final int value = 3;
if(value==1){
return 1;
}
else if(value==2){
return 2;
}
else if(value==3){
return 3;
}
else{
return -1;
}
// no return because "else" covers all cases
}
In this case you have an "else" at the end, so every case is covered. but if you leave the else ...
public int getValue(){
final int value = 3;
if(value==1){
return 1;
}
else if(value==2){
return 2;
}
else if(value==3){
return 3;
}
return -1;
// ... you have to return something at the end of the method, because value could be >3 or < 1 and the code under the last else if will be executed
}
The problem is your if/else-if/else parse is not complete, what does else with a condition like:
else(orientaionVal >= 0 && orientaionVal <=20)
mean? It's odd. Just omit the condition (orientaionVal >= 0 && orientaionVal <=20) of the last else sentence (and it's not logically correct when orientaionVal is 0 or 20), or there will be no default else in the scope.
When return in the scope of a if sentence, we must make sure that under any condition there is a return, so:
Make a default return out of the if-else scope
Or be sure that the condition judgement is complete and there is a return under any condition.
So
Correct:
if(condition){
return;
}
return;
Correct:
if(condition){
return;
}else if(anotherCondition){
return;
}else{
return;
}
Wrong:
if(condition){
return;
}
// no return ...
Wrong:
if(condition){
return;
}else if(anotherCodition){
return;
}
// no return ...

difference in else if {.. and else { if(

I recently got coursework back and was award 0 marks for some stupid reason and I checked someone in my classes and this is my code:
public static String take(String s, int n) {
while(true){
if(s.equals("")){
return "";
} else if(s.length() < n){
return s;
} else {
return s.substring(0,n);
}
but his is
public static String take(String s, int n) {
while (true) {
if (s.equals("")) {
return "";
} else {
if (s.length() < n) {
return s;
} else {
return s.substring(0, n);
}
}
}
}
I was wondering is there a difference in
else if{...}
and
else{
if{ }
}
Our code does EXACTLY the same..
No, there is no difference. You can do it either way.
There is technically no difference, it's a matter of code style.
But keep in mind that in case of multiple else if, you may end up with a messy indentation :
if(test1) {
...
} else {
if(test2) {
...
} else {
if(test3) {
...
} else {
if(test4) {
...
}
}
}
}
instead of the cleaner :
if(test1) {
...
} else if(test2) {
...
} else if(test3) {
...
} else if(test4) {
...
}
No, there is no difference at all in its working. But, you can have multiple else if blocks consecutively, but not multiple else blocks consecutively with if inside it
There is no difference.
You can do it in both ways.
In most cases I encourage people to use braces wherever they can; that is never to use:
if(x) y = z;
and always to use:
if(x) {
y = z;
}
However, "if else" is a solid idiom, so it's the exception to that rule:
if(x) {
...
} else if(y) {
...
} else {
...
}
... is well formatted code, and is equivalent to:
if(x) {
...
} else {
if(y) {
...
} else {
...
}
}
... which is messier, and has scope for misplaced braces which change the logic.
else if has no special meaning in Java. It's an else part whose statement is an if statement; and one must take into account that since the else part is not a block enclosed in curly braces, the else part has only one statement. So you could indent your example like this, to see it more clearly:
if(s.equals("")){
return "";
} else
if(s.length() < n){
return s;
} else {
return s.substring(0,n);
}
while the other example looks like
if (s.equals("")) {
return "";
} else {
if (s.length() < n) { // the second if statement starts here
return s;
} else {
return s.substring(0, n);
} // the second if statement ends here
}
which is just the same, except for the extra braces around the second if statement.
But although else if is not special, as others have said, it's common enough that programmers follow different indentation and { } conventions when using it, especially since sometimes there can be many of them chained together. (In fact, in languages like Perl that don't allow else if without a curly brace after the else, or Ada which requires end if at the end of each if, the idiom is so indispensable that they added a special keyword elsif to allow programmers to use it.)
No there is no difference technically but good practice to use else if {}

How to fix this infinite loop?

I put in system print outs to see where the problem was, and 2 and 7 were the two that kept repeating in the infinite loop. This part of the code is suppose to search a list and find the match that the user puts in, but every time i use the search the GUI freezes or is stuck in an infinite loop. Can anyone help me fix this ?
Here is the code i have:
if (whichOne.equals("Search"))
{
System.out.println("1");
String[] results = new String [5];
int count = 1;
list.moveCursorToRear();
int last = list.cursor;
list.resetCursor();
while(list.hasNext() || list.cursor == last)
{
int found = list.search(searchField.getText());
String result = list.spaces[found].getData();
System.out.println("2");
if(current != found)
{
list.stepCursorBack();
System.out.println("3");
if(list.cursor == list.head)
{
results[count] = result;
System.out.println(results[count]);
list.spaces[current].setLink(list.spaces[found].getLink());
count++;
System.out.println("4");
}
else
{
results[count] = result;
System.out.println(results[count]);
list.spaces[current].setLink(list.spaces[list.cursor].getLink());
count++;
System.out.println("5");
}
list.getNext();
System.out.println("6");
}
else
{
//break;
//System.exit(0);
list.hasNext();
System.out.println("7");
}
}
else
{
//break;
//System.exit(0);
list.hasNext();
System.out.println("7");
}
I suspect you wanted list.getNext() here, and not hasNext().
However, without more code - and especially more information about this list, a definite answer might be impossible to be given.

Categories

Resources