Everything would seem simple, but something does not go to the head a normal solution. Code on BASIC:

M = 5 KTR(2 * M, 2 * M) FOR i = 1 TO M - 1: FOR j = i + 1 TO M: KTR(i, j) = 1 

Python code:

 M = 5 KTR = [[None] * (2 * M), [None] * (2 * M)] z = 1 z1 = z + 1 for i in range(M - 1): for i1 in range(M): KTR[0][z] = 1 KTR[1][z1] = 1 z = z + 1 z1 = z1 + 1 

However, the list is constantly being accessed. Tell me what I'm doing wrong. This is not a school or university issue, I have a desire to remake the program in another language.

    2 answers 2

    Literal translation of the BASIC code

    FOR i = 1 TO M - 1 creates a loop that bypasses all values ​​from 1 to M-1 inclusive .

    On Python, this can be written as for i in range(1, m) . Please note range() does not include the right border, so both loops with the same i values ​​bypass. EW Dijkstra explains (in 1982) why the right border should not be included.

    KTR(2 * M, 2 * M) declares a KTR table with 2*M+1 rows and 2*M+1 columns (if this construct works like a DIM A(17) construct described in the BASIC manual for 1964 ).

    On Python, variables are not declared. Instead, an object (for example, a list) is assigned a name ( ktr in the example) using an assignment sign:

     ktr = [[None] * (2 * m + 1) for _ in range(2 * m + 1)] 

    Despite the fact that BASIC allows indexing from scratch, the first item in the list is usually referred to as A(1) in BASIC, and not A[0] as in Python. The manual clearly states that A(7) is the seventh element, and not the eighth element as is customary in languages ​​where indexation starts from zero ( A[7] is the eighth element in Python).

    In this regard, the literal translation of the BASIC code on Python:

     m = 5 ktr = [[None] * (2 * m + 1) for _ in range(2 * m + 1)] for i in range(1, m): for j in range(i + 1, m + 1): ktr[i][j] = 1 

    may not reflect the actual intentions of the programmer who wrote the BASIC code.

    Implementing [possible] intent for BASIC code

    If the intention is to create an upper triangular matrix of size m with a zero diagonal:

     m = 5 ktr = [[int(i < j) for j in range(m)] for i in range(m)] 

    Here it is used that True == 1 and False == 0 in Python.

    Or using numpy.triu() :

     import numpy as np m = 5 ktr = np.triu(np.ones((m, m), dtype=int), 1) 

    ktr

     [[0 1 1 1 1] [0 0 1 1 1] [0 0 0 1 1] [0 0 0 0 1] [0 0 0 0 0]] 

    Implementing another [possible] intention [programmer] BASIC code

    To create a 2m x 2m matrix initialized with zeros and fill the upper triangular quartert over the diagonal with one:

     m = 5 ktr = [[0] * (2 * m) for _ in range(2 * m)] for i, row in enumerate(ktr[:m - 1]): row[i + 1:m] = [1] * (m - i - 1) 

    assuming in your case BASIC indexes from one and for for the cycle includes both borders.

    For clarity, here is the same thing using numpy arrays :

     import numpy as np m = 5 ktr = np.zeros((2 * m, 2 * m), dtype=int) ktr[np.triu_indices(m, 1)] = 1 

    ktr

     [[0 1 1 1 1 0 0 0 0 0] [0 0 1 1 1 0 0 0 0 0] [0 0 0 1 1 0 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] 

      In BASIC, a two-dimensional array of 10x10, in Python, 2x10. Of course will not work.

      The whole cycle in Python is very easy to describe:

       m=5 KTR = [ [0 if j<i+1 else 1 for j in range(1,m+1) ] for i in range(1,m) ] 

      Result:

       [[0, 1, 1, 1, 1], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1]] 

      For some reason, the boundaries of the array are indicated by 2*M , and the search goes only up to M - most likely it is insurance against going beyond the array: so those who write on BASIC like to write.

      This, however, is easy to fix. We expand the boundaries to 2*M and at the same time shift the indices by 1, because in BASIC the first index of the array is 1, not 0:

       KTR = [[None]*2*m]+[None]+[ [None]+[0 if j<i+1 else 1 for j in range(1,m+1) ]+[0]*m for i in range(1,m) ]+[ [None]+[0]*2*m for k in range(m+1) ] 

      Result:

       [[None, None, None, None, None, None, None, None, None, None, None], [None, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0], [None, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0], [None, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

      Now, just like in BASIC.

      Well, a simple (but boring) translation as it is in Python from the original BASIC:

       m = 5 KTR = [ [0]*(2*m+1) for k in range(2*m+1) ] for i in range(1,m): for j in range(i+1,m+1): KTR[i][j] = 1 
      • tell me why for simple (boring) translation such boundaries are used range(1,m) | range(i+1,m+1) range(1,m) | range(i+1,m+1) . Although in the original: FOR i = 1 TO M - 1: FOR j = i + 1 TO M ? - St. Ivan
      • @VANECHKA: The "boring" code is a literal translation of BASIC in Python ( range(1,m) provides all values ​​from 1 to m-1 ), which may not reflect the actual intentions of the programmer. Now I think the intention is to create an ktr = [[i < j for j in range(m)] for i in range(m)] triangular matrix: ktr = [[i < j for j in range(m)] for i in range(m)] in Python. - jfs