1. segavvy

    Posted

    segavvy
Changes in title
+素人の言語処理100本ノック:16
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,237 @@
+
+[言語処理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)からどうぞ。
+
+## 第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本ずれています)。誤りなどありましたら、ご指摘いただけますと幸いです。