While loop executing too many times - while-loop

this program reads text files, and in this case, reads this one:
Sam
5 0 0 0
Dave
5 5 0 0
Bill
5 -5 0 0
Louise
3 3 5 0
Early in my program, I execute the following while loop:
int count = 0;
while (input.hasNextLine())
{
count++;
if (count % 2 == 1) //for every other line, reads the name
{
String line = input.nextLine();
names.add(line); //puts name into array
}
if (count % 2 == 0) //for every other line, reads the ratings
{
ArrayList<Integer> rtemp = new ArrayList<Integer>();
while (input.hasNextInt())
{
int tempInt = input.nextInt();
rtemp.add(tempInt);
}
allratings.add(rtemp);
}
}
For some reason, by the time this while loop is done, int count is at 14. I only want it to be at 8, and think that it should be, considering that there are only 8 lines of text, and it is supposed to execute for each line. Obviously, this causes big problems later in the program. Any idea what is going on?

It seems from your second loop, the cursor never moves to the next line...I added below lines just after your allratings.add(rtemp); and it worked.
if(input.hasNext())
input.next();

Related

Arduino LCD 2 digits to 1 digit

I have a problem with showing numbers on the LCD screen in Tinkercad. The time is counting down from 60 seconds. But when it counts until 9-1 the number has shown as 90-10. Eg: LCD screen shows 20 at 2 seconds instead of 02 or 2 only. May I know how can I change it to only 1 digit or 09-01? Hope someone can help me with this. Thanks in advance.
Here my code for Arduino of LCD:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
lcd.begin(16, 2); // Set up the number of columns and rows on the LCD.
// Print a message to the LCD.
lcd.print("Ambulance is approaching!");
}
void loop()
{
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting
// begins with 0):
lcd.setCursor(0,1);
// Print a message to the LCD.
lcd.print("Time:");
for (int seconds = 60; seconds > 0; --seconds){
lcd.setCursor(6,1);
lcd.print(seconds-1);
delay(1000);
}
}
This is because lcd.print only overwrites the necessary characters. So after displaying 11 it overwrites it with a 10 correctly. After that it overwrites the 1 with a 9 and the 0 stays because the new input is only one character long.
You can clear the line by printing a string containing two spaces and then print the time.
for (int seconds = 60; seconds > 0; --seconds){
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print(seconds-1);
delay(1000);
}

Cyclomatic Complexity edges

So I'm trying to figure out if that blue line is in the right place, I know that I should have 9 edges but not sure if it's correct.
The code
public int getResult(int p1, int p2) {
int result = 0; // 1
if (p1 == 0) { // 2
result += 1; //3
} else {
result += 2; //4
}
if (p2 == 0) { //5
result += 3; //6
} else {
result += 4; //7
}
return result; //8 exit node
}
so 8 nodes and it should have 9 edges, right? Did I do the right thing?
Yes, the blue line is placed correctly because after the 3rd line, your program is going to jump to the 5th line.
The easiest way to compute cyclomatic complexity without drawing any flow diagram is as follows:
Count all the loops in the program for, while, do-while, if. Assign a value of 1 to each loop. Else should not be counted here.
Assign a value of 1 to each switch case. Default case should not be counted here.
Cyclomatic complexity = Total number of loops + 1
In your program, there are 2 if loops, so the cyclomatic complexity would be 3(2+1)
You can cross-check it with the standard formulae available as well which are as below:
C = E-N+2 (9-8+2=3)
OR
C = Number of closed regions + 1 (2+1=3)
According to wikipedia:
M = E − N + 2P,
where
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components.
so:
9 - 8 + 2*1 = 3

Convert a fixed-length line by line text file into SQL and transpose

I have a very large text file (3gb) of data in a simple list in the format:
NEW
2016-08-15_20-45-47-3120
0
0
0
0
1960
0
0
Every new data entry is started by "NEW" then followed by the date stamp and 456 numbers.
I'd like to transform it into a format like:
New 2016-08-15_20-45-47-3120 0 190 0 300
New 2016-08-15_20-45-47-3140 0 0 0 0
New 2016-08-15_20-45-47-3620 1 34 4 76
I'd normally offset it in excel first but with such a large data set it can't begin to cope so it's got to be done in SQL.
Thanks
This is the kind of thing I find awk useful for.
This script captures every line it sees into an array, which it outputs and resets every time it sees the line containing NEW (or the end of file). If you save this code to transpose.awk, it can be run with awk -f transpose.awk big.txt > out.txt.
function output(a,n, i)
{
if(n > 0)
{
for(i = 0; i < n; i++) {
printf "%s\t", a[i];
}
printf "\n";
}
}
/^NEW/ { output(a,n); n=0; delete a; }
{ a[n++] = $0; }
END { output(a,n); }
If you wanted to only output the first 5 columns instead of all 8, you could change the for loop to stop earlier.
I tested this with a 224M dummy sample file and it took 44 seconds on my computer, so 3GB should take roughly ten minutes. Not fast, but bearable.

Trouble Understanding Fork Logic

Can someone help me understand what is happening in this segment of code? I am having trouble understanding why the output is how it is. Output is:
0 1 2 3 4
3
2
1
0
int main() {
int i;
for (i = 0; i < 5 && !fork(); i++) {
fflush(stdout);
printf("%d ", i);
}
wait(NULL);
printf("\n");
return 0;
}
Two things here:
First, fork() return 0 in child process while it returns a non zero pid to the parent process.
Second, short circuit of &&.
So in the beginning of the first process (p0), it runs to i < 5 && !fork(). Now i = 0 and another process created (p1). Now for p0, test !fork() fails, it ends the for loop and waiting for child to end. For p1, the test succeeds, and print out 0, then increment i to 1, then it will create process p2 and itself goes out the for loop as p0 did.
Because of short circuiting, when i equals 5, no more fork will be called.

What's wrong with my pascal's triangle?

I've been looking for some simple coding challenges recently, and discovered about Pascal's triangle (here), and I've tried to generate one myself in C/Objective-C. For those that don't know what it is, that link explains it pretty well.
I'm starting to get oddness after the fourth row, and I just can't figure out why.
My output for 5 iterations currently looks like this:
1
1 1
1 2 1
1 3 3 1
4 6 3 1
It should look like this:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Here is my code so far. The first loop is just a reset loop (setting all the values to 0). The actual logic happens mostly in the second loop. The third loop is where the values are concatenated and formatted in a string.
I've commented this code much more than I would for myself just to aid readability.
int iterations, i, b, mid, chars, temp;
NSLog(#"Please enter the number of itereations");
scanf("%i",&iterations); // take users input and store it in iterations
// calculate where the first 1 should go.
if (iterations % 2 == 0) mid = (iterations)/2;
else mid = (iterations+1)/2;
chars = iterations*2;
int solutions[iterations][chars];
// reset loop
for (i = 0; i<iterations; i++) {
for (b = 0; b<chars; b++) {
solutions[i][b] = 0;
}
}
solutions[0][mid] = 1; // place the initial 1 in first row
for (int row = 1; row<iterations; row++) {
for (int chi = 0; chi<chars; chi++) {
temp = 0;
if (chi > 0) {
temp += solutions[row-1][chi-1]; // add the one diagonally left
}
if (chi < iterations) {
temp += solutions[row-1][chi+1]; // add the one diagonally right
}
solutions[row][chi] = temp; // set the value
}
}
// printing below...
NSMutableString *result = [[NSMutableString alloc] initWithString:#"\n"];
NSMutableString *rowtmp;
for (i = 0; i<iterations; i++) {
rowtmp = [NSMutableString stringWithString:#""];
for (b = 0; b<chars; b++) {
if (solutions[i][b] != 0) [rowtmp appendFormat:#"%i",solutions[i][b]];
else [rowtmp appendString:#" "]; // replace any 0s with spaces.
}
[result appendFormat:#"%#\n",rowtmp];
}
NSLog(#"%#",result);
[result release];
I have a feeling the problem may be to do with the offset, but I have no idea how to fix it. If anyone can spot where my code is going wrong, that would be great.
It appears (from a brief look) that the original midpoint calculation is incorrect. I think it should simply be:
mid = iterations - 1;
In the example of 5 iterations, the midpoint needs to be at array position 4. Each iteration "moves" one more position to the left. The 2nd iteration (2nd row) would then place a 1 at positions 3 and 5. The 3rd iteration at 2 and 6. The 4th at 1 and 7. And the 5th and last iteration would fill in the 1s at 0 and 8.
Also, the second if statement for the temp addition should be as follows otherwise it reads past the end of the array bounds:
if (chi < iterations - 1) {