[英]Is there any python module to plot 2d cartesian coordinate in text mode?
[英]Python - Printing an ASCII cartesian coordinate grid from a 2D array of position objects
非常抱歉,所有人,但這將是一個漫長的過程。 因此,作為我之前關於 STDIN 的查詢的一個分支,不幸的是,似乎沒有足夠多的問題與我的具體問題相似,至少在 Python 中沒有(也沒有使用像 numpy 這樣的東西,這比我的水平高出一點) . 我確實有很多我已經實現的代碼,所以希望這會有所幫助(盡管它不是最干凈的,而且正如我上面提到的,它相當長)。
就目前而言,我的問題是打印出表示 class 對象的二維數組的 ASCII 藝術,以便 ASCII 准確地在簡單的 x,y 笛卡爾坐標網格的方向上描繪它們。
我有幾個相互交互的類,第一個構造包含兩個整數的 position 對象,表示笛卡爾坐標對的 x 和 y:
class Pos:
def __init__(self, x, y):
self.x = x
self.y = y
第二個 class 根據用戶在我程序的不同部分提供的一些大小參數構造一個“正方形”網格,這里實現為一個填充了這些 position 對象的二維數組:
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)
在這個 class 中還有一個方法,它打印出網格的 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
現在這看起來很好,直到我嘗試顯示 position 對象應該位於的位置。 在上面的代碼中,我用 ^^ 標記了一個條件語句,它在坐標 (5, 8) 處打印出一個“O”。 結果看起來像這樣:
+---------------------+
9 | . . . . . . . . . . |
8 | . . . . . . . . . . |
7 | . . . . . . . . . . |
6 | . . . . . . . . . . |
5 | . . . . . . . . O . |
4 | . . . . . . . . . . |
3 | . . . . . . . . . . |
2 | . . . . . . . . . . |
1 | . . . . . . . . . . |
0 | . . . . . . . . . . |
+---------------------+
0 1 2 3 4 5 6 7 8 9
理想的 output 實際上應該是這樣的:
+---------------------+
9 | . . . . . . . . . . |
8 | . . . . . O . . . . |
7 | . . . . . . . . . . |
6 | . . . . . . . . . . |
5 | . . . . . . . . . . |
4 | . . . . . . . . . . |
3 | . . . . . . . . . . |
2 | . . . . . . . . . . |
1 | . . . . . . . . . . |
0 | . . . . . . . . . . |
+---------------------+
0 1 2 3 4 5 6 7 8 9
正如您所看到的,ASCII 藝術以這樣一種方式打印,從外部看起來好像 x 軸和 y 軸已經交換,即使在內部任何 position object 的坐標響應正確。 我在上面的代碼中寫了兩條評論,我推測可能是什么問題。 我最好的猜測是我如何實現網格本身,或者我如何打印藝術作品; 但這就是我需要幫助弄清楚的。
一如既往,我們非常感謝您提供的任何幫助; 我再次道歉!
我建議使用字符串操作而不是直接打印來構建你的線條。 這將使代碼更簡單,並允許將模板字符串中的模式替換為典型的行內容。
例如:
# 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)
output:
+---------------------+
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
output 行=12,列=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
1. Grid
結構
pub struct Grid {
cells: Vec<Vec<char>>,
num_rows: usize,
num_cols: usize,
}
Grid
結構表示字符網格。 它具有三個字段:
cells
:表示網格中單元格的二維字符向量。num_rows
:表示網格中行數的usize
。num_cols
:表示網格中列數的usize
。 2. Alignment
枚舉
#[derive(Debug, PartialEq)]
enum Alignment {
Left,
Center,
Right,
}
Alignment
枚舉表示打印網格時單元格值的可能對齊方式。 它具有三種變體:
Left
:將單元格值左對齊。Center
:將單元格值對齊到中心。Right
:將單元格值右對齊。 3. new
方法
fn new(num_rows: usize, num_cols: usize, empty_cell_char: char) -> Self {
let cells = vec![vec![empty_cell_char; num_cols]; num_rows];
Self {
cells,
num_rows,
num_cols,
}
}
}
new
方法是Grid
結構的構造方法。 它需要三個參數:
num_rows
:表示網格中行數的usize
。num_cols
:表示網格中列數的usize
。empty_cell_char
:表示要填充空單元格的char
的字符。 它創建一個具有給定行數和列數的新網Grid
object,並用給定字符填充單元格。
set_cell
方法
fn set_cell(&mut self, row: usize, col: usize, character: char) {
self.cells[row][col] = character;
}
}
set_cell
方法在網格的特定單元格中設置字符。 它需要三個參數:
row
:表示單元格行號的usize
。col
:表示單元格列號的usize
。character
:一個char
表示要在單元格中設置的字符。它在給定行和列的單元格中設置字符。
5. draw
方法
impl Grid {
fn draw(
&self,
cell_width: usize,
border_char: char,
row_separator_char: char,
col_separator_char: char,
x_axis_separator_char: char,
alignment: Alignment,
) {
let frame_top_bottom = (0..self.num_cols)
.map(|_| border_char.to_string().repeat(cell_width))
.collect::<Vec<_>>()
.join(&border_char.to_string());
let row_template = format!(
"{row_num}{row_separator}{row_values}{row_values_separator}",
row_num = "{row_num}",
row_separator = row_separator_char,
row_values = "{row_values}",
row_values_separator = row_separator_char
);
let row_num = row_template.replace(
"{row_num}",
format!("{:width$}", "", width = cell_width).as_str(),
);
let frame_top = row_num.replace("{row_values}", &frame_top_bottom);
println!("{}", frame_top);
for (row_num, row) in self.cells.iter().rev().enumerate() {
let row_num_str = format!("{:width$}", self.num_rows - row_num - 1, width = cell_width);
let row_values: Vec<String> = row
.iter()
.map(|cell| {
let aligned_string: String = match alignment {
Alignment::Left => format!("{:<width$}", cell, width = cell_width),
Alignment::Center => format!("{:^width$}", cell, width = cell_width),
Alignment::Right => format!("{:>width$}", cell, width = cell_width),
};
aligned_string
})
.collect();
println!(
"{}",
row_template
.replace(
"{row_num}",
format!("{:<width$}", row_num_str, width = cell_width).as_str()
)
.replace(
"{row_values}",
&row_values.join(&col_separator_char.to_string())
)
);
}
println!("{}", frame_top);
let col_nums: Vec<String> = (0..self.num_cols)
.map(|col| {
let aligned_string: String = match alignment {
Alignment::Left => format!("{:<width$}", col, width = cell_width),
Alignment::Center => format!("{:^width$}", col, width = cell_width),
Alignment::Right => format!("{:>width$}", col, width = cell_width),
};
aligned_string
})
.collect();
let x_axis = row_num.replace(
"{row_values}",
&col_nums.join(&x_axis_separator_char.to_string()),
);
println!("{}", x_axis);
}
}
draw
方法使用給定的參數將網格打印到控制台。 它需要六個參數:
cell_width
:表示打印網格時每個單元格寬度的usize
。
border_char
:一個char
表示用於網格邊界的字符。
row_separator_char
:一個char
表示用作網格行之間分隔符的字符。
col_separator_char
:一個char
表示用作網格列之間分隔符的字符。
x_axis_separator_char
:一個char
,表示用作網格底部列號之間分隔符的字符。
alignment
:一個Alignment
值,表示打印網格時單元格值的 alignment。
draw
方法首先使用border_char
和cell_width
生成網格的頂部和底部邊框。 然后它為網格的每一行創建一個模板,該模板由行號、行分隔符、該行的單元格值和行值分隔符組成。
然后它從下到上遍歷網格的行,並使用模板和當前行號和單元格值為每一行生成一個字符串。 然后它將每一行打印到控制台。
最后,它使用alignment
和x_axis_separator_char
在網格底部生成列號,並將它們打印到控制台。
6. main
function
復制代碼
fn main() {
let mut grid = Grid::new(3, 3, ' ');
grid.set_cell(0, 0, 'X');
grid.set_cell(1, 1, 'O');
grid.set_cell(2, 2, 'X');
grid.draw(
4,
'+',
'|',
' ',
' ',
Alignment::Right,
);
}
main
function新建一個3行3列的Grid
object,並使用set_cell
方法設置單元格中的字符。 然后它調用Grid
object 上的draw
方法將其打印到控制台,單元格寬度為 4,邊框字符為'+'
,行分隔符為'|'
、列分隔符' '
、x 軸分隔符' '
和 alignment Alignment::Right
。
步 | 描述 |
---|---|
定義Grid 結構 |
Grid 結構表示具有三個字段的字符網格: cells ,表示網格中單元格的二維字符向量; num_rows ,表示網格中行數的usize ; 和num_cols ,一個表示網格中列數的usize 。 |
定義Alignment 枚舉 |
Alignment 枚舉表示打印網格時單元格值的可能對齊方式。 它具有三種變體: Left ,將單元格值左對齊; Center ,將單元格值與中心對齊; 和Right ,它將單元格值右對齊。 |
定義new 方法 |
new 方法是Grid 結構的構造函數。 它需要三個參數: num_rows ,一個表示網格中行數的usize ; num_cols ,表示網格中列數的usize ; 和empty_cell_char ,一個char 表示要填充空單元格的字符。 它創建一個具有給定行數和列數的新網Grid object,並用給定字符填充單元格。 |
定義set_cell 方法 |
set_cell 方法在網格的特定單元格中設置字符。 它需要三個參數: row ,一個usize 代表單元格的行號; col ,表示單元格列號的usize ; 和character ,一個char 表示要在單元格中設置的字符。 它在給定行和列的單元格中設置字符。 |
定義draw 方法 |
draw 方法使用給定的參數將網格打印到控制台。 它有六個參數: cell_width ,一個usize ,表示打印網格時每個單元格的寬度; border_char ,一個char 表示用於網格邊界的字符; row_separator_char ,一個char 表示用作網格行之間分隔符的字符; col_separator_char ,一個char 表示用作網格列之間分隔符的字符; x_axis_separator_char ,一個char 表示用作網格底部列號之間分隔符的字符; 和alignment ,一個Alignment 值,表示打印網格時單元格值的 alignment。 它首先使用border_char 和cell_width 生成網格的頂部和底部邊框。 然后它為網格的每一行創建一個模板,該模板由行號、行分隔符、該行的單元格值和行值分隔符組成。 然后它從下到上遍歷網格的行,並使用模板和當前行號和單元格值為每一行生成一個字符串。 然后它將每一行打印到控制台。 最后,它使用alignment 和x_axis_separator_char 在網格底部生成列號,並將它們打印到控制台。 |
定義main function |
main function新建一個3行3列的Grid object,並使用set_cell 方法設置單元格中的字符。 然后它調用Grid object 上的draw 方法將其打印到控制台,單元格寬度為 4,邊框字符為'+' ,行分隔符為 `' |
步 | 描述 |
---|---|
定義Grid 結構 |
Grid 結構表示具有三個字段的字符網格: cells ,表示網格中單元格的二維字符向量; num_rows ,表示網格中行數的usize ; 和num_cols ,一個表示網格中列數的usize 。 |
定義Alignment 枚舉 |
Alignment 枚舉表示打印網格時單元格值的 alignment。 它具有三個變體: Left 、 Center 和Right 。 |
定義new 方法 |
new 方法創建一個新的Grid object 具有給定的行數和列數,並用給定的字符填充單元格。 |
定義set_cell 方法 |
set_cell 方法在網格的特定單元格中設置字符。 |
定義draw 方法 |
draw 方法使用給定的參數將網格打印到控制台。 |
定義main function |
main function 創建一個Grid object 並在其單元格中設置字符。 然后它使用draw 方法將網格打印到控制台。 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.