Twitterなど、ほぼ全てのSNSは横書きですね。Pythonプログラミングの勉強も兼ねて、これを縦書きに変換するPythonスクリプトを書いてみましょう。
Tweet
以下のツイートを縦書きにしてみたいと思います。
tweet = '''\
普通は Tweet は横書きなんだけどさ、
これを縦書きにしたいわけよ。
そうすると、検索されにくくなるんじゃね?
いっちょ Pythonでやってみないか?
'''
tweet
'普通は Tweet は横書きなんだけどさ、\nこれを縦書きにしたいわけよ。\nそうすると、検索されにくくなるんじゃね?\nいっちょ Pythonでやってみないか?\n'
1文字1文字に分解
次のようにすれば1文字1文字に分解できます。
for line in tweet.split("\n"):
print([line[i] for i in range(len(line))])
['普', '通', 'は', ' ', 'T', 'w', 'e', 'e', 't', ' ', 'は', '横', '書', 'き', 'な', 'ん', 'だ', 'け', 'ど', 'さ', '、']
['こ', 'れ', 'を', '縦', '書', 'き', 'に', 'し', 'た', 'い', 'わ', 'け', 'よ', '。']
['そ', 'う', 'す', 'る', 'と', '、', '検', '索', 'さ', 'れ', 'に', 'く', 'く', 'な', 'る', 'ん', 'じ', 'ゃ', 'ね', '?']
['い', 'っ', 'ち', 'ょ', ' ', 'P', 'y', 't', 'h', 'o', 'n', 'で', 'や', 'っ', 'て', 'み', 'な', 'い', 'か', '?']
[]
ただし、最後の行だけ空白行になってしまうので除外しましょう。
for line in tweet.split("\n"):
if len(line) > 0:
print([line[i] for i in range(len(line))])
['普', '通', 'は', ' ', 'T', 'w', 'e', 'e', 't', ' ', 'は', '横', '書', 'き', 'な', 'ん', 'だ', 'け', 'ど', 'さ', '、']
['こ', 'れ', 'を', '縦', '書', 'き', 'に', 'し', 'た', 'い', 'わ', 'け', 'よ', '。']
['そ', 'う', 'す', 'る', 'と', '、', '検', '索', 'さ', 'れ', 'に', 'く', 'く', 'な', 'る', 'ん', 'じ', 'ゃ', 'ね', '?']
['い', 'っ', 'ち', 'ょ', ' ', 'P', 'y', 't', 'h', 'o', 'n', 'で', 'や', 'っ', 'て', 'み', 'な', 'い', 'か', '?']
以上の処理を、リスト内包表記を使ってスマートに表現し、 data
という変数に入れます。
data = [[line[i] for i in range(len(line))] for line in tweet.split("\n") if len(line) > 0]
print(data)
[['普', '通', 'は', ' ', 'T', 'w', 'e', 'e', 't', ' ', 'は', '横', '書', 'き', 'な', 'ん', 'だ', 'け', 'ど', 'さ', '、'], ['こ', 'れ', 'を', '縦', '書', 'き', 'に', 'し', 'た', 'い', 'わ', 'け', 'よ', '。'], ['そ', 'う', 'す', 'る', 'と', '、', '検', '索', 'さ', 'れ', 'に', 'く', 'く', 'な', 'る', 'ん', 'じ', 'ゃ', 'ね', '?'], ['い', 'っ', 'ち', 'ょ', ' ', 'P', 'y', 't', 'h', 'o', 'n', 'で', 'や', 'っ', 'て', 'み', 'な', 'い', 'か', '?']]
numpy で転置
行列の転置したいので numpy が使えるといいのですが
import numpy as np
np.array(data)
array([list(['普', '通', 'は', ' ', 'T', 'w', 'e', 'e', 't', ' ', 'は', '横', '書', 'き', 'な', 'ん', 'だ', 'け', 'ど', 'さ', '、']),
list(['こ', 'れ', 'を', '縦', '書', 'き', 'に', 'し', 'た', 'い', 'わ', 'け', 'よ', '。']),
list(['そ', 'う', 'す', 'る', 'と', '、', '検', '索', 'さ', 'れ', 'に', 'く', 'く', 'な', 'る', 'ん', 'じ', 'ゃ', 'ね', '?']),
list(['い', 'っ', 'ち', 'ょ', ' ', 'P', 'y', 't', 'h', 'o', 'n', 'で', 'や', 'っ', 'て', 'み', 'な', 'い', 'か', '?'])],
dtype=object)
以上のように、リストのアレイになってしまい、うまくいきません。
そこで、行数と列数をしっかり測って、その大きさに相当する配列を用意しましょう。
max_length = 0 # 最も長い文の文字数を数える
for d in data:
if max_length < len(d):
max_length = len(d)
以上のようにすれば、 tweet
は len(data)
行 max_length
列の配列で表現できることが分かります。そこで、同じ大きさの numpy 配列を用意しましょう。あらかじめ空白文字で埋めておきます。
import numpy as np
np.full((len(data), max_length), " ")
array([['\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000'],
['\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000'],
['\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000'],
['\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000', '\u3000', '\u3000']], dtype='<U1')
あとは、その numpy array に data の文字を1文字1文字書き写します。
ただし、このとき、文の順序が逆になるようにします。
data2 = np.full((len(data), max_length), " ")
for i in range(len(data)):
for j in range(max_length):
if j < len(data[i]):
data2[len(data) - i - 1][j] = data[i][j]
data2
array([['い', 'っ', 'ち', 'ょ', ' ', 'P', 'y', 't', 'h', 'o', 'n', 'で', 'や',
'っ', 'て', 'み', 'な', 'い', 'か', '?', '\u3000'],
['そ', 'う', 'す', 'る', 'と', '、', '検', '索', 'さ', 'れ', 'に', 'く', 'く',
'な', 'る', 'ん', 'じ', 'ゃ', 'ね', '?', '\u3000'],
['こ', 'れ', 'を', '縦', '書', 'き', 'に', 'し', 'た', 'い', 'わ', 'け', 'よ',
'。', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000', '\u3000',
'\u3000'],
['普', '通', 'は', ' ', 'T', 'w', 'e', 'e', 't', ' ', 'は', '横', '書',
'き', 'な', 'ん', 'だ', 'け', 'ど', 'さ', '、']], dtype='<U1')
ここまでできれば、行列の転置を用いて縦書きにできます。
data2.T # 行列の転置
array([['い', 'そ', 'こ', '普'],
['っ', 'う', 'れ', '通'],
['ち', 'す', 'を', 'は'],
['ょ', 'る', '縦', ' '],
[' ', 'と', '書', 'T'],
['P', '、', 'き', 'w'],
['y', '検', 'に', 'e'],
['t', '索', 'し', 'e'],
['h', 'さ', 'た', 't'],
['o', 'れ', 'い', ' '],
['n', 'に', 'わ', 'は'],
['で', 'く', 'け', '横'],
['や', 'く', 'よ', '書'],
['っ', 'な', '。', 'き'],
['て', 'る', '\u3000', 'な'],
['み', 'ん', '\u3000', 'ん'],
['な', 'じ', '\u3000', 'だ'],
['い', 'ゃ', '\u3000', 'け'],
['か', 'ね', '\u3000', 'ど'],
['?', '?', '\u3000', 'さ'],
['\u3000', '\u3000', '\u3000', '、']], dtype='<U1')
転置した行列を文字列として出力
delimiter = " "
for line in data2.T:
print(delimiter.join(line))
い そ こ 普
っ う れ 通
ち す を は
ょ る 縦
と 書 T
P 、 き w
y 検 に e
t 索 し e
h さ た t
o れ い
n に わ は
で く け 横
や く よ 書
っ な 。 き
て る な
み ん ん
な じ だ
い ゃ け
か ね ど
? ? さ
、
これを、リスト内包表記を使ってスマートに書き直せばこうなります。
delimiter = " "
print("\n".join([delimiter.join(line) for line in data2.T]))
い そ こ 普
っ う れ 通
ち す を は
ょ る 縦
と 書 T
P 、 き w
y 検 に e
t 索 し e
h さ た t
o れ い
n に わ は
で く け 横
や く よ 書
っ な 。 き
て る な
み ん ん
な じ だ
い ゃ け
か ね ど
? ? さ
、
まとめ
以上の操作を yoko2tate
という関数にしてみました。
def yoko2tate(tweet, delimiter = " "):
data = [[line[i] for i in range(len(line))] for line in tweet.split("\n") if len(line) > 0]
max_length = 0
for d in data:
if max_length < len(d):
max_length = len(d)
data2 = np.full((len(data), max_length), " ")
for i in range(len(data)):
for j in range(max_length):
if j < len(data[i]):
data2[len(data) - i - 1][j] = data[i][j]
return "\n".join([delimiter.join(line) for line in data2.T])
使用例はこんな感じ。
tweet = '''\
あ...ありのまま 今 起こったことを話すぜ!
「ツイートを入力したら、縦書きになった」
な...何を言っているか分からねーと思うが、おれも何をされたのか分からなかった...
'''
print(yoko2tate(tweet))
な 「 あ
. ツ .
. イ .
. ー .
何 ト あ
を を り
言 入 の
っ 力 ま
て し ま
い た
る ら 今
か 、
分 縦 起
か 書 こ
ら き っ
ね に た
ー な こ
と っ と
思 た を
う 」 話
が す
、 ぜ
お !
れ
も
何
を
さ
れ
た
の
か
分
か
ら
な
か
っ
た
.
.
.