2019/10/16

色、いろいろ(Python, Rust, OCaml, C, Clojure)

ライブラリがなくても色付けできる

まずは実例画像を
この魅惑のレインボーう◯ちプログラムでは、サードパーティ製ライブラリは使っていませんし、標準ライブラリも特に使っておりません。色に関するコードは以下のようになっています。


from enum import Enum


class Color(Enum):
    BLACK = '\033[30m'
    R_BLACK = '\033[40m'
    RED = '\033[31m'
    R_RED = '\033[41m'
    GREEN = '\033[32m'
    R_GREEN = '\033[42m'
    YELLOW = '\033[33m'
    R_YELLOW = '\033[43m'
    BLUE = '\033[34m'
    R_BLUE = '\033[44m'
    PURPLE = '\033[35m'
    R_PURPLE = '\033[45m'
    CYAN = '\033[36m'
    R_CYAN = '\033[46m'
    WHITE = '\033[37m'
    R_WHITE = '\033[47m'
    END = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'
    INVISIBLE = '\033[08m'
    REVERSE = '\033[07m'


def colored(color: Color, char):
    if isinstance(char, int):
        return f"{color.value}{chr(char)}{Color.END.value}"
    elif isinstance(char, str):
        return f"{color.value}{char}{Color.END.value}"
    else:
        return "ERROR"

print(colored(Color.CYAN, 'A'))
print(colored(Color.YELLOW, 0x1F4A9))
# 0x2588 -> カーソルと同じサイズ
# 0x25AE
# 0x25FE
# 0x1F4A9 ->unchi 避けて通れない
enumモジュールを使って、列挙型にしています。各ヴァリアントの値は色付けするためのものです。そして、PythonのEnumはvalueメソッドによって、値を取得できるようになっています。列挙型を使用しなくとも、単なるクラスでも実現可能です。その場合は、単なる文字列として扱います。
Python3.6から導入されたf-stringは、直接{}内に埋め込むことができるので、以前までのformatよりも便利です。
ちなみに、C言語やOCaml、Rust、Clojureでは\033のところを\x1bとすると同様に色付けできます。


---------
C言語の場合
---------

#include <stdio.h>

int main() {
    printf("\x1b[32mHello, world!!\x1b[0m\n");
    return 0;
}


---------------
OCamlの場合(抜粋)
---------------

Lwt_main.run (Lwt_io.printf "\x1b[32mHello, world!!\x1b[0m\n")


----------------
Rustの場合
----------------

fn main() {
    println!("{}{}{}", "\x1b[32m", "Hello, world!!", "\x1b[0m");
}

-------------------------------
Clojureの場合(javaも)
-------------------------------

user=> (println "\u001b[00;32mHello, world!!\u001b[00m")

たとえばPythonのインタラクティブシェルのような対話環境でプロンプトに色を付けたい場合にも使えます。 サードパーティ製ライブラリももちろんありますし、おそらくより多くのことができるでしょう。しかし、そこまでの機能はいらないなんて方は知っておくと便利かもしれません。

追記(2019/10/18)

ちなみに工夫すると以下のようなものも作成可能です。