Friends, the task is the following: Dana encryption lattice and encrypted password, as a list (list) of lines. Example:

('X...', '..X.', 'X..X', '....'), ('itdf', 'gdce', 'aton', 'qrdi')) 

It is necessary to "overlay" the first list with the second one to receive values ​​from the second list if the symbol in one list corresponds to the symbol "X" in another list. Next, turn the matrix with the characters "X" and perform the operation again. 90, 180, 270. The values ​​obtained from the second list - to the conclusion.

I wrote the solution to this problem, I ask you to look and make comments on the code I wrote.

 def recall_password(cipher_grille, ciphered_password): list = "" #Список, где будут храниться полученные данные turn = 0 #Счетчик while turn < 4: for elem1, elem2 in zip(ciphered_password, cipher_grille): #Заходим в каждый из списков for word1, word2 in zip(elem1, elem2): #Получаем значения из каждого списка if word2 == "X": list += word1 cipher_grille = tuple(zip(*cipher_grille[::-1])) #Поворачиваем матрицу на 90 градусов" turn += 1 print(list) return list 

My decision about the while loop and the counter seems to be ugly, I hope you can suggest how you can make the code "simpotichnoe." thank

  • 3
    If you are sure that the code works and any comments on the code are interesting, then add a code-inspection label (see its description to understand the difference with ordinary questions) - jfs
  • Execution time: fer0m - 0.00008 sec, Max - 0.00011 sec, Alexander - 0.00013 sec, MaxU - 1.51231 sec. - users

3 answers 3

When you need to perform a sequence of actions a specified number of times, usually use this structure:

 for _ in range(number_of_times): # some code 

And yet - at your deepest level of nesting, the code has five indents (the first level, by the way, you lost when copying the code). It's a lot. When then your code will be read by another programmer (or you yourself in a few weeks), it will be difficult to understand these heaps.

If you notice that your code starts to be piled up in such monstrous constructions, then look - is it possible to bring something into separate small functions?

I myself solved this problem in the following way:

 from itertools import compress def recall_password(cipher_grille, ciphered_password): letters = ''.join(ciphered_password) def turn(matrix): return list(''.join(tpl) for tpl in zip(*matrix[::-1])) def gain(template, letters): t = ''.join(template) t = [(lambda i: 1 if i == 'X' else 0)(i) for i in t] return ''.join(compress(letters, t)) res = [] for _ in range(4): res.append(gain(cipher_grille, letters)) cipher_grille = turn(cipher_grille) return ''.join(res) 

By the way, if you still have questions about tasks with checkio, indicate how this task is called on the site and from which section it is.

I remember exactly what I did this task, but I didn’t find it at once.

  • Interesting application of itertools.compress ! - MaxU

I would do that.

We lead to a flat array and filter.

 def compress(key, val): # similar for itertools.compress key = list(''.join(key)) # make all in one list like ['........'] val = list(''.join(val)) return ''.join(v for v, k in zip(val, key) if k=='X') 

Using zip, rotate the array. The resulting lines must also be expanded.

 def right_rotate(array): return tuple(map(lambda a: ''.join(reversed(a)),zip(*array))) 

Calculate

 if __name__ == '__main__': key = ( 'X...', '..X.', 'X..X', '....') value = ('itdf', 'gdce', 'aton', 'qrdi') (k,v) = (key, value) l = '' for i in range(0,4): l +=compress(k,v) k = right_rotate(k) print(l) 

    “Creative” vectorized solution on Numpy + Pandas (almost without cycles):

     import numpy as np import pandas as pd data = ( ('X...', '..X.', 'X..X', '....'), ('itdf', 'gdce', 'aton', 'qrdi')) df = pd.DataFrame(list(data), index=['grid','code']).T grid_arr = df.grid.str.extractall(r'(.)').unstack().eq('X').values data_arr = df.code.str.extractall(r'(.)').unstack().values result = ''.join([''.join(data_arr[np.rot90(grid_arr, -i)].tolist()) for i in range(4)]) 

    Result:

     icantforgetiddqd 

    Some explanations:

     In [58]: df Out[58]: grid code 0 X... itdf 1 ..X. gdce 2 X..X aton 3 .... qrdi In [59]: grid_arr Out[59]: array([[ True, False, False, False], [False, False, True, False], [ True, False, False, True], [False, False, False, False]], dtype=bool) In [60]: data_arr Out[60]: array([['i', 't', 'd', 'f'], ['g', 'd', 'c', 'e'], ['a', 't', 'o', 'n'], ['q', 'r', 'd', 'i']], dtype=object) In [61]: data_arr[grid_arr] Out[61]: array(['i', 'c', 'a', 'n'], dtype=object)