ファイル入出力

ファイルに保存されたデータを読み取ったり、計算結果を書き込んだりする。

例1: 1行に一つずつ数字データの入ったファイルを読んでその数字の合計を計算する。ファイルから入力した行を 1行ずつ処理し、ファイルの終わりで終了するには、 while 1: の無限ループから if not s: break のようにして抜け出るとよい。
#!/pub/sol8/bin/python
# sum3.py

import string
import sys

def sum3(fname):
    fp = open(fname, 'r')
    sum = 0
    while 1:
        s = fp.readline()
        if not s:
            break
        print s,
        d = string.atoi(s)
        sum = sum + d
    fp.close()
    print '合計 = %d' % sum

if __name__ == '__main__':
    sum3(sys.argv[1])

例2: 0から89度までの sin の値を arc.datという名前のファイルに入れる。
#!/pub/sol8/bin/python
# sintable.py

import math

fp = open('arc.dat','w')
for i in range(90):
    s = math.sin(math.pi * i / 180.0)
    fp.write('%2d %10.8g\n' % (i, s))
fp.close()

例3: ファイルをコピーする。一度に読み込むには read()を使う。
#!/pub/sol8/bin/python
# copy.py

import sys

def copy(fname1, fname2):
    fp1 = open(fname1, 'r')
    fp2 = open(fname2, 'w')
    fp2.write(fp1.read())
    fp1.close()
    fp2.close()

if __name__ == '__main__':
    copy(sys.argv[1], sys.argv[2])

例4: grep と awk の練習問題 5 を Python で書いたもの。
#!/pub/sol8/bin/python
# topten.py

def topten(fname):
    fp = open(fname)
    # ユーザ名: アクセスカウンタ のディクショナリを作る
    access = {}
    while 1:
        s = fp.readline()
        if not s:
            break
        t = s.split()     # 文字列を空白で区切ってリストにする
        if access.has_key(t[2]):
            access[t[2]] += 1   # 3番目のフィールド(ユーザ名)をキーに
                                # カウンタに1を加える.
        else:
            access[t[2]] = 1    # キーが無いので作る
    # アクセスカウント: ユーザ名リスト のディクショナリを作る
    ranking = {}
    for i in access.keys():
        if ranking.has_key(access[i]):
            ranking[access[i]].append(i) # 同じカウントのところに
                                         # ユーザ名を追加
        else:
            ranking[access[i]] = [i]
    k = ranking.keys()
    k.sort()                    # カウンタ値を並べ替え
    k.reverse()                 # 降順にする
    for count in k[:10]:
        print '%3d %s' % (count, ranking[count])


if __name__ == '__main__':
    topten('../TX.log')


練習問題

以下の練習は、もちろん ~/coreinfo/python でおこなう。
  1. sum3.pyを作成する。
  2. 適当なデータをdataファイルに作成して、sum3.pyを使って計算する。
  3. sintable.pyを作成し、実行する。
  4. copy.py を作成し、arc.datsin.datにコピーする。
  5. topten.pyを作成し、実行する。

発展課題

次回(1/27)用の発展課題です。できれば、加点として評価します。必須点は以上の練習問題までです。

上記の topten.py では基本的な順位作成まではできるが、いくつかの点で常用するプログラムとしては不十分な点がある。以下にそのいくつかを挙げるので、topten.py を改良して top.py というファイル名にして保存しなさい。

  1. ユーザ名がわからないときは '-' になる。これを取り除く。
  2. ユーザ認証に失敗したものも含まれているため、メールアドレスとして完全でないものも含まれている。 認証に成功したものは
    tws.is.kochi-u.ac.jp - tkikuchi@is.kochi-u.ac.jp [21/Oct/2002:15:46:47 +0900] "GET /TX/register/ HTTP/1.0" 200 359
    
    のように、最後から二つ目のフィールドが '200' になっている。これを利用して、正しい ユーザのものだけを取り出す。
  3. 処理対象のログファイルが固定になっているので、これをコマンドラインで指定するようにする。
  4. 上位 10 番までを出力するようになっているが、この数字が固定なので、コマンドラインで指定する。
  5. 出力されるユーザ名がリスト形式なので [ ] に囲まれている。これをユーザ名だけを表示する。
  6. 出力の各行の最初に 順位 を入れる。但し、同順があった場合、次の順位は繰り下がるので、これを考慮すること。

<a href="http://www.is.kochi-u.ac.jp/~tkikuchi/>菊地のホームページ