I am not experienced in Java, but I need to create Java snippet node in KNIME.
I am trying to write a short Loop that creates a counter/iterator based on a specific condition. I managed to write the IF THEN ELSE part but I wonder how to put it inside the Loop:
out_user_session_counter = 1;
if (c_session_end.equals("session end")) {
out_user_session_counter = out_user_session_counter + 1;
} else {
out_user_session_counter = out_user_session_counter + 0;
}
The idea is: each time c_session_end.equals("session end")
then out_user_session_counter should be augmented by 1
UPD.: Here is screenshot of data model with loop result (not correct result):
Correct expected result would be 1 1 1 1 2 2 3 3 3 3 3
instead of 1 1 1 1 11 1 11 1 1 1 1
You need the loop counter to persist between rows in the Java Snippet. To do that, you define it in the //Your custom variables: part of the snippet:
int sessionCounter=0;
Then in the //Enter you code here: part:
if("session end".equalsIgnoreCase(c_column2)){
sessionCounter++;
}
out_user_session_counter = sessionCounter;
As shown, the row with 'session end' will contain the incremented counter. If you want it to contain the old counter, change the snippet so that the final line above is before the if statement.
You don't need to put this in a loop in KNIME - the expression part of the snippet is already calculated sequentially for each input row. Shown below in the snippet dialog for clarity
You need to work with for/while loops to achieve that.
int out_user_session_counter = 1; //Step 1
while(c_session_end.equals("session_end")) { //Step 2
out_user_session_counter++; //Step 3
//Step 4 Other code to modify c_session_end.equals("session_end")
}
Step 1. In this step we initialize the variable to 1
Step 2. While the variable is equal to session_end
Step 3. increment the variable by 1 ( note that this is the same as out_user_session_counter = out_user_session_counter + 1; )
Step 4. Code to modify the c_session_end value must be placed so loop exits as some point or the loop will never stop.
What happens in your code is the following => if(c_session_end.equals("session end")) increment the variable by one, otherwise increment it with 0.
If you want it to run multiple times you have to use while or for loops.
You need a simple loop and this will take care of your else part itself.
int out_user_session_counter = 1;
while(c_session_end.equals("session end")){
out_user_session_counter++;
}
Hope this helps.
Well, we don't know what you are looping, but I assume you are looping some Strings.
This example shows how to loop a List<String> containing session events while counting the ones that equal "session end":
public static void main(String[] args) {
// create a data structure for sample data
List<String> sessionEvents = new ArrayList<String>();
// add some sample data
sessionEvents.add("session start");
sessionEvents.add("session somthing");
sessionEvents.add("session end");
sessionEvents.add("session start");
sessionEvents.add("session something");
sessionEvents.add("session something");
sessionEvents.add("session something");
sessionEvents.add("session end");
sessionEvents.add("session start");
sessionEvents.add("session something");
sessionEvents.add("session end");
// define a counter variable (considering Java naming conventions)
int outSessionCounter = 0;
// use an enhanced for loop (aka for-each loop)
for (String sessionEvent : sessionEvents) {
// every time the event is "session end"...
if (sessionEvent.equals("session end")) {
// ... increment the counter
outSessionCounter++;
}
}
// print the result
System.out.println("Amount of session ends is " + outSessionCounter);
}
This just counts occurrences of "session end", but you would have to tell us if you are using a different data structure or maybe even a stream.
Im not exactly sure what you're trying to achieve, but I think I have something
class Result{
public int out_user_session_counter = 1;
public String c_session_end;
}
Result r = new Result();
r.c_session_end = /*[whatever you want it to be];*/ "";
Thread thread = (new Thread(new Runnable() {
int out_user_session_counter = 1;
public void run() {
out_user_session_counter = 1;
while (!Thread.interrupted()) {
if (r.c_session_end.equals("session end")) {
out_user_session_counter++;
r.out_user_session_counter = out_user_session_counter;
}
//code to modify the r.c_session_end
}
}
}));
thread.start();
//to get the result do
int result = r.out_user_session_counter;
this will keep looping indefinitely.(this can go within a method)
you can edit the result object to influence the
Try something like this:
out_user_session_counter = 1;
int loopCycles = 10
for(int i = 0; i < loopCycles; i++){
if (c_session_end.equals("session end")) {
out_user_session_counter = out_user_session_counter + 1;
}
}
You can simply do something like:
out_user_session_counter = 1;
int loop_counter =0;
int rows = 10 //or some other variable that contains the number of rows
while(loop_counter < rows) {
if (c_session_end.equals("session end")) {
out_user_session_counter = out_user_session_counter++;
loop_counter++;
}
System.out.println(out_user_session_counter);
}
All you need to do is add a loop to the outer portion of you code. Any loop will do, I used a while loop. You could use a for loop as well.
for(int i = 0; ii < rows; ii++){
if (c_session_end.equals("session end")) {
out_user_session_counter = out_user_session_counter++;
}
System.out.println(out_user_session_counter);
}
Or, you can use a do-while loop:
int index = 0;
do{
if (c_session_end.equals("session end")) {
out_user_session_counter = out_user_session_counter++;
index++;
}
System.out.println(out_user_session_counter);
} while (index < rows);
It should be noted that with the do-while loop, you will alway enter the loop, even if there are no rows available (the rows are 0).
Also, you don't need the else portion, as there is no point in adding 0 to your value, you can simply skip it.
Related
I am Beginner practicing java with bluej and trying to print the next element every time I use the getNext() method . I tried some options but they didn't work and now I am stuck . Here is my code:
public void getNextQuestion()
{
int counter = 0;
Iterator<Questions> it = this.questions.iterator();
while(it.hasNext())
{
counter = counter + 1;
Questions nextObject = it.next();
System.out.println(counter+ ". " + nextObject.getDescription());
}
}
I am guessing you only want to print one question whenever getNextQuestion is called. In that case, you need to do this:
public class MyClass {
int counter = 0;
public void getNextQuestion()
{
Questions nextObject = questions.get(counter);
counter = counter + 1;
// If counter gets to the end of the list, start from the beginning.
if(counter >= questions.size())
counter = 0;
System.out.println(counter+ ". " + nextObject.getDescription());
}
}
As you can see, counter is now a global variable inside whaever class contains the method, and you don't need the iterator at all.
Sorry I am having a mental block, can anyone see why I get the 'cannot convert from int to boolean' error message. Much appreciated
public static void main (String[]args) {
int max=10;
int sum=0;
int count=0;
for(int counter=0;counter=max-4;counter++) {
sum=max-4;
count=max-3;
for(sum=3;sum<5;sum++) {
if(count==0 && max>0){
System.out.println("Hello");
} else if (count<4) {
System.out.println("Go for it");
} else {
System.out.println("OK");
}
}
}
sum=sum+count;
System.out.println("Total = "+sum);
System.out.println("Max = "+count);
}
I feel like I have checked using the '==' for the if condition.
= is assignment, you need a comparison in the second term of your loop.
for(int counter=0;counter=max-4;counter++) {
should be
for (int counter = 0; counter < max - 4; counter++) {
(white space added, but note < is a comparison... perhaps you wanted <=).
In case of Java, the syntax of for loop is
for(initialization; Boolean_expression; update) {
// Statements
}
1) The initialization part executes only once when the flow enters the for loop for the first time
2) Next, the boolean expression is resolved according to the condition
3) Then next the update statement is resolved and after execution of the body of the for loop again the flow goes to the boolean expression and then update statement and the flow goes on.
So, In your program instead of a boolean expression, you have used an assignment operator which turns out to be 6 which is not 0 or 1. Boolean expression are true = 1 and false = 0. Hence the integer 6 cannot be converted to boolean. So, you can go with counter < max-4
What is the Java equivalent of the while/else in Python? Because it doesn't work in Java. The first chunk was my python code and the second portion is my attempt to translate it into Java. Edit: tring to replicate while-else
while temp.frontIsClear():
if temp.nextToABeeper():
temp.pickBeeper()
count += 1
temp.move()
else:
if temp.nextToABeeper():
temp.pickBeeper()
count += 1
print "The count is ", count
Java Attempt
Robot temp = new Robot();
int count = 0;
while (temp.frontIsClear())
{
if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
temp.move();
}
else
{
if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
}
print ("The count is ", count);
The closest Java equivalent is to explicitly keep track of whether you exited the loop with a break... but you don't actually have a break in your code, so using a while-else was pointless in the first place.
For Java folks (and Python folks) who don't know what Python's while-else does, an else clause on a while loop executes if the loop ends without a break. Another way to think about it is that it executes if the while condition is false, just like with an if statement.
A while-else that actually had a break:
while whatever():
if whatever_else():
break
do_stuff()
else:
finish_up()
could be translated to
boolean noBreak = true;
while (whatever()) {
if (whateverElse()) {
noBreak = false;
break;
}
doStuff();
}
if (noBreak) {
finishUp();
}
Just use one more if statement:
if (temp.nextToABeeper())
// pick beer
} else {
while (temp.frontIsClear()) { /* your code */ }
}
Or:
if (temp.frontIsClear())
while (temp.frontIsClear()) { /* your code */ }
} else if (temp.nextToABeeper()) {
// pick beer
}
If you look at the Java Backus–Naur form Grammar (Syntax Specification), else never follows a while.
Your solution needs to be modified accordingly. You can put the while in an else, that way you handle the if statement.
if temp.nextToBeeper() {
//handle
} else {
while(temp.frontIsClear()) {
//handle
}
}
Try this:
Robot temp = new Robot();
int count = 0;
if (temp.frontIsClear())
{
while (temp.frontIsClear())
{
if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
temp.move();
}
}
else if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
print ("The count is ", count);
In Java
if is a conditional statement .
But
while is loop that is iterate again an again and stop itself when falsecondition occurred .
I am processing elements of an ArrayList in random order, generally by printing them out. I would like to detect when the randomly selected index is 0 or 1 so as to perform special handling for those cases, where the handling for index 0 is partially dependent on whether index 1 has previously been processed. Specifically, nothing is immediately printed when index 1 is processed, but if it is processed then when index 0 is subsequently processed, both the index 1 and the index 0 values are printed. In any event, the loop is exited after ten iterations or after processing index 0, whichever comes first.
I tried to implement this using if statements, but there where obvious flaws with that one. I have searched everywhere for any examples but found none. I have begun to consider using sorting algorithms or threads to hold the first value found then continue looping until it sees the second the print it out. I would appreciate any help possible.
Here is my code:
public static void random_sortType(){
types = new ArrayList<String>();
types.add("Start");
types.add("Starting");
types.add("Load");
types.add("Loading");
types.add("End");
ran = new Random();
int listSize = types.size();
String tempEventType;//the temp variable intended to hold temporary values
for(int i = 0; i < 10; i++){ //the loop goes round the ArrayList 10 times
int index = ran.nextInt(listSize);//this produces the random selection of the elements within the list
if(index == 0){
out.println(types.get(index));
out.println();
break;
}
if(index == 1){
tempEventType = types.get(index);
if(index == 0){
tempEventType = types.get(0) + " " + types.get(1);
out.println(tempEventType);
break;
}
}/*if(index == 0){
tempEventType = types.get(0) + " " + types.get(1);
out.println(tempEventType);
break;
}*/
//out.print("Index is " + index + ": ");
//out.println(types.get(index));
}
}
You need to store the random generated index into a global variable and update it everytime a random number is generated. It should be something like this.
public static void random_sortType(){
types = new ArrayList<String>();
types.add("Start");
types.add("Starting");
types.add("Load");
types.add("Loading");
types.add("End");
` int previousIndex;
ran = new Random();
int listSize = types.size();
String tempEventType;//the temp variable intended to hold temporary values
for(int i = 0; i < 10; i++){ //the loop goes round the ArrayList 10 times
int index = ran.nextInt(listSize);//this produces the random selection of the elements within the list
previous_index =index;
if(index == 0){
out.println(types.get(index));
out.println();
break;
}
if(index == 1){
tempEventType = types.get(index);
if(previousIndex == 0){
temp EventType = types.get(0) + " " + types.get(1);
out.println(tempEventType);
break;
}
According to your description, these are the basic requirements for your application:
Process ArrayList in random order
Processing = printing value at randomly selected index
Make 10 attempts to process items in the list.
Detect when random index is 1 or 0.
if 1
don't process, but flag it was selected.
if 0 && 1 is flagged
process 0 and 1
exit
If these requirements are correct, here is the implementation I came up with:
import java.util.ArrayList;
import java.util.Random;
import static java.lang.System.*;
public class RandomSort {
private static final int MAX_ATTEMPTS = 10;
private static boolean wasOneSelected = false;
public static void main(String[] args) {
ArrayList<String> types = new ArrayList<>(5);
types.add("Start");
types.add("Starting");
types.add("Load");
types.add("Loading");
types.add("End");
random_sortType(types);
}
public static void random_sortType(ArrayList<String> types) {
Random ran = new Random();
int lastIndex = types.size() - 1; // index range is from 0 to 4
for (int i = 0; i < MAX_ATTEMPTS; i++) {
int index = ran.nextInt(lastIndex);
if ( (index == 0) && wasOneSelected) {
process(types.get(index) + " " + types.get(index + 1));
break;
} else if (index == 1) {
wasOneSelected = true;
} else {
process(types.get(index));
}
}
}
public static void process(String str) {
out.println("Processing: " + str);
}
}
The key here is the inclusion of the boolean wasOneSelected initialized to false. Once it is set to true, it will never be false again for the duration of the application. The if-else block handles all branching within the loop, and I favored wrapping the println call into a method called "process" for readability purposes to align it more closely with your description.
Feedback appreciated :)
I have this code which applies a counter to each item on the list. When the item reaches a certain number it is moved from jList3 to jList 1.
public Map<Object, Integer> buttonMap = new HashMap<Object, Integer>();
private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {
Integer counter = null;
int[] selection = jList3.getSelectedIndices();
for (int i = 0; i < selection.length; i++){
Object selString = jList3.getModel().getElementAt(selection[i]);
counter = buttonMap.get(selString);
if(counter == null ) {
buttonMap.put(selString, new Integer(1));
}
else {
buttonMap.put(selString, new Integer(counter.intValue() + 1));
}
System.out.println(selString + " has been clicked " + buttonMap.get(selString) + " times.");
try{
if (counter == 4){
listModel2.removeElement(selString);
listModel.addElement(selString);
}
}
catch (NullPointerException npe1) {
npe1.getMessage();
}
}
}
The behavior comes in the if counter == 4 section.
It works fine but here is the weird part that I need help understanding
If I am counting up two items at the same time and they both reach the number that moves them on the same button click.
-It moves 1 of the items
-It does not count up on the other
-Instead it adds +1 to the counter of a non highlighted item
Example:
I am counting on list item 1 and 2, they both reach the max number, 1 gets moved 2 stays put(no increase in count) and item 3 gets +1 to counter
When you remove an element from jList3, the elements that follow are shifted.
I would sort the selection array and scan it in reverse order.
...
int[] selection = jList3.getSelectedIndices();
Arrays.sort(selection);
for (int i = selection.length; --i >= 0; ){
...
UPDATE: the sorting is not required, because the array returned by getSelectedIndices() already is
The problem is that you are modifying one of your model lists in the same loop as in which you are querying it. If you were using an iterator you would actually get a concurrent modification exception, but as it is you are using specific indexing. In either case your logic is now wrong because the indexes you were relying on to query the list have changed. You can sort your selection array in descending order and keep your code the way it is, but I think it will be cleaner and more maintainable to modify your source array after the loop is done, like so:
...
System.out.println(selString + " has been clicked " + buttonMap.get(selString) + " times.");
if (counter == 4) {
listModel.addElement(selString);
}
}
for(Object o : listModel) {
listModel2.removeElement(o);
}