必要知識
標準入出力
ファイルの開き方、読み込み方
例外処理の仕方
Listの使い方
ファイルの書き込み方
注意点
正常な動作はテストしましたが、保証は致しかねます。
あくまでも以下に掲載するソースコードは解答例として参考にして頂き、
ご自身で、「何故こう動くのか」という事を意識した上で一行一行読んでいただけたら幸いです。
以下、ソースコード(解答例)
Python
1 import sys
2
3 # ファイル名を聞く
4 print ( "Please enter a file name" )
5 file_name = input ( )
6
7 try :
8 # ファイルを開けてみる
9 file = open ( file_name , "r" )
10 except IOError :
11 # 開けれないならエラーを出力し、IO閉じて、エラーコードを返し終了
12 print ( file_name + " is not found" )
13 sys . exit ( 1 )
14
15 # 読み込んだファイルを一行ずつリストに入れる
16 file_rows = file . readlines ( )
17 # IOをクローズする
18 file . close ( )
19
20 # 何行目から読み込みたいか聞く
21 # 読み込み直後にint型へ変換し、配列インデックスに合せ-1しとく
22 print ( "What line does start row say that?" )
23 start_row = int ( input ( ) ) - 1
24
25 try :
26 # 指定された行にアクセスしてみる
27 _ = file_rows [ start_row ]
28 except IndexError :
29 # アクセスできないならエラーを出力し、エラーコードを返し終了
30 print ( "The row is not found" )
31 sys . exit ( 1 )
32
33 # 書き込み用にファイルを開く。本来であれば例外処理すべきだが指定が無いのであえてそのまま
34 # 尚、"a"は追記モード
35 new_file = open ( "count_" + file_name , "a" )
36
37 # 100回繰り返す、iには0、1、2、...98、99の順で値が入る
38 for i in range ( 100 ) :
39 try :
40 # 指定行の内容を変数にいれとく
41 current_row = file_rows [ start_row + i ]
42 except IndexError :
43 # もし100行満たす前に最後の行まで来てしまったら
44 # IOクローズして正常終了
45 new_file . close ( )
46 sys . exit ( 0 )
47
48 # 現在行の内容をスペースで区切ってリスト化しその要素数を求める(=単語数を求める)
49 current_row_word_len = len ( current_row . split ( ) )
50
51 # 単語数を追加した、新しいファイルに書き込むための行を構築する
52 current_row = str ( current_row_word_len ) + " words | " + current_row
53 # ファイルに書き込む
54 new_file . write ( current_row )
55
56 #IOを閉じる
57 new_file . close ( )
58 #正常終了
59 sys . exit ( 0 )
仕様
ファイル名を標準入力で受け付け開きます。存在しない場合は終了します。
何行目から読み込むか標準入力で受け付けます。存在しない行が指定された場合は終了します。
指定された行から100行、単語数のカウント を行先頭に追記したファイルを「count_元ファイル名」で保存します。
指定された行から、元ファイルの最後行が100行未満の場合は、最後行まで上述の処理を行います。
追加質問回答
追加質問①
一つ目は単語の数の表示なのですが、
I am a Japanese. (4)
このように表示するにはどうすればいいのでしょうか?
回答欄ソースコード、コメント,空行を除く、下から4行目あたりに
current_row = str(current_row_word_len) + " words | " + current_row
というコードがあるのは分かりますか?
この部分で、current_row
には最初、元のテキストのある一行がそのまま入ってますが、これに文字列結合でただ単語数を追加してるだけです!
まず、
python
1 current_row = str ( current_row_word_len ) + " words | " + current_row
この行は、current_row
へ「何か」を代入する行というのはお分かりいただけると思います。
そして、その「何か」、すなわち、
str(current_row_word_len) + " words | " + current_row
は何をしているかというと、
次に以下3つを結合しています。
str(current_row_word_len)
current_row_word_lenを文字列型へ変換したもの
words |
単純な文字列
current_row
文字列型変数(現在処理中の元ファイルの行の文字列)
それら結合した物を、current_row
へぶち込みなおす処理をしてます。
なので、I am a Japanese. (4)
という表示にしたければ
python
1 current_row = current_row + " (" + str ( current_row_word_len ) + ")"
で、いけそうですが、無理です。(私はこれでいけると思った・・・)
なぜならば、current_row
の一番最後の文字に改行コードが入ってしまっています。
よって、以下のようにcurrent_row最後の改行を消して、さらに改行コードを連結すればいけます。
python
1 current_row = current_row . rstrip ( '\n' ) + " (" + str ( current_row_word_len ) + ")\n"
ポイントとしては
current_row.rstrip('\n')
で改行コードを消してる
")\n"
で最後にカッコを閉じるだけでなく改行を入れてあげる
です。
追加質問②
二つ目は
python
1 try :
2 # 指定された行にアクセスしてみる
3 _ = file_rows [ start_row ]
の初めの_の部分はどういうことを表しているのでしょうか?
これは特にPythonでは意味は無いです。紛らわしくてごめんなさい。
一部のプログラミング言語では、ブランク識別子等と呼ばれ、要は捨てるための変数と考えて頂けると分かりやすいです。
ただ、Pythonにはその概念が無いのでこのようにして使いました。
もっとスマートなやり方あれば教えてください笑
今回の場合、別に今すぐにはfile_rows[start_row]
に対して用事は無いけど、
もし存在しなかったら困るから念のためtry:
の中でいったんアクセスしてみる、ために使ってます。