素人の言語処理100本ノック:16


[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の挑戦記録です。環境はUbuntu 16.04 LTS ＋ Python 3.5.2 \:\: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧は[こちら](http://qiita.com/segavvy/items/fb50ba8097d59475f760)からどうぞ。

## 第2章: UNIXコマンドの基礎
>hightemp.txtは，日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである．以下の処理を行うプログラムを作成し，hightemp.txtを入力ファイルとして実行せよ．さらに，同様の処理をUNIXコマンドでも実行し，プログラムの実行結果を確認せよ．

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


####出来上がったコード：

```python:main.py
# coding: utf-8
import math

fname = 'hightemp.txt'
n = int(input('N--> '))

with open(fname) as data_file:
	lines = data_file.readlines()

count = len(lines)
unit = math.ceil(count / n)  # 1ファイル当たりの行数

for i, offset in enumerate(range(0, count, unit), 1):
	with open('child_{:02d}.txt'.format(i), mode='w') as out_file:
		for line in lines[offset:offset + unit]:
			out_file.write(line)
```

####実行結果：
一例として、N=5の場合の結果を載せます。
全部で24行なので、5分割すると各ファイルは5行になり、最後のファイルだけは4行になります。

```text:child_01.txt
高知県	江川崎	41	2013-08-12
埼玉県	熊谷	40.9	2007-08-16
岐阜県	多治見	40.9	2007-08-16
山形県	山形	40.8	1933-07-25
山梨県	甲府	40.7	2013-08-10
```

```text:child_02.txt
和歌山県	かつらぎ	40.6	1994-08-08
静岡県	天竜	40.6	1994-08-04
山梨県	勝沼	40.5	2013-08-10
埼玉県	越谷	40.4	2007-08-16
群馬県	館林	40.3	2007-08-16
```

```text:child_03.txt
群馬県	上里見	40.3	1998-07-04
愛知県	愛西	40.3	1994-08-05
千葉県	牛久	40.2	2004-07-20
静岡県	佐久間	40.2	2001-07-24
愛媛県	宇和島	40.2	1927-07-22
```

```text:child_04.txt
山形県	酒田	40.1	1978-08-03
岐阜県	美濃	40	2007-08-16
群馬県	前橋	40	2001-07-24
千葉県	茂原	39.9	2013-08-11
埼玉県	鳩山	39.9	1997-07-05
```

```text:child_05.txt
大阪府	豊中	39.9	1994-08-08
山梨県	大月	39.9	1990-07-19
山形県	鶴岡	39.9	1978-08-03
愛知県	名古屋	39.9	1942-08-02
```

####UNIXコマンド確認用のシェルスクリプト:

```bash:test.sh
#!/bin/sh

# Nを入力
echo -n "N--> "
read n

# 行数算出　wcは行数とファイル名を出力するのでcutで行数のみ切り出し
count=`wc --line hightemp.txt | cut --fields=1 --delimiter=" "`

# 1分割当たりの行数算出　余りがある場合は行数を+1
unit=`expr $count / $n`
remainder=`expr $count % $n`
if [ $remainder -gt 0 ]; then
	unit=`expr $unit + 1`
fi

# 分割
split --lines=$unit --numeric-suffixes=1 --additional-suffix=.txt hightemp.txt child_test_

# 検証
for i in `seq 1 $n`
do
	fname=`printf child_%02d.txt $i`
	fname_test=`printf child_test_%02d.txt $i`
	diff --report-identical-files $fname $fname_test
done
```

####結果の確認：

いくつかの結果を載せます。

N=1の場合：

```console:端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ python main.py 
N--> 1
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ ./test.sh
N--> 1
ファイル child_01.txt と child_test_01.txt は同一です
```

N=2の場合：

```console:端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ python main.py 
N--> 2
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ ./test.sh
N--> 2
ファイル child_01.txt と child_test_01.txt は同一です
ファイル child_02.txt と child_test_02.txt は同一です
```

N=5の場合：

```console:端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ python main.py 
N--> 5
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ ./test.sh
N--> 5
ファイル child_01.txt と child_test_01.txt は同一です
ファイル child_02.txt と child_test_02.txt は同一です
ファイル child_03.txt と child_test_03.txt は同一です
ファイル child_04.txt と child_test_04.txt は同一です
ファイル child_05.txt と child_test_05.txt は同一です
```

N=7の場合：

```console:端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ python main.py 
N--> 7
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ ./test.sh
N--> 7
ファイル child_01.txt と child_test_01.txt は同一です
ファイル child_02.txt と child_test_02.txt は同一です
ファイル child_03.txt と child_test_03.txt は同一です
ファイル child_04.txt と child_test_04.txt は同一です
ファイル child_05.txt と child_test_05.txt は同一です
ファイル child_06.txt と child_test_06.txt は同一です
diff: child_07.txt: そのようなファイルやディレクトリはありません
diff: child_test_07.txt: そのようなファイルやディレクトリはありません
```

今回のプログラムでは6分割しかされないので、7分割目のファイルがない旨のエラーになります。これは、全24行を7分割しようとすると1ファイル当たり4行になってしまい、6ファイルで済んでしまうロジックのためです。
もしかしたら、4行のファイルを3つと、3行のファイルを4つに分割しないといけないかも知れません。このコードだと不正解かも...^^;

N=24の場合：

```console:端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ python main.py
N--> 24
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ ./test.sh
N--> 24
ファイル child_01.txt と child_test_01.txt は同一です
ファイル child_02.txt と child_test_02.txt は同一です
ファイル child_03.txt と child_test_03.txt は同一です
ファイル child_04.txt と child_test_04.txt は同一です
ファイル child_05.txt と child_test_05.txt は同一です
ファイル child_06.txt と child_test_06.txt は同一です
ファイル child_07.txt と child_test_07.txt は同一です
ファイル child_08.txt と child_test_08.txt は同一です
ファイル child_09.txt と child_test_09.txt は同一です
ファイル child_10.txt と child_test_10.txt は同一です
ファイル child_11.txt と child_test_11.txt は同一です
ファイル child_12.txt と child_test_12.txt は同一です
ファイル child_13.txt と child_test_13.txt は同一です
ファイル child_14.txt と child_test_14.txt は同一です
ファイル child_15.txt と child_test_15.txt は同一です
ファイル child_16.txt と child_test_16.txt は同一です
ファイル child_17.txt と child_test_17.txt は同一です
ファイル child_18.txt と child_test_18.txt は同一です
ファイル child_19.txt と child_test_19.txt は同一です
ファイル child_20.txt と child_test_20.txt は同一です
ファイル child_21.txt と child_test_21.txt は同一です
ファイル child_22.txt と child_test_22.txt は同一です
ファイル child_23.txt と child_test_23.txt は同一です
ファイル child_24.txt と child_test_24.txt は同一です
```

N=25の場合：

```console:端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ python main.py
N--> 25
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/16$ ./test.sh
N--> 25
ファイル child_01.txt と child_test_01.txt は同一です
ファイル child_02.txt と child_test_02.txt は同一です
ファイル child_03.txt と child_test_03.txt は同一です
ファイル child_04.txt と child_test_04.txt は同一です
ファイル child_05.txt と child_test_05.txt は同一です
ファイル child_06.txt と child_test_06.txt は同一です
ファイル child_07.txt と child_test_07.txt は同一です
ファイル child_08.txt と child_test_08.txt は同一です
ファイル child_09.txt と child_test_09.txt は同一です
ファイル child_10.txt と child_test_10.txt は同一です
ファイル child_11.txt と child_test_11.txt は同一です
ファイル child_12.txt と child_test_12.txt は同一です
ファイル child_13.txt と child_test_13.txt は同一です
ファイル child_14.txt と child_test_14.txt は同一です
ファイル child_15.txt と child_test_15.txt は同一です
ファイル child_16.txt と child_test_16.txt は同一です
ファイル child_17.txt と child_test_17.txt は同一です
ファイル child_18.txt と child_test_18.txt は同一です
ファイル child_19.txt と child_test_19.txt は同一です
ファイル child_20.txt と child_test_20.txt は同一です
ファイル child_21.txt と child_test_21.txt は同一です
ファイル child_22.txt と child_test_22.txt は同一です
ファイル child_23.txt と child_test_23.txt は同一です
ファイル child_24.txt と child_test_24.txt は同一です
diff: child_25.txt: そのようなファイルやディレクトリはありません
diff: child_test_25.txt: そのようなファイルやディレクトリはありません
```

全部で24行しかないので、25分割はできません。このエラーは仕方ないかと思います。

今回はpythonよりもシェルスクリプトに苦労しましたが、少し慣れてきました。`printf`というコマンドまであることを知って、UNIXコマンドの多彩さに驚いています。
　
17本目のノックは以上です（いつも最後に書いているノックの本数が1本ずれていませんか？とのご指摘をいただきましたが、このノックの最初の問題番号は0なので、問題番号とは1本ずれています）。誤りなどありましたら、ご指摘いただけますと幸いです。