言語処理１００本ノックをやる 1章,2章,3章

はい、やります。
00,文字列"stressed"の文字を逆に並べた文字列を得よ

```
mozi="stressed"
new_mozi_list=list(reversed(mozi))
#これはリストが表示される
new_mozi=''.join(list(reversed(mozi)))
print(new_mozi)

desserts
```

```
mozi="stressed"
print(mozi[::-1])
```
こっちのほうが楽だったっぽい
01,パタトクカシーという文字列の1,3,5,7番目をとりだして連結した文字列を得よ

```
mozi="パタトクカシー"
mozi_list=list(mozi)
new_mozi=''.join(mozi_list[1::2])
print(new_mozi)

タクシー
```
02,パトカーとタクシーの文字を先頭から交互に連結してパタトクカシーを得よ

```
mozi1="パトカー"
mozi2="タクシー"
ans=""
for x in range(4):
    ans+=mozi1[x]
    ans+=mozi2[x]
print(ans)

パタトクカシー
```

```
mozi="パタトクカシーー"
print(mozi[1::2])
```
03,"Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."という文を単語に分解し，各単語の（アルファベットの）文字数を先頭から出現順に並べたリストを作成せよ．

```
target = 'Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.'
result = []

words = target.split(' ')
for word in words:
    result.append(len(word) - word.count(',') - word.count('.'))

print(result)

[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]
```

```
target = 'Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.'
result = []

words = target.split(' ')
for word in words:
    count = 0
    for char in word:
        if char.isalpha():
            count += 1
    result.append(count)

print(result)
```
isalphaを使う方法

04元素"Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."という文を単語に分解し，1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字，それ以外の単語は先頭に2文字を取り出し，取り出した文字列から単語の位置（先頭から何番目の単語か）への連想配列（辞書型もしくはマップ型）を作成せよ．

```
key="Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
key2=list(key.split())
print(key2)
ans={}
one=[0,4,5,6,7,8,14,15,18]
for i in range(len(key2)):
    if i in one:
        ans[key2[i][0]]=i
    else:
        ans[key2[i][0:2]]=i
print(ans)
```
05与えられたシーケンス（文字列やリストなど）からn-gramを作る関数を作成せよ．この関数を用い，"I am an NLPer"という文から単語bi-gram，文字bi-gramを得よ．

n-gramってなんやねん調べるか
任意の文字列や文書を連続したn個の文字で分割するテキスト分割方法．特に，nが1の場合をユニグラム（uni-gram），2の場合をバイグラム（bi-gram），3の場合をトライグラム（tri-gram）と呼ぶ．
らしい。https://qiita.com/segavvy/items/4e592dea2f828e5385ff
このサイトに簡単にまとめてくれていた

```
def n_gram(target,n):
    return [target[idx:idx+n] for idx in range(len(target)-n+1)]
target="I am an NLPer"
print(n_gram(target,2))
#文字bi-gram
words=target.split(' ')
print(n_gram(words,2))
#単語bi-gram
```
06"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ．

```
def n_gram(target,n):
    return [target[idx:idx+n] for idx in range(len(target)-n+1)]
x="paraparaparadise"
y="paragraph"
X=n_gram(x,2)
Y=n_gram(y,2)
X=set(X)
Y=set(Y)
#setでリストから集合に変える
print(X|Y)#和集合
print(X&Y)#積集合
print(X-Y)#差集合
print("se" in X)
print("se" in Y)
```

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

```
def fuck(x,y,z):
    return str(x)+'時の'+y+"は"+str(z)
print(fuck(12,"気温",22.4))
```
08 与えられた文字列の各文字を，以下の仕様で変換する関数cipherを実装せよ．
英小文字ならば(219 - 文字コード)の文字に置換
その他の文字はそのまま出力
この関数を用い，英語のメッセージを暗号化・復号化せよ．

```
def cipher(s):
    result=''
    for word in s:
        if word.islower():
            result+=chr(219-ord(word))
        else:
            result+=word
    return result
traget=input('文字列を入力してください--> ')
#暗号化
result=cipher(target)
print('暗号化:'+result)
#復号化
result2=cipher(result)
print('復号化:'+result2)
#復号化で元に戻っているかチェック
if result2!=target:
    print('ふぁっく')
```
09 スペースで区切られた単語列に対して，各単語の先頭と末尾の文字は残し，それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ．ただし，長さが４以下の単語は並び替えないこととする．適当な英語の文（例えば"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."）を与え，その実行結果を確認せよ．

```
import random 
def Typoglycemia(target):
    ans=[]
    for i in target.split():
        if len(i)<=4:
            ans.append(i)
        else:
            chr_list=list(i[1:-1])
            random.shuffle(chr_list)
            ans.append(i[0]+''.join(chr_list)+i[-1])
    return ' '.join(ans)
target = input('文字列を入力してください--> ')
result=Typoglycemia(target)
print(result)
```

2章　なんかubuntuとかいうのをインストールする必要があるっぽいのでインストールした
10 行数のカウント
行数をカウントせよ。確認にはwcコマンドを用いよ

```
f=open("hightemp.txt","r",encoding="utf-8")
print(len(f.readlines()))
f.close()
```
open()はファイルオブジェクトを取得する関数です。第一引数には対象のファイル名、第二引数にはオブジェクトを取得する際のモードを指定する。このプログラムではファイルを読み込んで操作するのでrモードを指定した(実はデフォルトでrが指定されているが)
readlines()はopen()関数のメソッドで読み込んだ関数をリストにして返す

```
fname='hightemp.txt'
count=0
with open(fname,"r",encoding="utf-8") as data_file:
    for line in data_file:
        count+=1
print(count)

f.close()
```
with openを使う書き方

```
wc -l hightemp.txt
```

```
wc --line hightemp.txt
```
wcはファイルのバイト数、行数、文字数または単語数をカウントするコマンド。-lをオプションに指定すると、ファイルの行数を数えることができます。

11 タブをスペースに置換

```
f = open("hightemp.txt", "r",encoding="utf-8")
print(f.read().replace("\t"," "),end="")
f.close()
```

```
fname = 'hightemp.txt'
with open(fname,encoding="utf-8") as data_file:
    for line in data_file:
        print(line.replace('\t',' '),end='')
```
```
# sedのsコマンド： s/検索パターン/置換文字列/g（すべて置換）
sed 's/\t/ /g' hightemp.txt
```
```
# trコマンド 
tr '\t' ' ' < hightemp.txt
#二つの文字を指定すれば置換してくれる
```
```
# expandコマンド
expand --tabs=1 hightemp.txt
#タブを空白に変換するもの
```
12 1列目をcol1.txtに、2列目をcol2.txtに保存

```
fname='hightemp.txt'
with open(fname,encoding="utf-8") as data_file, \
        open('col1.txt',mode='w') as col1_file,\
        open('col2.txt',mode='w') as col2_file:
    for line in data_file:
        cols=line.split('\t')
        col1_file.write(cols[0]+'\n')
        col2_file.write(cols[1]+'\n')
```

```
# col1の抽出と比較
cut --fields=1 hightemp.txt > col1_test.txt
diff --report-identical-files col1.txt col1_test.txt

# col2の抽出と比較
cut --fields=2 hightemp.txt > col2_test.txt
diff --report-identical-files col2.txt col2_test.txt
```

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

```
fname='hightemp.txt'
with open(fname,encoding="utf-8") as data_file, \
        open('col1.txt',mode='w') as col1_file,\
        open('col2.txt',mode='w') as col2_file:
    for line in data_file:
        cols=line.split('\t')
        col1_file.write(cols[0]+'\n')
        col2_file.write(cols[1]+'\n')
```

```
# マージ
paste col1.txt col2.txt > merge_test.txt

# 比較
diff --report-identical-files merge.txt merge_test.txt
```

13 
自然数Nをコマンドライン引数などの手段で受け取り，入力のうち先頭のN行だけを表示せよ．確認にはheadコマンドを用いよ．

```
fname='hightemp.txt'
n=int(input('N-->'))
with open(fname,encoding="utf-8") as data_file:
    cnt=0
    for line in data_file:
        if cnt>=n:
            break
        print(line.rstrip())
        cnt+=1
```
14 自然数Nをコマンドライン引数などの手段で受け取り，入力のうち末尾のN行だけを表示せよ．確認にはtailコマンドを用いよ．

```
fname = 'hightemp.txt'
n=int(input('N--> '))
if n>0:
    with open(fname,encoding="utf-8") as data_file:
        lines=data_file.readlines()
        #ファイルの内容を1行ずつ読み込み内容をリストに格納
    for line in lines[-n:]:
        print(line.rstrip())
```

```
echo -n "N--> "
read n

# 切り出し
tail --lines=$n hightemp.txt
```

16 自然数Nをコマンドライン引数などの手段で受け取り，入力のファイルを行単位でN分割せよ．同様の処理をsplitコマンドで実現せよ．

```python
import math
fname='hightemp.txt'
n=int(input('N-->'))
with open(fname,encoding="utf-8") as data_file:
    lines=data_file.readlines()

count=len(lines)
unit=math.ceil(count/n)

for i,offset in enumerate(range(0,count,unit),1):
    with open('child_{:02d}.txt'.format(i),encoding="utf-8",mode='w') as  out_file:
        for line in lines[offset:offset+unit]:
            out_file.write(line)
```
17
1列目の文字列の種類（異なる文字列の集合）を求めよ．確認にはsort, uniqコマンドを用いよ．
```
fname='hightemp.txt'
with open(fname,encoding="utf-8") as data_file:
    set_ken=set()
    for line in data_file:
        cols=line.split('\t')
        set_ken.add(cols[0])

for n in set_ken:
    print(n)
```

18
各行を3コラム目の数値の逆順で整列せよ（注意: 各行の内容は変更せずに並び替えよ）．確認にはsortコマンドを用いよ（この問題はコマンドで実行した時の結果と合わなくてもよい）．

```
fname='hightemp.txt'
lines=open(fname,encoding="utf-8").readlines()
lines.sort(key=lambda line: float(line.split('\t')[2]),reverse=True)

for line in lines:
    print(line,end='')
```
 19 
各行の1列目の文字列の出現頻度を求め，その高い順に並べて表示せよ．確認にはcut, uniq, sortコマンドを用いよ．

```
from itertools import groupby
fname='hightemp.txt'
lines=open(fname,encoding="utf-8").readlines()
#都道府県名の読み込み
kens=[line.split('\t')[0] for line in lines]
#都道府県で集計し、（都道府県、出現頻度)のリスト作成
kens.sort()
result=[(ken,len(list(group))) for ken,group in groupby(kens)]

result.sort(key=lambda ken:ken[1],reverse=True)

for ken in result:
    print('{ken}({count})'.format(ken=ken[0],count=ken[1]))
    
```
20

```
import gzip
import json
fname='jawiki-country.json.gz'

with gzip.open(fname,'rt',encoding="utf-8") as data_file:
    for line in data_file:
        data_json=json.loads(line)
        if data_json['title']=='イギリス':
            print(data_json['text'])
            break
```
20

```python
import gzip
import json
import re

def read_wiki(fname,tiltle):
    with gzip.open(fname,'rt',encoding="utf-8") as data_file:
        #ファイルを解凍しつつ読み込む
        for line in data_file:
            data_json=json.loads(line)
            if data_json['title']== tiltle:
                #タイトルが'イギリス'のテキストを返す
                return data_json['text']

def is_category(string):
    #カテゴリー行を正規表現で判定
    return re.match(r'^\[\[Category:.+\]\]',string)

def main():
    fname='jawiki-country.json.gz'
    text=read_wiki(fname,'イギリス').split('\n')
    
    #カテゴリの行を表示する
    for line in text:
        if is_category(line):
            print(line)
main()
```