It says 1 of 2 branches missed in java - java

I have 3 classes. I am trying to set a variable in the main method through an object called "main" and reuse that value by writing super.getnumberofsets(); in the for loop but it says "1 of 2 branches missed".
public static void main(){
//in the main method
//Main class maintain the private variables with their setters and getters.
Main main = new Main();
Sets sets = new Sets();
System.out.print("Enter how many sets you want to create: ");
newnumberofsets = in.nextInt();
main.set_numberofsets(newnumberofsets);
sets.setgroups();
sets.getgroups();
}
// in Sets class
protected void setgroups()
{
//In this loop it says "1 of 2 branches missed".
for(int x = 0; x<super.getnumberofsets();x++) {
main_zeroarray[x] = new Main0();
}
}
protected void getgroups() {
count = 1;
for(int x = 0 ;x < super.getnumberofsets();x++) {
System.out.println(count + ". Set " + setnames[x]);
count++;
}
}
I expected that the super keyword would read the same value from the object main.set_newnumberofsets(newnumberofsets);

The most likely explanation of there being a missed branch in the lopp is that that super.getnumberofsets() returns 0, so the loop terminating condition x < super.getnumberofsets() is false, thus the loop increment x++ is never executed, making it a "missed branch".

Related

Array will not update but rather print out the wrong array

I managed to figure out how to print the array for my connect four program but I cannot get the board to update with my code, I looked at it and ran it the code works in theory but however the array won't take the new inputs
Ive tried running it through with a for loop but that turned out wrong and I was thinking about putting the drop method in the print board method but I feel that that would result in an error
public class Connect4 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// DON'T MODIFY THE MAIN METHOD UNLESS FOR DEBUGGING
//MAKE SURE YOU GET RID OF YOUR MODIFICATIONS HERE BEFORE
SUBMISSION
String[][] board = createEmptyBoard();
Scanner input = new Scanner(System.in);
boolean bl = true;
printPattern(board);
while(bl) {
int player1 = 1 , player2 = 2 , userInput;
System.out.println("Please drop a RED disk at the column between 0
and 6:");
userInput = input.nextInt();
dropDisk(board, userInput , player1);
printPattern(board);
System.out.println("Please drop a YELLOW disk at the column
between 0 and 6:");
userInput = input.nextInt();
dropDisk(board, userInput , player2);
printPattern(board);
String win = checkWinner(board);
/*
Write code to announce if there is winner and end the game
*/
}
}
public static String[][] createEmptyBoard() {
/* This method prints the first empty pattern for the game
DON'T MODIFY THIS METHOD
*/
String[][] f = new String[7][15];
for (int i =0;i<f.length;i++) {
for (int j =0;j<f[i].length;j++) {
if (j% 2 == 0) f[i][j] ="|";
else f[i][j] = " ";
if (i==6) f[i][j]= "-";
}
}
return f;
} // end of createEmptyBoard
public static void printPattern(String[][] brd) {
for (int i = 0; i < 7; i++){
System.out.println(brd[i][0] + brd[i][1]+ brd[i][2]+ brd[i][3]+
brd[i][4]+ brd[i][5]+ brd[i][6]+ brd[i][7]+ brd[i][8]+ brd[i][9]+
brd[i][10]+ brd[i][11]+ brd[i][12]+ brd[i][13]+ brd[i][14]);
}
} // end of printPattern
public static void dropDisk(String[][] brd, int position, int
player) {
if (player == 1){
brd[6][position] = "R";
if(brd[6][position] == "R"){
brd[6][position] = brd[6 - 1][position];
}
}
else if (player == 2){
brd[6][position] = "Y";
if(brd[6][position] == "Y"){
brd[6][position] = brd[6 - 1][position];
}
}
/*Write your code to drop the disk at the position the user entered
depending on which player*/
} // end of dropDisk
The logic of dropDisk seems to be not finished yet.
It sets the brd[6][position] to R or Y, just to immediately after that set it to the current value of brd[5][position].
And this should always be null.
In Java, objects are passed into methods by value. This means that when you pass a parameter into a function, the JVM makes a copy of that object which can be modified in the method.
In this case, when you pass brd into dropDisk, it is copied, and you make changes to the copy inside dropDisk. But once dropDisk ends, that copy is discarded. No changes are made to the board from your main method. This is because your board is an array of Strings, and Strings are immutable, meaning that they cannot be changed after instantiation.
If you wanted the board from your main method to update, consider returning brd in dropDisk.

Why does my method return the wrong value?

Even though my method operationsNeeded prints the correct value for my return-int "count1", the very next line it returns something else to my main method. I did not include the rest of my code, if needed I'd gladly provide it.
For example if operationsNeeded is executed 4 times, count1 is on 4 which is printed out as well. But for reasons unknown to me the System.out.println("check: " +count1); Statement is executed 4 times like this:
check: 4
check: 4
check: 3
check: 2
I would expect my program to execute this only once and then continue to the return statement.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testcases = sc.nextInt();
int count =0;
while (count<testcases){
int numberOfColleagues = sc.nextInt();
sc.nextLine();
String startPieces = sc.nextLine();
int[] listOfcolleagues = listOfColleagues(numberOfColleagues, startPieces);
int count2 = operationsNeeded(listOfcolleagues, 1);
count++;
System.out.println(count2);
}
}
public static int operationsNeeded (int[] listOfColleagues, int count1){
//remove duplicates first
ArrayList<Integer> relevantList=removeDuplicatesAndSort(listOfColleagues);
System.out.println("relevantlist" + relevantList);
//check for smallestdelta & index
int [] deltaAndIndex = smallestDeltaHigherIndex(relevantList);
int delta = deltaAndIndex[0];
int index = deltaAndIndex[1];
if (delta==1){
for (int i=0;i<relevantList.size();i++){
if (i!=index){
relevantList.set(i,relevantList.get(i)+1);
}
}
}
if (delta>1 && delta<5){
for (int i=0;i<relevantList.size();i++){
if (i!=index){
relevantList.set(i,relevantList.get(i)+2);
}
}
}
if (delta>4){
for (int i=0;i<relevantList.size();i++){
if (i!=index){
relevantList.set(i,relevantList.get(i)+5);
}
}
}
System.out.println(count1);
int[] updatedList = new int[relevantList.size()];
for (int i=0; i<relevantList.size();i++){
updatedList[i]=relevantList.get(i);
}
if (!isAllTheSame(relevantList)) {
count1 +=1;
operationsNeeded(updatedList,count1);
}
System.out.println("check: " + count1);
return count1;
}
Your method is recursive. The "check: " line is printed on each level of that recursion, with the value that it currently has on that level. It first prints the "inner-most" value (4), than that of the level above (also 4), and finally hte value in the top-level, which is 2 after being incremented in the if above. And the value it returns is always the value from to top-level.
If you want to print it only once, you could print it on the inner-most level only, using else. However, that will still return the value from the top-level iteration; instead, keep track of the value returned from the recirsive call and update count1 accordingly.
if (! isAllTheSame(relevantList)) {
// we have to go deeper!
count1 = operationsNeeded(updatedList, count1 + 1);
} else {
// phew, finally done
System.out.println("check: " + count1);
}

multi-threading in Java working even without dekker/pterson's algorithm?

Yes, this is a homework assignment, but I have tried everything possible and can't come up with a possible. The point of this assignment is to illustrate that, before implementing the dekker's algorithm / peterson's algorithm, it is very likely that two processes will not go one after another.
import java.util.*;
public class myProcess
{
private static final Random R = new Random();
private int id;
public myProcess(int i){
id = i;
}
private static void delay(int value){
try{
java.lang.Thread.sleep(R.nextInt(value));
}
catch(InterruptedException e){
}
}
public void run(){
System.out.println("");
delay(20);
System.out.println(this.id + " is starting");
delay(20);
System.out.println("LINE ONE");
delay(20);
System.out.println("LINE TWO");
delay(20);
System.out.println("LINE THREE");
delay(20);
System.out.println(this.id+ " is ending ");
delay(20);
}
public static void main(String [] args){
final int N = 2;
myProcess[] t = new myProcess[N];
for(int i = 0; i < N; i++){
t[i] = new myProcess(i);
t[i].run();
}
}
Right now the output is
0 is starting
LINE ONE
LINE TWO
LINE THREE
0 is ending
1 is starting
LINE ONE
LINE TWO
LINE THREE
1 is ending
but it should be all mixed up to illustrate that processes don't necessarily wait for another one to finish.
I tried other methods of defining run() such as
String[] statements = new String[5];
statements[0] = "Thread " + this.id + " is starting iteration ";
statements[1] = "We hold these truths to be self-evident, that all men are created equal,";
statements[2] = "that they are endowed by their Creator with certain unalienable Rights,";
statements[3] = "that among these are Life, Liberty and the pursuit of Happiness.";
statements[4] = "Thread " + this.id+ " is done with iteration ";
for(int i = 0; i< 5; i++){
System.out.println(statements[i]);
delay(20);
}
but it still does not return to me any "wrong outputs"
What am I doing so wrong that's making the output so right?
You should call start() function on your thread, not run().
Edit: Also your class should implement Runnable interface or extend Thread class.
You are not creating new Threads in your code and everything is running in one thread.
public class myProcess extends Thread
...
for(int i = 0; i < N; i++){
t[i] = new myProcess(i);
t[i].start();
}
I would guess that your delays are too short to see any significant mixing. You pass in 20, as if it's 20 seconds, but it's only 20 milliseconds of sleep. Pass in 20,000 and see if you get the behavior you expect.
Change your delay method to look like the following. According to this post (https://stackoverflow.com/a/1600603/1265692), the Java sleep method is not guaranteed to relinquish control over the cpu. By adding the yield call, you remind Java to let other Threads run.
private static void delay(int value){
try{
java.lang.Thread.sleep(R.nextInt(value));
java.lang.Thread.yield();
}
catch(InterruptedException e){
}
}

Is this method thread safe?

Are these methods getNewId() & fetchIdsInReserve() thread safe ?
public final class IdManager {
private static final int NO_OF_USERIDS_TO_KEEP_IN_RESERVE = 200;
private static final AtomicInteger regstrdUserIdsCount_Cached = new AtomicInteger(100);
private static int noOfUserIdsInReserveCurrently = 0;
public static int getNewId(){
synchronized(IdManager.class){
if (noOfUserIdsInReserveCurrently <= 20)
fetchIdsInReserve();
noOfUserIdsInReserveCurrently--;
}
return regstrdUserIdsCount_Cached.incrementAndGet();
}
private static synchronized void fetchIdsInReserve(){
int reservedInDBTill = DBCountersReader.readCounterFromDB(....); // read column from DB
if (noOfUserIdsInReserveCurrently + regstrdUserIdsCount_Cached.get() != reservedInDBTill) throw new Exception("Unreserved ids alloted by app before reserving from DB");
if (DBUpdater.incrementCounter(....)) //if write back to DB is successful
noOfUserIdsInReserveCurrently += NO_OF_USERIDS_TO_KEEP_IN_RESERVE;
}
}
No.
If 21 threads comes in here
synchronized(IdManager.class){
if (noOfUserIdsInReserveCurrently <= 20)
fetchIdsInReserve();
noOfUserIdsInReserveCurrently--;
}
and wait while another 180 threads proceed through the top and through the line below, then by the time the 21st thread reaches the line below, there will be no user ids in reserve when the 21st thread from the first group calls
return regstrdUserIdsCount_Cached.incrementAndGet();
EDIT:
Here's the initial state on class load:
regstrdUserIdsCount_Cached = 100
noOfUserIdsInReserveCurrently = 0
Let's assume that the write back to the DB is always successful. If it isn't, this code is clearly broken, because it still allocates an ID in that case.
The first thread comes through, and calls fetch because there are no ids in reserve.
regstrdUserIdsCount_Cached = 100
noOfUserIdsInReserveCurrently = 0
assuming the DB returns 100 as the initial ID, after the method completes without contention
regstrdUserIdsCount_Cached = 101
noOfUserIdsInReserveCurrently = 199
Now, let's assume 178 more threads go through without contention
regstrdUserIdsCount_Cached = 279
noOfUserIdsInReserveCurrently = 21
if that thread is preempted by another that comes through after it exits the synchronized block but before it decrements the atomic int, the preempting thread will trigger a fetch.
Since noOfUserIdsInReserveCurrently has not been decremented by the thread that was pre-empted,
(noOfUserIdsInReserveCurrently + regstrdUserIdsCount_Cached.get() != reservedInDBTill)
will be false.
Assuming that exception indicates a failure mode, we have a failure during one interleaving that is not thrown during other-interleavings. Therefore, the code is not thread-safe.
The solution is to consistently access regstrdUserIdsCount_Cached inside the critical section. In that case, it need not be an atomic int, but can simply be a non-final int.
You the field noOfUserIdsInReserveCurrently is not accessed from anywhere else, then yes - access to it is thread-safe.
P.S. if fetchIdsInReserve is called only from inside the synchronized
block in the getNewId method, then you don't have to make the method synchronized.
UPDATE: as long as the question was edited, now it is not thread-safe. You have to have the return statement in the first method INSIDE the synchronized block. And it doesn't have to be an AtomicInteger, it can be just a simple int in this case.
Here is an example test to show it is thread safe. Replace the AtomicInteger with an int and get rid of the syncs and the test should fail.
public static void main(String... arg) throws Exception {
final int loops = 1042;
for (int l = 0; l != loops; l++) {
reset(); // add this method to your class to reset the counters
final int maxThreads = 113;
final ArrayList<String> checker = new ArrayList<String>();
final CountDownLatch cl1 = new CountDownLatch(maxThreads);
final CountDownLatch cl2 = new CountDownLatch(maxThreads);
for (int x = 0; x != maxThreads; x++) {
Thread thread = new Thread(new Runnable() {
public void run() {
cl1.countDown();
try {
cl1.await(); // stack all threads here
} catch (InterruptedException e) {
e.printStackTrace();
}
int id = getNewId();
synchronized(checker) {
checker.add("" + id);
}
cl2.countDown();
}
});
thread.start();
}
cl2.await();
for (int x = 0; x != maxThreads; x++) {
String key = "" + (101 + x); // 1st ID value
if (!checker.contains(key)) {
System.out.println("Checker 1 FAIL - missing id=" + key);
} else {
checker.remove(key);
if (checker.contains(key)) {
System.out.println("Checker 2 FAIL - extra id=" + key);
}
}
}
for (int x = 0; x != checker.size(); x++) {
String key = "" + (101 + x);
System.out.println("Checker 3 FAIL - extra id=" + key);
}
}
}

Why is my loop skipping this conditional?

Time for my daily newbie Java question :-D
I must not be understanding conditionals in a while loop correctly.
I have this:
while (true){
if (){
...
} else {
...
}
if (){
...
} else {
...
}
if (SENTINEL){
break;
}
}
The first if/else statement is working, and the sentinel is working, but the second if statement gets skipped. If I flip the first and second if statement, then the first if statement still always gets executed and skips the second. What am I missing?
Can I have two if/else statements in one block like this?
I'll include the whole code, though it's pretty ugly, and I'm sure I'll get lots of people telling me better ways of doing this. I don't mind learning better ways, but for now, I just want an answer to this looping question. thanks!
public class FindRange extends ConsoleProgram {
private static final int SENTINEL = 0;
int value = 0;
int highNumber = 0;
int latestValue = 0;
int lowNumber = 0;
public void run() {
addNumbers();
}
private void addNumbers(){
value = readInt("Enter number:");
while(true){
if (value == SENTINEL){
break;
}
latestValue = readInt("Enter number:");
getHighNumber();
getLowNumber();
if (latestValue == SENTINEL){
break;
}
}
println("High Number is "+highNumber+".");
println("Low Number is "+lowNumber+".");
}
private void getHighNumber(){
if (latestValue >= value){
highNumber = latestValue;
}else {
highNumber = value;
}
}
private void getLowNumber(){
if (latestValue <= value){
lowNumber = latestValue;
}else {
lowNumber = value;
}
}
}
Are you trying to find the minimum and maximum of a series of numbers? If so, you should definitely use Math.min() and Math.max(). It's much clearer that way and you can do away with the if statements. It's also simple enough to do it in the loop with local variables instead of fields.
The common idiom is something like this:
minValue = Math.min(minValue, candidateValue);
maxValue = Math.max(maxValue, candidatevalue);
It's possible that the behavior you're seeing comes from the fact that you are always comparing the latest value to the initial value. The initial value will never change-- so if you put in the following input:
20, 60, 50
the high value that gets reported would be 50. That's because 50 is the most recent value to be greater than 20. I think you probably mean to compare the latest value to the high value, no?
You can definitely have 2 if/else blocks within the loop; however if your sentinel gets hit the loop will exit.
Posting the entire block would help.
What will happen (after reading the posted code) is when any new value you enter within the loop is greater than the original value, lowNumber is set back to the original. So for example if your input is:
7 6 5 8
Your corresponding low number values will be:
7 6 5 7
Which is incorrect. What you could do is toast the "value" variable altogether, set your low and high to the original value, then compare latest with low and high in the get* methods.
Shouldn't you be setting value = latestValue at the bottom of your while loop?
Value never gets updated after the initial read... maybe something like this:
public class FindRange extends ConsoleProgram {
private static final int SENTINEL = 0;
public void run() {
addNumbers();
}
private void addNumbers() {
int value = 0;
// Set this to highest possible value
int highNumber = Integer.MIN_VALUE;
// Set this to lowest possible value
int lowNumber = Integer.MAX_VALUE;
while (true) {
value = readInt("Enter number:");
if (value == SENTINEL)
break;
lowNumber = Math.min(lowNumber, value);
highNumber = Math.max(highNumber, value);
}
println("High Number is " + Integer.toString(highNumber) + ".");
println("Low Number is " + Integer.toString(lowNumber) + ".");
}
}

Categories