鱼C论坛

 找回密码
 立即注册
查看: 1009|回复: 0

[作品展示] 【Python】命令行表格渲染器 v0.1.0

[复制链接]
发表于 2022-2-1 15:07:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 ckblt 于 2022-2-1 15:06 编辑

我改进了一下我的表格渲染器,
给大家分享一下。

特别感谢@python爱好者. 的建议与支持!
from typing import Union, List, Tuple, Set
import random


class Table:
    @staticmethod
    def random_table(
        len_x: Union[int, None] = None, len_y: Union[int, None] = None
    ) -> List[List]:
        """
        随机生成一个二维列表

        参数:
        `len_x: int | None` -- 二维列表的长度
        `len_y: int | None` -- 二维列表的宽度
        """
        x = random.randint(2, 5) if len_x == None else len_x
        y = random.randint(2, 5) if len_y == None else len_y
        return [[random.randint(0, 10000) for _ in range(x)] for _ in range(y)]

    def __init__(self, table: List[List]):
        """
        初始化 Table

        参数:
        `table: List[List]` -- 表格
        """
        self.table = table.table if isinstance(table, Table) else [i for i in table]
        self.length = len(self.table[0]), len(self.table)
        self.__check()

    def __check(self):
        """
        检查 self.table 是否合法
        """
        temp = set([len(x) for x in self.table])
        if len(temp) != 1:
            raise Exception()

    def __no_list_list(self, x, no_tuples=False, no_sets=False):
        new_list = []

        for i in x:
            if (
                (isinstance(i, list))
                or (no_tuples and isinstance(i, tuple))
                or (no_sets and isinstance(i, set))
            ):
                new_list.extend(self.__no_list_list(i, no_tuples, no_sets))
            else:
                new_list.append(i)

        return new_list

    def render(self, isSquare=False, spacing=4, prop=3) -> str:
        """
        以普通模式渲染 self.table

        参数:
        `isSquare: bool` -- 正方形模式
        `spacing: int` -- 间距, 需要大于 0
        `prop: int | float` -- 方形的长宽比例,使它接近正方形
        """
        col_spaces = spacing
        l = self.__no_list_list(self.table)
        rendered = ""

        # 每列之间的空,存储到 col_spaces
        for i in l:
            if len(str(i)) > col_spaces - spacing:
                col_spaces = len(str(i)) + spacing

        # 正式渲染
        for i_i in range(self.length[1]):
            i = self.table[i_i]
            for j in i:
                rendered += str(j) + " " * (col_spaces - len(str(j)))

            if i_i != self.length[1] - 1:
                if isSquare:
                    rendered += "\n" * round(col_spaces / prop)
                else:
                    rendered += "\n"

        return rendered

    def chart(
        self,
        isSquare=False,
        align: Union["left", "center", "right"] = "left",
        align_y: Union["top", "center", "bottom"] = "top",
        spacing=4,
        prop=3,
    ) -> str:
        """
        以图表模式渲染 self.table

        参数:
        `isSquare: bool` -- 正方形模式
        `align: "left" | "center" | "right"` -- 左右对齐
        `align_y: "top" | "center" | "bottom"` -- 上下对齐, 需要让 `isSquare` 为 `True`
        `spacing: int` -- 间距, 需要大于 0
        `prop: int | float` -- 方形的长宽比例,使它接近正方形
        """
        col_spaces = spacing
        l = self.__no_list_list(self.table)
        rendered = ""

        # 每列之间的空,存储到 col_spaces
        for i in l:
            if len(str(i)) > col_spaces - spacing:
                col_spaces = len(str(i)) + spacing

        # 正式渲染
        rendered += "-" * ((col_spaces + 1) * self.length[0] + 1) + "\n"
        for i_i in range(self.length[1]):
            i = self.table[i_i]
            temp = ""
            for j in i:
                if align == "left":
                    temp += str(j) + " " * (col_spaces - len(str(j))) + "|"
                elif align == "center":
                    a = (col_spaces - len(str(j))) // 2
                    b = ((col_spaces - len(str(j)))) - a
                    temp += " " * a + str(j) + " " * b + "|"
                    del a, b
                elif align == "right":
                    temp += " " * (col_spaces - len(str(j))) + str(j) + "|"

            if isSquare:
                if align_y == "top":
                    rendered += (
                        "|"
                        + temp
                        + "\n"
                        + (("|" + " " * col_spaces) * (self.length[0] + 1) + "\n")
                        * round(col_spaces / prop)
                    )
                elif align_y == "center":
                    a = round(col_spaces / prop / 2)
                    b = round(col_spaces / prop) - a
                    rendered += (
                        ((("|" + " " * col_spaces) * (self.length[0] + 1) + "\n") * a)
                        + "|"
                        + temp
                        + "\n"
                        + ((("|" + " " * col_spaces) * (self.length[0] + 1) + "\n") * b)
                    )
                    del a, b
                elif align_y == "bottom":
                    rendered += (
                        (("|" + " " * col_spaces) * (self.length[0] + 1) + "\n")
                        * round(col_spaces / prop)
                        + "|"
                        + temp
                        + "\n"
                    )
            else:
                rendered += "|" + temp + "\n"
            rendered += "-" * ((col_spaces + 1) * self.length[0] + 1) + "\n"

        return rendered

使用方法:
用 Table.random_table(列表长度, 列表宽度) 来创建一个二维列表
用 t = Table(你的二维列表) 来创建表格
用 t.render() 来渲染
用 t.chart() 来以图表方式渲染

例子:
l = Table.random_table(3, 3)  # 创建一个 3x3 的随机二维数组
t = Table(l)  # 创建一个表格
print(t.render())
print("分隔线")
print(t.chart())

输出:
2139    3152    757
3783    2615    8039
1156    6488    9565
分隔线
----------------------------
|2139    |3152    |757     |
----------------------------
|3783    |2615    |8039    |
----------------------------
|1156    |6488    |9565    |
----------------------------

评分

参与人数 1鱼币 +5 收起 理由
python爱好者. + 5 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 02:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表