Python - Печать декартовой координатной сетки ASCII из двумерного массива позиционных объектов - PullRequest
0 голосов
/ 06 мая 2020

Очень жаль, но это будет долгое время. Итак, как ответвление моего предыдущего запроса относительно STDIN, к сожалению, похоже, что существует не так много вопросов, достаточно похожих на мою конкретную проблему c, по крайней мере, не в Python (или без использования чего-то вроде numpy, которое чуть выше моего уровня). У меня есть много кода, который я уже реализовал, так что, надеюсь, это поможет (хотя он не самый чистый и, как я уже упоминал выше, довольно длинный).

Моя проблема в нынешнем виде связана с печатью out ASCII-art, представляющий 2D-массив объектов классов, так что ASCII точно отображает их в ориентации простой декартовой координатной сетки x, y.

У меня есть несколько взаимодействующих друг с другом классов, первый из которых конструирует объекты позиции, содержащие два целых числа, представляющих x и y декартовой пары координат:

class Pos:
    def __init__(self, x, y):
        self.x = x
        self.y = y

Второй класс конструирует «квадратную» сетку из некоторого параметра размера, предоставленного пользователем в другой части моего программа, реализованная здесь как 2D-массив, заполненный этими позиционными объектами:

class Grid:
    def __init__(self, size):
        assert size > 0
        self.size = size
        self.grid = []
        #1  Perhaps there is something wrong with my 2D implementation...
        for x in range(size):
            sub_grid = []
            for y in range(size):
                sub_grid.append(Pos(x, y))
            self.grid.append(sub_grid)

Также в этом классе есть метод, который распечатывает ASCII-графику сетки, чтобы действовать как внешнее представление для пользователя (это это беспорядок):

def print(self):
    #  This is the main ASCII-art.
    size_check = self.size - 1
    if self.size > 10:
        print('   +' + ('-' * (((self.size * 2) + 1)) + '+'))
    else:
        print('  +' + ('-' * (((self.size * 2) + 1)) + '+'))
    counter = 0
    #2  ...or perhaps it's something wrong with this iterative condition.
    for x in self.grid[::-1]:
        if self.size > 10:
            if size_check > 9:
                print(self.size - 1 - counter, '|', end=' ')
            else:
                print('', self.size - 1 - counter, '|', end=' ')
        else:
            print(self.size - 1 - counter, '|', end=' ')
        counter += 1
        size_check -= 1
        for y in x:
            #  This is only here to check if the coords are in the correct position in the art.
            ^^if y.x == 5 and y.y == 8:
                print('O ', end='')^^
            else:
                print('. ', end='')
        print('|')
    if self.size > 10:
        print('   +' + ('-' * (((self.size * 2) + 1)) + '+'))
        print('     ', end='')
    else:
        print('  +' + ('-' * (((self.size * 2) + 1)) + '+'))
        print('    ', end='')

    #  This is simply support for grid sizes greater than 10.
    if self.size > 10:
        for x in self.grid:
            if x[0].x <= 9:
                print('', '', end=' ')
            elif x[0].x > 9 and x[0].x < (self.size - 1):
                strng = str(x[0].x)
                print(int(strng[0]), end=' ')
            elif x[0].x == (self.size - 1):
                strng = str(x[0].x)
                print(int(strng[0]))
        print('     ', end='')
        for x in self.grid:
            if x[0].x <= 9:
                print(x[0].x, '', end='')
            elif x[0].x > 9 and x[0].x < (self.size - 1):
                strng = str(x[0].x)
                print(int(strng[1]), end=' ')
            elif x[0].x == (self.size - 1):
                strng = str(x[0].x)
                print(int(strng[1]), end=' ')
    else:
        for x in self.grid:
            if x[0].x < (self.size - 1):
                print(x[0].x, '', end='')
            elif x[0].x == (self.size - 1):
                print(x[0].x, end='')
    print()

Я знаю, что это много, но что это успешно распечатывает выглядит так (заданный размер = 10):

  +---------------------+
9 | . . . . . . . . . . |
8 | . . . . . . . . . . |
7 | . . . . . . . . . . |
6 | . . . . . . . . . . |
5 | . . . . . . . . . . |
4 | . . . . . . . . . . |
3 | . . . . . . . . . . |
2 | . . . . . . . . . . |
1 | . . . . . . . . . . |
0 | . . . . . . . . . . |
  +---------------------+
    0 1 2 3 4 5 6 7 8 9

Теперь это выглядит нормально, пока я не попытаюсь показать, где должны быть расположены объекты позиции. В приведенном выше коде я пометил ^^ условный оператор, который выводит «O» в координатах (5, 8). Результат выглядит так:

  +---------------------+
9 | . . . . . . . . . . |
8 | . . . . . . . . . . |
7 | . . . . . . . . . . |
6 | . . . . . . . . . . |
5 | . . . . . . . . O . |
4 | . . . . . . . . . . |
3 | . . . . . . . . . . |
2 | . . . . . . . . . . |
1 | . . . . . . . . . . |
0 | . . . . . . . . . . |
  +---------------------+
    0 1 2 3 4 5 6 7 8 9

Идеальный результат должен выглядеть так:

  +---------------------+
9 | . . . . . . . . . . |
8 | . . . . . O . . . . |
7 | . . . . . . . . . . |
6 | . . . . . . . . . . |
5 | . . . . . . . . . . |
4 | . . . . . . . . . . |
3 | . . . . . . . . . . |
2 | . . . . . . . . . . |
1 | . . . . . . . . . . |
0 | . . . . . . . . . . |
  +---------------------+
    0 1 2 3 4 5 6 7 8 9

Как видите, ASCII-art печатается таким образом, что внешне it выглядит , как если бы оси x и y поменялись местами, даже если внутренне координаты в любом объекте позиции реагируют правильно. Я написал два комментария в приведенном выше коде, где предполагаю, в чем может быть проблема. Мои самые лучшие предположения заключаются в том, как я реализовал саму сетку или как я печатаю искусство; но это то, что мне нужно выяснить.

Любая помощь, как всегда, приветствуется; и еще раз прошу прощения!

1 Ответ

3 голосов
/ 06 мая 2020

Я бы посоветовал строить ваши строки, используя манипуляции со строками вместо прямой печати. Это упростит код и позволит заменять шаблоны в строке шаблона для типичного содержимого строки.

Например:

# prepare the empty content
rows = 10
cols = 10
content = [["."]*cols for _ in range(rows)]

# assign values at coordinates as needed (based on your grid)
content[5][8]  = "O"
grid = [(4,1,"H"),(6,3,"L"),(5,2,"E"),(4,6,"R"),(7,4,"L"),(6,6,"W"),(3,6,"L"),(2,6,"D"),(5,6,"O")]
for (y,x,c) in grid: content[y][x] = c

# build frame
width       = len(str(max(rows,cols)-1))
contentLine = "# | values |"

dashes      = "-".join("-"*width for _ in range(cols))
frameLine   = contentLine.replace("values",dashes)
frameLine   = frameLine.replace("#"," "*width)
frameLine   = frameLine.replace("| ","+-").replace(" |","-+")

# print grid
print(frameLine)
for i,row in enumerate(reversed(content),1):
    values = " ".join(f"{v:{width}s}" for v in row)
    line   = contentLine.replace("values",values)
    line   = line.replace("#",f"{rows-i:{width}d}")
    print(line)
print(frameLine)

# x-axis numbers
numLine = contentLine.replace("|"," ")
numLine = numLine.replace("#"," "*width)
colNums = " ".join(f"{i:<{width}d}" for i in range(cols))
numLine = numLine.replace("values",colNums)
print(numLine)

вывод:

  +---------------------+
9 | . . . . . . . . . . |
8 | . . . . . O . . . . |
7 | . . . . L . . . . . |
6 | . . . L . . W . . . |
5 | . . E . . . O . . . |
4 | . H . . . . R . . . |
3 | . . . . . . L . . . |
2 | . . . . . . D . . . |
1 | . . . . . . . . . . |
0 | . . . . . . . . . . |
  +---------------------+
    0 1 2 3 4 5 6 7 8 9                  

вывод со строками = 12 и cols = 15:

   +----------------------------------------------+
11 | .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  |
10 | .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  |
 9 | .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  |
 8 | .  .  .  .  .  O  .  .  .  .  .  .  .  .  .  |
 7 | .  .  .  .  L  .  .  .  .  .  .  .  .  .  .  |
 6 | .  .  .  L  .  .  W  .  .  .  .  .  .  .  .  |
 5 | .  .  E  .  .  .  O  .  .  .  .  .  .  .  .  |
 4 | .  H  .  .  .  .  R  .  .  .  .  .  .  .  .  |
 3 | .  .  .  .  .  .  L  .  .  .  .  .  .  .  .  |
 2 | .  .  .  .  .  .  D  .  .  .  .  .  .  .  .  |
 1 | .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  |
 0 | .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  |
   +----------------------------------------------+
     0  1  2  3  4  5  6  7  8  9  10 11 12 13 14  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...