Python: Index in for loop is resetting without a reason - python-2.7

First of all, I would like to apologize for my english since it is not my native language.
I'm having a quite crazy problem with the following code:
linecounter = []
for i in range(20):
linecounter.append("Color "+str(i)+"\n")
for line in linecounter:
color_list = range(20)
for j in range(len(color_list)):
stri = "Color " + str(j+1)
if stri in line:
print j
The result I expect:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
The result I'm getting:
0
1
2
3
4
5
6
7
8
0
9
0
10
0
11
0
12
0
13
0
14
0
15
0
16
0
17
0
18
Can somebody tell me how I get this result or how I get the result I want?
I would like to thank everyone who answers.
Sincerely, Nikster

Those extra zeroes are being printed because of the way the in operator works for strings. When line is "Color10" and stri is "Color1", then if stri in line evaluates to True, and prints the value of j, which is zero at the time.
Try using an equality comparison instead of in. You would also need to add a newline to the end of stri so that they compare properly.
stri = "Color " + str(j+1) + "\n"
if stri == line:
print j
This will print the numbers from 0 through 18. I don't entirely understand what you're trying to do, but if you want 19 to get printed, you could try not adding 1 to j:
stri = "Color " + str(j) + "\n"
if stri == line:
print j

Strange logic but:
linecounter = []
for i in range(20):
linecounter.append("Color "+str(i))
for line in linecounter:
color_list = range(20)
for j in range(len(color_list)):
stri = "Color " + str(j+1)
if stri == line:
print j

Related

Why does this new [ ] and delete [ ] implementation break down for integers > 12?

The problem: I need to print the Pascal triangle for any (unsigned int) input passed as a command line argument. All the values must be stored in a LINEAR array and elements must only be manipulated as dereferenced pointers. Following this, the array elements must printed as a lower triangular matrix and subsequently deleted. My implementation functions perfectly for input ranging from 0 to 12 but produces spurious results for higher values.
I tried two different implementations.
Declare a pointer to an array of size (n+1)*(n+2)/2 (which is the number of elements in the triangle for input 'n'). Assign/print variables within a nested loop. Delete the pointer once both loops have been executed.
Run a nested loop, 0 <= i <= n, and 0 <= j <= i. Declare a pointer to an array of size (i+1) in the outer loop. Assign/print elements in the inner loop. Delete the pointer once the inner loop has been executed.
// VERSION 1
unsigned N = (n+1)*(n+2)/2;
unsigned* elements = new unsigned[N];
for(i = 0; i <= n; i++) {
for(j = 0; j <= i; j++) {
*(elements + j+(i*i+i)/2) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
cout << endl;
}
delete [] elements;
// VERSION 2
for(i = 0; i <= n; i++) {
unsigned* elements = new unsigned[i+1];
for(j = 0; j <= i; j++) {
*(elements + j) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
delete [] elements;
cout << endl;
}
Both these versions were tried separately on Xcode. In both cases, the triangle printed correctly until the 12th layer, i.e. n=12, but generated incorrect results for higher values.
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 35 21 7 1
8 | 1 8 28 56 70 56 28 8 1
9 | 1 9 36 84 126 126 84 36 9 1
10 | 1 10 45 120 210 252 210 120 45 10 1
11 | 1 11 55 165 330 462 462 330 165 55 11 1
12 | 1 12 66 220 495 792 924 792 495 220 66 12 1
13 | 1 4 24 88 221 399 532 532 399 221 88 24 4 1
14 | 1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
15 | 1 1 0 0 2 4 7 9 9 7 4 2 0 0 1 1
16 | 1 0 0 0 0 4 0 1 1 1 0 4 0 0 0 0 1
The debugger, to the extent that I can use it, produced no error messages.
What is happening and how do I fix it?
fact(i) overflows really fast. I haven't checked the numbers, but I'm pretty sure that's what's happening.
Instead, use the fact that a number in Pascal's triangle is the sum of the two numbers above it.
Wikipedia has a nice animation for this.
When i is 13, fact(i) is 6227020800, which is too big to fit in a 32-bit unsigned integer, so integer overflow occurs.

Read in variable length integer matrix

I'm trying to read in the file
10 5 6 78 5 120 5 6 84 9 5 1
1 3 2 4 5 2 3 4 1 2 1 3
1 4 7 8 12 13
With a variable length of the rows.
I attempt to count the number of elements in a column first by reading in one number at a time, but it seems as if every call to read moves me to the next line. Is there an easy way to count the number of elements in an individual line in Fortran?
Check if this helps -
program count_words_text
implicit none
integer, parameter :: nlen=1000
character (len=nlen) :: text
integer :: nwords, pos, i
text = "foo boo 1 2 goo"
pos = 1
nwords = 0
loop: do
i = verify(text(pos:), ' ') !-- Find next non-blank.
if (i == 0) exit loop !-- No word found.
nwords = nwords + 1 !-- Found something.
pos = pos + i - 1 !-- Move to start of the word.
i = scan(text(pos:), ' ') !-- Find next blank.
if (i == 0) exit loop !-- No blank found.
pos = pos + i - 1 !-- Move to the blank.
end do loop
print*,nwords ! gives 5
end program count_words_text

Python 2.7, restart loop

i am trying to loop though a series of numbers and assign a constant index to them with restarting a loop at a certain number.
input numbers
0
3
6
9
12
15
18
21
0
3
6
9
12
15
18
21
......
the expected output should be
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
my code looks like this. I works but never stops.
How could i iterate over the input data?
count = 1
for line in in_file:
should_restart = True
while should_restart:
should_restart = False
for i in xrange(0,22,3):
print count
if i == 21:
should_restart = True
count+=1
break
Thanks!
Supposing you have an in_file like this (that's just an example yours is different but I wanted to do it with your given input):
in_file = "0 3 6 9 12 15 18 21 0 3 6 9 12 15 18 21"
in_file = in_file.split(" ")
you setup an end-condition for your counter and a starting count:
end_condition = 21
count = 1
then you iterate through your list:
for line in in_file:
line = int(line) # This is only needed if you have string-data
within the loop print the current count:
print(count, end=' ')
and later increment the counter if you reach the final value:
if line == end_condition:
count += 1

Magic Square in Python Debugging

Problem originally is in this link. I wrote a Python code but I got 64 points (total points is 100) and this indicates that my code has some missing points. I passed 11 of 16 test cases but 5 test cases have problematic for me. Could you say where my code has some missing points and how can I fix it?
import math
m = int(raw_input())
liste = []
y_liste = []
md = 0
ad = 0
sum = 0
sum2 = 0
for k in range(m):
temp = str(raw_input())
liste.append(temp)
liste[k] = liste[k].split(" ")
liste[k] = [int(i) for i in liste[k]]
for k in range(m):
md += liste[k][k]
ad += liste[k][m-k-1]
if md == ad:
print 0
else:
for k in range(m):
for l in range(m):
sum2 += liste[l][k]
sum += liste[k][l]
if sum2 != md and -(k+1) is not y_liste:
y_liste.append(-(k+1))
if sum != md and (k+1) is not y_liste:
y_liste.append(k+1)
sum2 = 0
sum = 0
if md != ad:
y_liste.append(0)
print len(y_liste)
y_liste.sort()
for i in y_liste:
print i
Problem Statement
Magic Square
Johnny designed a magic square (square of numbers with the same sum for all rows, columns and diagonals i.e. both the main diagonal - meaning the diagonal that leads from the top-left corner towards bottom-right corner - and the antidiagonal - meaning the diagonal that leads from top-right corner towards bottom-left corner). Write a program to test it.
Task
Write a program that will check if the given square is magic (i.e. has the same sum for all rows, columns and diagonals).
Input
First line: N , the size of the square (1 <= N <= 600).
Next N lines: The square, N space separated integers pre line, representing the entries per each row of the square.
Output
First line: M , the number of lines that do not sum up to the sum of the main diagonal (i.e. the one that contains the first element of the square). If the Square is magic, the program should output 0.
Next M lines: A sorted (in incremental order ) list of the lines that do not sum up to the sum of the main diagonal. The rows are numbered 1,2,…,N; the columns are numbered -1,-2,…,-N; and the antidiagonal is numbered zero.
Note: There is a newline character at the end of the last line of the output.
Sample Input 1
3
8 1 6
3 5 7
4 9 2
Sample Output 1
0
Sample Input 2
4
16 3 2 13
5 10 11 8
6 9 7 12
4 15 14 1
Sample Output 2
3
-2
-1
0
Explanation of Sample Output 2
The input square looks as follows: http://i.stack.imgur.com/JyMgc.png
(Sorry for link but I cannot add image due to reputation)
The square has 4 rows (labeled from 1 to 4 in orange) and 4 columns (labeled from -1 to -4 in green) as depicted in the image above. The main diagonal and antidiagonal of the square are highlighted in red and blue respectively.
The main diagonal has sum = 16 + 10 + 7 +1 = 34.
The antidiagonal has sum = 13 + 11 + 9 + 4 = 37. This is different to the sum of the main diagonal so value 0 corresponding to the antidiagonal should be reported.
Row 1 has sum = 16 + 3 + 2 + 13 = 34.
Row 2 has sum = 5 + 10 + 11 + 8 = 34.
Row 3 has sum = 6 + 9 + 7 + 12 = 34.
Row 4 has sum = 4 + 15 + 14 + 1 = 34.
Column -1 has sum = 16 + 5 + 6 + 4 = 31. This is different to the sum of the main diagonal so value -1 should be reported.
Column -2 has sum = 3 + 10 + 9 + 15 = 37. This is different to the sum of the main diagonal so value -2 should be reported.
Column -3 has sum = 2 + 11 + 7 + 14 = 34.
Column -4 has sum = 13 + 8 + 12 + 1 = 34.
Based on the above, there are 3 lines that do not sum up to the sum of the elements of the main diagonal. Since they should be sorted in incremental order, the output should be:
3
-2
-1
0
Your explanation doesn't discuss this clause which is a potential source of error:
if md == ad:
print 0
else:
It says that if the main diagonal and antidiagonal add up to the same value, print just a 0 (no bad lines) indicating the magic square is valid (distinct from reporting a 0 in the list of bad lines). Consider this valid magic square:
9 6 3 16
4 15 10 5
14 1 8 11
7 12 13 2
If I swap 13 and 11, the diagonals still equal each other but the square is invalid. So the above code doesn't appear to be correct. In the else clause for the above if statement, you test:
if md != ad:
y_liste.append(0)
a fact you already know to be true from the previous/outer test so your code seems to be out of agreement with itself.

find adjacent vertical elements in a grid

I'm having trouble figuring out the thought process behind grabbing adjacent vertical elements in a grid. Say I have a 5x5 grid:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
I want to find all adjacent horizontal and vertical adjacent elements and place them into an array. The size of the array is given by the possible number of walls between each element (not counting the outside) e.g.
1 | 2 | 3
--- --- ---
4 | 5 | 6
A graph of 2x3 has 7 walls so the array would look like
1 2
2 3
4 5
5 6 //end of horizontal walls
1 4 //beginning of vertical walls
2 5
3 6
now I've figured out how to find all horizontal walls given rows and cols, where walls is the array I will be storing the result in:
//find all horizontal walls in grid
//2-d array to store the element between the wall (0 1) (1 2)
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols-1; c++){
int s = r > 0 ? -1*r : 0; //after first row always write over last space
walls[r*rows+c+s][0] = r*rows+c;
walls[r*rows+c+s][1] = r*rows+c+1;
}
}
but I'm just getting lost on figuring out how to determine all vertical walls, in a grid of 5x5 for example the vertical walls would be
0 5
5 10
10 15
15 20
1 6
6 11
etc...
here's what I'm currently trying:
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
//just print the values at the moment, setting walls properly is easy
std::cout << r*rows+c*cols << " " << r*rows+c*cols+5 << std::endl;
}
}
only problem is this does not reset after the first column to 1, instead it continues on like:
0 5
5 10
10 15
15 20
20 25 //nope, should be 1 6
and suggestions? pseudo-code is much appreciated I would prefer an explanation over code
Ok, just figured out the solution so I'll post all I did:
the problem I had was rows did not recent back to 1 when the inner for loop left and started again, this was because I was still multiplying r by rows, this was actually a really simple fix:
r*rows+c*cols << " " << r*rows+c*cols+5 <<
becomes
r+c*cols << " " << r+c*cols+5 <<
I also was running the inner for loop one too many times so, changing
c < cols should become c < cols-1 and now my output is:
0 5
5 10
10 15
15 20
1 6
6 11
11 17
etc...