ファイル

菊地時夫 先生のオンラインテキストに基づく。
今回の作業は python/07で実施してください。

はじめに

  • この授業の前半では、UNIX コマンドでファイルを作ったりコピーしたり削除したりしました。
  • Python を使ったプログラムでも open() を使って、ファイルの読み書きができます。
  • ファイルの内容をプログラムで読み込むには、ファイルを「読み取りモード」で開いて、read()readline() の関数を使います。
  • 読み取りが終了したファイルは close() で 閉じます。(Python 終了時に開いているファイルは自動的に閉じられます。)

read() はファイルの中身を全部読み取ります。
>>> f = open('/etc/hosts')
>>> s = f.read()
>>> s
'##\n# Host Database\n# .....'
>>> f.close()

例(続き)

1行ずつ読み取るには readline() を使います。

>>> f = open('/etc/hosts')
>>> f.readline()
'##\n'
>>> f.readline()
'# Host Database\n'
>>> f.close()

ファイルに書き込む

ファイルを新たに作成して文字列を書き込むには、
「書き込みモード」で開いたファイルに
write('文字列')で書き込み、
最後にファイルを閉じます。

書き込みの例

>>> fw = open('aaa', 'w')
>>> fw.write('Hello, File!\n')
>>> fw.close()
>>> ^D
$ ls
aaa
$ cat aaa
Hello, File!

プログラム例

        a.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# a.py
# ファイルの中身を画面に出力する
import sys
 
fname = sys.argv[1]
# ファイルを読み出しモードで開く
f = open(fname)
while 1:
# 一行読み込む
s = f.readline()
if not s:
# ファイルの終わりを検出
break
# 標準出力に書き出す
sys.stdout.write(s)
f.close()

実行例

a.py を使って,先ほど作った aaa を画面に出してみましょう。

$ ./a.py aaa
Hello, File!

練習:a.py で a.py を画面に出してみましょう。

補足

ここでは、画面に出力するのに print でなく、sys.stdout.write() を使っていることに注意してください。
sys.stdout は標準出力のファイルオブジェクトです。
readline() で読み取った文字列には最後に ¥n (改行) が付いているので、自動的に改行を加える print でなく、write() (改行を加えない)を使っています。

プログラム例(その2)

次の例は、UNIX の cp コマンドをまねています。

           b.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# b.py
# cp コマンドを python で作る
# 書式:b.py file1 file2
import sys
 
# ファイルを読み出しモードで開く
f1 = open(sys.argv[1])
# コピー先のファイルを書き込みモードで開く
f2 = open(sys.argv[2], 'w')
while 1:
# 一行読み込む
s = f1.readline()
if not s:
# ファイルの終わりを検出
break
# 出力に書き出す
f2.write(s)
f1.close()
f2.close()

実行例

b.py を使って aaa を bbb にコピーしてみます。
$ ./b.py aaa bbb
$ ls
a.py aaa b.py bbb
$ cat bbb
Hello, File!

プログラム例(その3)

次のようなデータをファイル(fortune.dat) に作成しておくと、その次のプログラムを実行することでデータがディクショナリに読み込まれることを確かめましょう。
但し、空白文字は半角であることに注意してください

ファイル fortune.dat

いちご 幸運が訪れます
みかん 努力が必要です
りんご 我慢が必要です

プログラム

         c.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# c.py
# fortune.dat を読み取るプログラムの例
f = open('fortune.dat')
fortune = {}
while 1:
s = f.readline().strip()
if not s:
break
key, value = s.split()
fortune[key] = value
f.close()
for key in fortune.keys():
print key, fortune[key]

コメント: 8行目のstrip()は文字列のメソッドで、末尾や、先頭の空白、改行コードなどを除去することができます。
      その他の文字列メソッドも含め、こちらで確認してください。


課題


以下の問題をといて,解答(スクリプト,モジュール(添付するとともに本文にもコピー)と実行例) をメールで送ってください。
作業はpython/07のなかで行うものとし,作成したスクリプトは残しておいてください 。(評価の対象とします)。

メールあて先:           honda@is.kochi-u.ac.jp

サブジェクト名:        p6-7 kadai

締め切り       :           1/14 17:00

問題1

    a.py のユーザとの対話の部分を次の例(q1.py)のように、ループの中に入れると,何度も占いを実行できる。
    このプログラムを変更して、新しい果物名が入力 されたときには、その占いの結果をユーザーに聞いて占
    いに追加し、くりえし占いができるようにしてください。

    ヒント(ディクショナリの要素の追加を行うように、赤字のブロックを修正すればよい。。。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# q1.py
# いちご占い
print '*** いちご占い ***'
fortune = {
'いちご': '幸運が訪れます',
'みかん': '努力が必要です',
'りんご': '我慢が必要です'
}
 
while 1:
ans = raw_input('好きなフルーツの名前をどうぞ: ')
if not ans:
print '********* さようなら *********'
break
if fortune.has_key(ans):
print '%sの好きなあなたには%s.' % (ans, fortune[ans])
else:
print '%sの好きなあなたは健康に気をつけてください.' % ans
  • 次の実行例を参考にすること。
$ ./q1.py
*** いちご占い ***
好きなフルーツの名前をどうぞ: ばなな
ばななのことは知りません。教えてください: 忍耐が必要です
好きなフルーツの名前をどうぞ: ばなな
ばななの好きなあなたには忍耐が必要です.
好きなフルーツの名前をどうぞ:
********* さようなら *********
問題 2

前回のa.py を改造して、占い文を fortune.dat から取り出すようにしなさい。スクリプトはq2.py という名前で作成してください。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# a.py
# いちご占い
print '*** いちご占い ***'
fortune = {
'いちご': '幸運が訪れます',
'みかん': '努力が必要です',
'りんご': '我慢が必要です'
}
ans = raw_input('好きなフルーツの名前をどうぞ: ')
if fortune.has_key(ans):
print '%sの好きなあなたには%s.' % (ans, fortune[ans])
else:
print '%sの好きなあなたは健康に気をつけてください.' % ans

ヒント
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# a.py
# いちご占い
print '*** いちご占い ***'
#fortune.datからディクショナリを読み込むようにここに数行追加。
ans = raw_input('好きなフルーツの名前をどうぞ: ')
if fortune.has_key(ans):
print '%sの好きなあなたには%s.' % (ans, fortune[ans])
else:
print '%sの好きなあなたは健康に気をつけてください.' % ans

問題3
問題1の q1.py と  問題2の q2.py を参考にして、"占い文を fortune.dat から取り出し、ユーザーが入力した新しい占い文をデイクショナリに登録して、終了時にその占い文をfortune.datに保存する"スクリプトを作成しなさい。スクリプトの名前はq3.pyとしてください。
実行例
$ ./q3.py
*** いちご占い ***
好きなフルーツの名前をどうぞ: ばなな
ばななのことは知りません。教えてください: 忍耐が必要です
好きなフルーツの名前をどうぞ:
********* さようなら *********
$ ./q3.py
*** いちご占い ***
好きなフルーツの名前をどうぞ: ばなな
ばななの好きなあなたには忍耐が必要です.
好きなフルーツの名前をどうぞ:
********* さようなら *********



問題4  自分用に英単語テストをするスクリプトを作成せよ。(ほぼ、問い3の問題の応用でできます)

基本的には以下のような機能をもつものとするが、さらに追加機能を設けてもしてもよい

  • 前提:英単語はwordlist.txtというファイルに下記のように記入されているとする
    •        year 年
                          differential  微分
                          .......
  1. ディクショナリにwordlist.txtの内容を読み込む
  2. 英語単語を入力する、
  3. 登録が有れば日本語訳が表示される。なければ日本語訳を入力してくださいというメッセージが表示されて、ディクショナリに英語と日本語のペアを入力
  4. 次の単語に進むかどうか尋ね, 'yまたはn'で回答。yが入力されれば1にもどり、nが入力されれば、現在のディクショナリの内容をファイルに保存して終了する。
仕様、スクリプト、テスト用の単語リスト、実行結果を提出する事。
全てメールの本文に記入するが、スクリプトとテスト用の単語リストは
wordtest.py, wordlist.txtという名前として添付ファイルとしても添えてください。