Python(フォーマットを意識した九九表示)

九九表で任意の数からフォーマットを揃えた表を表示できるようにプログラムしてみました。
ポイントはリスト内包表記を利用して事前に計算結果のリストを作成し、ループ処理を利用して表を作成している点です。
またprintf形式表示で桁数を揃えるためにzip関数でタプルを作成し、引数に渡すようにしています。

# table作成show関数

def time_log(func):
    """処理時間を計測するデコレータ関数"""
    def wrapper(*args,**kwargs):
        import datetime
        start = datetime.datetime.today()
        print("\n---start:" + func.__name__)
        res = func(*args,**kwargs)
        end = datetime.datetime.today()
        delta = end - start
        print("\n---end:" + func.__name__,delta,"sec")
        return res
    return wrapper

@time_log
def show(first=1,end=9):
    column=[i for i in range(first,end+1)]
    table=[[i*j for i in range(first,end+1)] for j in range(first,end+1)]
    digit=[len(str(table[-1][i])) for i in range(len(column))]
    left=len(str(table[-1][0]))
    def print_column():
        print(" "*left,end="  ")
        for x in zip(digit,column):
            print("%*d"%x,end=" ")
        print("")

    def print_line():
        print(" "*left,end=" +")
        for i in digit:
            print("-"*i,end="+")
        print("")
    
    # 1段目
    print_column()
    # 2段目以降
    for n in range(len(column)):
        print_line()
        print("%*d"%(left,column[n]),end=" |")
        for v in zip(digit,table[n]):
            print("%*d"%v,end="|")
        print("")

show()
show(5)
show(4,10)

こちらは最初の列と区切りの線を関数にして動的に作成した表ですが、線の部分は形式が決まったら使いまわす部分なんで、事前にstring型として登録しておけば効率的だって事でちょっと改良↓

def show(first=1,end=9):
    column=[i for i in range(first,end+1)]
    table=[[i*j for i in range(first,end+1)] for j in range(first,end+1)]
    digit=[len(str(table[-1][i])) for i in range(len(column))]
    left=len(str(table[-1][0]))
    
    str_column="".join(" "*left + "  ")
    for x in zip(digit,column):
        str_column = str_column + "%*s"%x + " "        
        
    str_line="".join(" "*left + " +")
    for i in digit:
        str_line = str_line + "-"*i + "+"        
    
    # 1段目
    print(str_column)
    # 2段目以降
    for n in range(len(column)):
        print(str_line)
        print("%*d"%(left,column[n]),end=" |")
        for v in zip(digit,table[n]):
            print("%*d"%v,end="|")
        print("")

下が改良verの結果でやはり事前にstring型を作っておく方が実行速度が速かったです。

r=range(1,10)
table=[[i*j for i in r] for j in r]
print(table)
ps = [len(str(x)) for x in table[-1]]
print(ps)
print("\n".join(["".join(line) for line in [["%*d|"%x for x in zip(ps,xs)] for xs in table]]))

ポイントとなるリスト内包表記は上記です。
計算結果も同様に事前にstringにしてしまって表示すれば、より実行速度が上がるかと・・・

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください