Why does not this for-loop work? - loops

Help, please.
This code does't work:
for (i = 0; i == userWhoIsInLineArray.GetNumberOfUsersOnline() - 1; i++) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
}
When I write this one, all work!
while(i != userWhoIsInLineArray.GetNumberOfUsersOnline() - 1) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
i++;
}
Why is happening?

I doubt you meant to use equality in your for loop test for continuance?
This bit:
i == userWhoIsInLineArray.GetNumberOfUsersOnline()-1
Perhaps you meant another comparison operator?

You should write as:
for (i = 0; i < userWhoIsInLineArray.GetNumberOfUsersOnline(); i++) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
}
Only when the second sentence of for-clause is true, for-block is executed. So, when the variable i is smaller than userWhoIsInLineArray.GetNumberOfUsersOnline(), it must be true.
cf 1. i == userWhoIsInLineArray.GetNumberOfUsersOnline() means only when variable i equals userWhoIsInLineArray.GetNumberOfUsersOnline() it is true. Unless userWhoIsInLineArray.GetNumberOfUsersOnline() is 0, it results false for the first loop.
cf 2. In the same sence your while-loop is better to rewrite as:
int i = 0;
while (i < userWhoIsInLineArray.GetNumberOfUsersOnline()) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
i++;
}

Related

Loop to change the set while moving the array - C

How to keep the smoke set changing while the rocket goes up?
I don't understood very well, but the set only changes while the rocket is at the base.And he wasn't supposed to stand still.
veja o movimento do vĂ­deo no link ->
https://i.imgur.com/RRvFqBR.mp4
The loop for(int h = 0; h < 29; h++){ maintains the set by changing the condition of the increment, and only takes off after that. Then the set stops changing.
#include <unistd.h>
#include <stdio.h>
#define LINE 11
#define COLN 12
#define R_COLN 12
#define R_LINE 9
#define R_SET 2
#define DELAY 95000
//string to display the rocket
const char rocket[LINE][COLN+1]={
" ^ ",
" /^\\ ",
" |-| ",
" |R| ",
" |O| ",
" |C| ",
" |K| ",
" |E| ",
" /|T|\\ ",
" / | | \\ ",
" | | | | "
};
const char smoke[R_SET][R_LINE][R_COLN+1]={
{
" ' * ",
" * + . ' ",
" - . + ",
" . ' : . ",
" + ' ' * . ",
" . * . ",
" . ' : ",
" . ' . ",
" ' "
},
{
" * ' ",
" ' . + * ",
" + . - ",
" . : ' . ",
" . * ' ' + ",
" . * . ",
" : ' . ",
" . ' . ",
" ' "}
};
int main(){
int jumpControlAtBottom = 0;
int shifControl = 0;
int smoke_set = 0;
for(int h = 0; h < 29; h++){ //frame
for (jumpControlAtBottom = 0; jumpControlAtBottom < 28; ++jumpControlAtBottom){
// Jump to bottom of console
printf("\n");
}
for(int i = 0; i< LINE; i++){
printf("%.*s\n", COLN, rocket[i]);
}
for(int y=0; y<R_LINE; ++y){
printf("%.*s\n", R_COLN, smoke[smoke_set][y]);
}
smoke_set=(smoke_set+1)%R_SET; // Advance to the next set
// (or go back to the first one).
fflush(stdout); // Draw the current frame on the screen.
usleep(DELAY); // Pause to be visible.
}
for (shifControl = 0; shifControl < 28; ++shifControl){
// Rocket move on the basis of delay
usleep(DELAY);
// move rocket a line upward
printf("\n");
}
return 0;
}
Currently your logic is:
Draw one frame.
Change smoke set.
Repeat 1-2 for 29 frames.
Draw line to push frame up.
Repeat 4 to keep pushing frames up.
From that it is obvious the smoke will stop changing at step 4. So the logic needs to include the take off elevation in step 1. The easiest way to do that is to put the draw frame into a function and add the elevation as a parameter.
Here is an example:
void draw_frame(int elevation)
{
int jumpControlAtBottom = 0;
static int smoke_set = 0;
for (jumpControlAtBottom = 0; jumpControlAtBottom < 28 + elevation; ++jumpControlAtBottom){
// Jump to bottom of console
printf("\n");
}
for(int i = 0; i< LINE; i++){
printf("%.*s\n", COLN, rocket[i]);
}
for(int y=0; y<R_LINE; ++y){
printf("%.*s\n", R_COLN, smoke[smoke_set][y]);
}
smoke_set=(smoke_set+1)%R_SET; // Advance to the next set
// (or go back to the first one).
// Push image up by elevation
for (int ix = 0; ix < elevation; ix++) {
printf("\n");
}
fflush(stdout); // Draw the current frame on the screen.
usleep(DELAY); // Pause to be visible.
}
int main(){
int shifControl = 0;
// No elevation - engine starting up
for(int h = 0; h < 29; h++){ //frame
draw_frame(0);
}
// take off has occured
for (shifControl = 0; shifControl < 28; ++shifControl){
// Rocket move on the basis of delay
// move rocket a line upward
draw_frame(shifControl);
}
return 0;
}
It seems to me like you're struggling to understand the procedural nature of C, which probably means you're guessing and playing around with code from other (probably poor) examples.
This is akin to guessing how to prepare a chicken for cooking and then asking your guests how to prepare a chicken for cooking, after the chicken is cooked. You have an application that does most of what you want. How did you come up with this code, yet not know how to apply such a simple tweak?
If you don't understand the procedural nature of C, it stands to reason that any exercise that has you read the procedural nature of C in order to extract some logic and repeat it is terrible for you. Where is your book? Start with the basics.
To be clear, this answer may not seem relevant, but it does actually answer your question: you need to hoist some of your smoke-related logic out into a different function so that you can reuse it later... but before you do that, you need to be able to read C, and we're not here to do your work for you, rather to guide you in the right direction.

Make for loop continue until a goal is accomplished

I need to be able to find 5 sequential bits of EEPROM memory, ideally closest to 2 (as I have bit #1 & 2 associated with other data and want things to be kept organized). I developed this code which works, but the for loop continues after it has found a good set of numbers.
Serial.println("got to assignment number finder");
for (int AssignCheck = 2; AssignCheck < 250; AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
}
}
}
}
}
}
I then thought I could put a while loop around it, and have the while loop stop once a variable is set to 0 as opposed to 1, so I wrote this: (notice the introduction of the while loop, the variable and the Scanner = 0 line in the middle).
Serial.println("got to assignment number finder");
int Scanner = 1;
while (Scanner == 1){
for (int AssignCheck = 2; AssignCheck < 250; AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck) + ". Scanner value = " + String(Scanner));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Scanner = 0;
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
}
}
}
}
}
}
}
It correctly identifies and sets the variable to 0 when I want, but the while loop doesn't seem to have an impact and the loop continues to produce sets of numbers which could work.
As a novice coder myself, I'm not sure what I could try next.
Any advice would be greatly appreciated.
In these case you can use the instruction break:
Serial.println("got to assignment number finder");
for (int AssignCheck = 2; AssignCheck < 250; AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
break;
}
}
}
}
}
}
As you can read here, it does exactly what you want.
Please note that your second attempt doesn't work because the for loop is inside the while: it completes before the whole for loop and, after, it compare the "scanner" variable of the while loop
You can correct it in this way:
Serial.println("got to assignment number finder");
int Scanner = 1;
for (int AssignCheck = 2; (AssignCheck < 250) && (Scanner == 1); AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck) + ". Scanner value = " + String(Scanner));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Scanner = 0;
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
}
}
}
}
}
}
Reading EEPROM is expensive, please consider this:
Serial.println("got to assignment number finder");
int Scanner = 1;
char rollingBuffer[5];
rollingBuffer[0] = EEPROM.read(2 + 0);
rollingBuffer[1] = EEPROM.read(2 + 1);
rollingBuffer[2] = EEPROM.read(2 + 2);
rollingBuffer[3] = EEPROM.read(2 + 3);
rollingBuffer[4] = EEPROM.read(2 + 4);
pointRoll = 0;
for (int AssignCheck = 7; (AssignCheck < 255); AssignCheck++)
{
if ((rollingBuffer[0] == 255) && (rollingBuffer[1] == 255) && (rollingBuffer[2] == 255) && (rollingBuffer[3] == 255) && (rollingBuffer[4] == 255))
{
Serial.println("Found assignment numbers " + String(AssignCheck-5) + " through to " + String(int(AssignCheck-1)) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
break;
}
rollingBuffer[pointRoll] = EEPROM.read(AssignCheck);
pointRoll++;
if (pointRoll > 4) pointRoll = 0;
}

Scanner cleared during loop: how do I still maintain a certain condition?

I am in the process of making a program which will display 3 problems of operation type which a user picks. I've used a loop to keep the program generating random numbers for each iteration as well as to display another problem. The problem I'm having is in trying to clear the scanner after taking user input as to not keep the wrong value stored and screw up the loop. I need the one value ("a") to be stored so that the loop continues with the next question. For this post I've taken out all options but addition just for debugging purposes. My code I will paste below:
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
Random randGen = new Random(Config.RANDOM_SEED);
// Welcome
System.out.println("Hello and welcome to the Math Trainer!\n======================================");
System.out.println("Which math operation would you like to practice?");
// Create a counter for correct answers
int correctCount = 0;
// Create a for loop to generate multiple questions
for (int count = 0; count < Config.NUMBER_OF_QUESTIONS; count++) {
// Calculate random values from seed and shift them within range
int ran1 = randGen.nextInt(Config.MAX_VALUE - Config.MIN_VALUE + 1);
int ran2 = randGen.nextInt(Config.MAX_VALUE - Config.MIN_VALUE + 1);
int ran1Shift = ran1 + Config.MIN_VALUE;
int ran2Shift = ran2 + Config.MIN_VALUE;
// Initialize different answers per operation
double additionAnswer = (double) ran1Shift + ran2Shift;
double subtractionAnswer = (double) ran1Shift - ran2Shift;
double multiplicationAnswer = (double) ran1Shift * ran2Shift;
double divisionAnswer = (double) ran1Shift / ran2Shift;
double remainderAnswer = (double) ran1Shift % ran2Shift;
// Ask for user input on which to choose (only on first run of loop)
if (count == 0) {
System.out.println(" " + "[A]ddition");
System.out.println(" " + "[S]ubtraction");
System.out.println(" " + "[M]ultiplication");
System.out.println(" " + "[D]ivision");
System.out.println(" " + "[R]emainder");
System.out.print("Enter your choice:" + " ");
}
// Presentation of addition problems
if (stdin.nextLine().equalsIgnoreCase("a")) {
System.out.print(
"What is the solution to the problem:" + " " + ran1Shift + " " + "+" + " " + ran2Shift + " = ");
if (stdin.hasNextDouble()) {
double userNum = stdin.nextDouble();
stdin.nextLine();
if (userNum == additionAnswer) {
System.out.println("That is correct!");
correctCount++;
} else {
System.out.println("The correct solution is: " + additionAnswer + ".");
}
} else {
stdin.nextLine();
System.out.println("All solutions must be entered as decimal numbers.");
System.out.println("The correct solution is " + additionAnswer + ".");
}
} else {
System.out.println("I'm sorry, I only understand choices of: A, S, M, D, or R!");
count--;
}
}
// Program exit
System.out.println("*** You answered " + correctCount + " out of 3 questions correctly. ");
System.out.println("======================================");
System.out.println("Thank you for using the Math Trainer!");
}
}
The output I get if I enter the correct answer to the first problem (13) is:
https://gyazo.com/773f9be3b51f51f5086f38f36ed0c86b
In which I have to enter "a" again for the next question to show.
The output I should get is here:
https://gyazo.com/6609a9f0b44d0b446439d3331be51eb9
Please let me know if you have any questions and thank you very much for your help.
if (stdin.nextLine().equalsIgnoreCase("a")) this is the cause of your problem.
For a quick fix, move the codes asking for operationType to outside of the loop since it's only executed once.
System.out.println(" " + "[A]ddition");
System.out.println(" " + "[S]ubtraction");
System.out.println(" " + "[M]ultiplication");
System.out.println(" " + "[D]ivision");
System.out.println(" " + "[R]emainder");
System.out.print("Enter your choice:" + " ");
String operationType = stdin.nextLine();
for (int count = 0; count < Config.NUMBER_OF_QUESTIONS; count++) {
//codes
if (operationType.equalsIgnoreCase("a")) {
Might be better to use a switch statement for checking the operationType too.

What is the logic behind the control statement 'if((i+j) & 1)'?

This program declares an 8x8 character array and then uses a loop to store the following data into the array(one character per array element). Then it prints this array to the screen:
BRBRBRBR
RBRBRBRB
BRBRBRBR
RBRBRBRB
BRBRBRBR
RBRBRBRB
BRBRBRBR
RBRBRBRB
The program works fine. However, I am having trouble understanding the logic behind the if statement:
if((i+j) & 1)
I don't understand how if adding i + j 'and' 1 is true set array to 'R' else set it to 'B'. This might have a rather obvious answer, but I am new to C. Can someone help clarify why this program works with this logic? Thank You!
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j;
char letter[8][8];
for(i=0; i<8; i++) {
for(j=0; j<8; j++) {
//This if-statement
if ((i+j) & 1)
letter[i][j] = 'R';
else
letter[i][j] = 'B';
printf("%c" , letter[i][j]);
}
printf("\n");
}
return 0;
}
(i+j) & 1 will evaluate to true when i+j is odd and false when i+j is even.
The & in that expression is the bitwise AND operator, not the logical AND operator.
The code would be so much more readable if written as:
int is_odd(int n)
{
return ((n&1) == 1);
}
...
if ( is_odd(i+j) )
There's a pattern here - the last bit of the value is constantly flipped:
i = 0, j = 0 --> i + j = 0 --> 2'b00
i = 0, j = 1 --> i + j = 1 --> 2'b01
i = 0, j = 2 --> i + j = 2 --> 2'b10
...and so on
The & operator then does a bit-wise and operation on the bits of the value:
//this evaluates to false, and 'B' is printed
2'b00 & 1 == 2'b00 & 2'b01 == 2'b(0&0)(0&1) == 2'b00
//this evaluates to true, and 'R' is printed
2'b01 & 1 == 2'b01 & 2'b01 == 2'b(0&0)(1&1) == 2'b01

indexOf and substring skipping 1 result

I'm trying to separate / explode an String to do something with it later on.
The input string is this:
1_2_3_2_2
The function I'm calling with the above value as parameter:
void parseXString(String value){
int amountX = (value.length() / 2) + 1;
int seperatorIndex = value.indexOf('_');
int secondSeperator = 0;
for(int i = 0; i < amountX; i++){
String xPoint = "";
if(i == 0){
xPoint = value.substring(0, seperatorIndex);
}else{
xPoint = value.substring(seperatorIndex + 1, secondSeperator);
}
sendMessage((String)i + " X = " + xPoint + " || SEP: " + (String)seperatorIndex + " / " + (String)secondSeperator );
seperatorIndex = value.indexOf("_", seperatorIndex + 1);
secondSeperator = value.indexOf("_", seperatorIndex + 1);
}
sendMessage("Last X = " + value.substring(seperatorIndex + 1));
}
The sendMessage function will shout the value back to the operating Java application. The output I get is this:
0 X = 1 || SEP: 1 / 0
1 X = 3 || SEP: 3 / 5
2 X = 2 || SEP: 5 / 7
3 X = 2 || SEP: 7 / -1
4 X = 1 || SEP: -1 / 1
Last X = 2_3_2_2
As you can notice, on the second iteration there should be an return of the value 2 instead of an 3.
I think there's something wrong with the seperatorIndexes, but I'm out of the blank right now (working on this way to long).
So my question is very simple. Why doesn't I get the right value back / how can I fix that?
Your error is that you increase seperatorIndex in the first iteration. Therefore, seperatorIndex is 3 in your second iteration.
You should put the part where you increment seperatorIndex into the else part of your if(i == 0) condition. When doing this, you also have to increment secondSeperator in the if part of your condition.

Resources