13 : 言語処理100本ノックでPythonのお勉強

第二章 : 13 col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

コードはこんな感じ。

f1 = 'col1.txt'
f2 = 'col2.txt'
f3 = 'output.txt'

with open(f1) as file1, open(f2) as file2, open(f3, 'w') as out_file:
    for f1_line, f2_line in zip(file1, file2):
        out_file.write(f1_line.rstrip() + '\t' + f2_line.rstrip() + '\n')

rstrip()関数は各行の末尾の改行コードを削除するために使っています。

Unixコマンドだと以下のようにできます。

paste col1.txt col2.txt >output.txt

Qiitaのこちらの記事を参考にしています。

12 : 言語処理100本ノックでPythonのお勉強

第二章 : 12 1列目をcol1.txtに、2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ

コードはこんな感じ。

f = 'hightemp.txt'
f1 = 'col1.txt'
f2 = 'col2.txt'

with open(f) as file, open(f1, 'w') as file1, open(f2, 'w') as file2:
    for line in file:
        cols = line.split('\t')
        file1.write(cols[0] + '\n')
        file2.write(cols[1] + '\n')

open()関数の第2引数'w'がないとファイルが無い場合、新規にファイルを作成してくれません。プログラムの中で新規ファイルを作成する場合、忘れないように注意せねば。

Unixコマンドで行なう場合はcutを使います。

# 1列目をカットして新規ファイルに。
$ cut -f 1 hightemp.txt > col1.txt
# 2列目をカットして新規ファイルに。
$ cut -f 2 hightemp.txt > col2.txt

Qiitaのこちらの記事を参考にしています。

11 : 言語処理100本ノックでPythonのお勉強

第二章 : 11 タブをスペースに置換せよ

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

sedコマンドを使ってファイル中の文字を置換します。当方macOS10.12 Sierraを使っているため、 sedコマンドではなく、gsedコマンドを使います。macではこっちを使ったほうがいいみたい。 あまり詳しくは調べてません。こちらでチェックしました。

$ wget 'hightemp.txt'   
$ gsed -i 's/\t/ /g' hightemp.txt

pythonでも処理を書いてみました。

f = 'hightemp.txt'
result = []

with open(f, mode='r') as data:
    for line in data:
        line = line.replace('\t', ' ')
        result.append(line)

with open(f, mode='w') as data:
    data.writelines(result)

10 : 言語処理100本ノックでPythonのお勉強

第二章 : 10 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

今回から「第二章:UNIXコマンドの基礎」に入りました。unixコマンドで行数をカウントするだけならとても簡単で、以下のように書くと表示されます。ファイルを使うのでこちらもダウンロードしておきます。

ちなみにwcコマンドはファイルの中の行数や文字数を調べるために利用します。

$ wget http://www.cl.ecei.tohoku.ac.jp/nlp100/data/hightemp.txt
$ wc -l hightemp.txt

pythonの使い方に慣れたいので、pythonでファイルを処理するコードも書いてみます。

thisfile = 'hightemp.txt'
count = 0

with open(thisfile) as data:
    for line in data:
        count += 1

    print(count)

09 : 言語処理100本ノックでPythonのお勉強

第一章 : 09 Typoglycemia

スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ.ただし,長さが4以下の単語は並び替えないこととする.適当な英語の文(例えば"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .")を与え,その実行結果を確認せよ.

Typoglycemiaとは、ニコニコ大百科に以下の用に書かれている。

Typoglycemiaとは、単語を構成する文字を並べ替えても、最初と最後の文字が合っていれば読めてしまう現象のことである。
[例え]
こんちには みさなん おんげき ですか? わしたは げんき です。 この ぶんょしう は いりぎす の ケブンッリジ だがいく の けゅきんう の けっか にんんげ は もじ を にしんき する とき その さしいょ と さいご の もさじえ あいてっれば じばんゅん は めくちちゃゃ でも ちんゃと よめる という けゅきんう に もづいとて わざと もじの じんばゅん を いかれえて あまりす。 どでうす? ちんゃと よゃちめう でしょ? ちんゃと よためら はのんう よしろく

文字が入れ替わっていてもなんか読めちゃいますね。これは欧米人が英語を読んでも同様のようです。 今回のプログラムはTypoglycemiaに変換する関数を書きます。 プログラムはこのような感じになりました。

import random

def typoglycemia(sentence):
    result_list = []
    sentence_list = sentence.split(' ')
    for i in range(len(sentence_list)):
        if len(sentence_list[i]) > 4:
            word = sentence_list[i]
            first = word[0]
            last = word[-1]
            middle = word[1:-1]
            rand_middle = random.sample(middle, len(middle))
            rand_middle = ''.join(rand_middle)
            word = first + rand_middle + last
            result_list.append(word)
        else:
            result_list.append(sentence_list[i])
    result_sentence = ' '.join(result_list)
    return result_sentence

l = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."
print(typoglycemia(l))

上の書き方はいろいろ微妙なので、ネットで調べた内容を参考に以下のように書き換えました。

import random

def typoglycemia(sentence):
    '''
    param : 対象の文字列
    return : 変換した文字列
    '''
    result = []
    for word in sentence.split(' '):
        if len(word) <= 3:
            result.append(word)
        else:
            w_list = list(word[1:-1])
            random.shuffle(w_list)
            result.append(word[0] + ''.join(w_list) + word[-1])

    return ' '.join(result)

target = input('文字列を入力してください。\n')

result = typoglycemia(target)
print('変換結果\n' + result)

こちらを参考にしました。というかほぼ同じです。ありがとうございました。

素人の言語処理100本ノック:09 - Qiita

08 : 言語処理100本ノックでPythonのお勉強

第一章 : 08 暗号文

与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ.
- 英小文字ならば(219 - 文字コード)の文字に置換
- その他の文字はそのまま出力
この関数を用い,英語のメッセージを暗号化・復号化せよ.

プログラムはこんな感じになりました。

# ord()関数はアスキーコードを取得します。
# chr()関数はアスキーコードを文字に変換します。

def cipher(t):
    result = ''
    for c in t:
        if c.islower():
            result += chr(219 - ord(c))
        else:
            result += c
    return result

t = "helloworld"

# 暗号化
coded = cipher(t)
print('暗号化:' + coded)

# 復号化
decoded = cipher(coded)
print('復号化:' + decoded)
   

07 : 言語処理100本ノックでPythonのお勉強

第一章 : 07 テンプレートによる文作成

引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ.さらに,x=12, y="気温", z=22.4として,実行結果を確認せよ.

pythonではテンプレートによる文を作成する場合、format()関数を使うと簡単に書ける。

プログラムなこんな感じになります。

def f(x, y, z):
    result = "{0}時の{1}は{2}".format(x ,y ,z)
    return result

print(f(x=12,y="気温",z=22.4))