Python学習【365日チャレンジ!】107日目のマスターU(@Udemy11)です。
ドラマの【JIN-仁-】と漫画の【JIN-仁-】の結末が違いすぎて、なんとも言えない気持ちになってしまいました。
確かに同じ結末にするのは芸がないのですが、ほんとにそれでいいの?なんて思えてくる結末で、ちょっと残念なような悲しいような。。。
まー、寝不足になりながらもすべて観終えたので、これでPython学習に集中できます。
ということで、今日もPython学習をはじめていきましょう!
昨日の復習
昨日は、オブジェクト指向でJarvis
クラスを作成しました。
クラスと関数の骨組みだけなら次のようなコードになります。
import csv
class Jarvis(object):
def say_hello(self):
# 質問1
def ask_main(self):
# 質問2
def __del__(self):
# お礼の挨拶とCSVへの書き込み
if __name__ =='__main__':
jarvis = Jarvis()
jarvis.say_hello()
jarvis.ask_main()
del jarvis
Jarvis
に質問をさせて、CSVファイルに取得したデータを書き込むという感じでしたね。
昨日出来上がったコードはこちらをごらんください。
それでは、2人目の質問をカバーするコードを書いていきましょう。
使用するライブラリ
1人目、2人目の質問までをカバーするのに必要なライブラリは次の2つ。
- csvライブラリ
- osライブラリ
CSVファイルを扱うライブラリとファイルの存在を確認するためのライブラリです。
__init__(self)の追加
1人目限定のJarvis
と大きく違うのは、__init__(self)
で初期化処理を入れるところです。
最初の質問の回答を取得するための関数input
は__init__
に入れることはできませんでした。
初期化ですることは、ranking.csv
の有無の確認と、データの取得です。
def __init__(self):
self.check = os.path.exists('ranking.csv')
if self.check is True:
with open('ranking.csv', 'r') as rank_csv:
ranking = csv.DictReader(rank_csv)
for k in ranking:
self.r_sport = k['NAME']
まずos.path.exists()
でself.check
にTrue
かFalse
が代入されます。
クラスJarvis
内の関数で共通に使えるように、必要な変数にはself.
をつけています。
ファイルの有無を確認して、ファイルが存在する場合は、csv.DictWriter
を使って、値を取得しています。
名前を聞く質問
最初のあいさつと名前を聞く質問は、一人目のコードと同じです。
def say_hello(self):
name = input('こんにちは。わたしはジャービスです。あなたの名前を教えてください。\n')
self.c_name = name.title()
return self.c_name
取得した値の先頭の文字を大文字にして、関数の返り値をself.c_name
にしています。
次の質問
次の質問はranking.csv
に保存されているスポーツをおすすめして、好きかどうかたずねます。
答えはYes
でもNo
でも次の質問へいくので、それ以外の回答はないという前提で、条件分岐をつけませんでした。
def y_or_n(self):
y_n = input('\nわたしのおすすめのスポーツは{}です。\n
あなたはこのスポーツが好きですか? [Yes/No]\n'.format(self.r_sport))
ただ質問をして、なにか入力してもらうだけの関数ですね。
メインの質問
次は、メインの大好きなスポーツを尋ねる質問です。
def ask_main(self):
like_sports = input('\n{}さん、あなたの好きなスポーツは何ですか?\n英語で答えてください\n'.format(self.c_name))
self.c_like_sports = like_sports.title()
return self.c_like_sports
この質問で取得した値は、1人目のスポーツとは違うという前提で、ranking.csv
に追記します。
CSVへの書き込み
ranking.csv
への書き込みですが、__init__
で取得したself.check
がTrue
の場合は、前の質問で取得したself.c_link_sports
を追記して、False
の場合は、新しくranking.csv
を作成して書き込みます。
def write_csv(self):
if self.check is True:
with open('ranking.csv', 'a') as rank_csv:
fieldnames = ('NAME', 'COUNT')
writer = csv.DictWriter(rank_csv, fieldnames=fieldnames)
writer.writerow({'NAME': self.c_like_sports, 'COUNT': 1})
else:
with open('ranking.csv', 'w') as rank_csv:
fieldnames = ('NAME', 'COUNT')
writer = csv.DictWriter(rank_csv, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'NAME': self.c_like_sports, 'COUNT': 1})
デストラクタで出力
最後のあいさつは、デストラクタでprint
出力します。
def __del__(self):
print('\n{}さん、回答ありとうございました。\n良い1日をお過ごし下さい!'.format(self.c_name))
完成コード
Javis
クラスに関数を6つ持たせたので、最後にオブジェクトを作成して、関数を実行するコードを追記します。
import csv
import os
class Jarvis(object):
def __init__(self):
self.check = os.path.exists('ranking.csv')
if self.check is True:
with open('ranking.csv', 'r') as rank_csv:
ranking = csv.DictReader(rank_csv)
for k in ranking:
self.r_sport = k['NAME']
def say_hello(self):
name = input('こんにちは。わたしはジャービスです。あなたの名前を教えてください。\n')
self.c_name = name.title()
return self.c_name
def y_or_n(self):
y_n = input('\nわたしのおすすめのスポーツは{}です。\nあなたはこのスポーツが好きですか? [Yes/No]\n'.format(self.r_sport))
def ask_main(self):
like_sports = input('\n{}さん、あなたの好きなスポーツは何ですか?\n英語で答えてください\n'.format(self.c_name))
self.c_like_sports = like_sports.title()
return self.c_like_sports
def write_csv(self):
if self.check is True:
with open('ranking.csv', 'a') as rank_csv:
fieldnames = ('NAME', 'COUNT')
writer = csv.DictWriter(rank_csv, fieldnames=fieldnames)
writer.writerow({'NAME': self.c_like_sports, 'COUNT': 1})
else:
with open('ranking.csv', 'w') as rank_csv:
fieldnames = ('NAME', 'COUNT')
writer = csv.DictWriter(rank_csv, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'NAME': self.c_like_sports, 'COUNT': 1})
def __del__(self):
print('\n{}さん、回答ありとうございました。\n良い1日をお過ごし下さい!'.format(self.c_name))
if __name__ == '__main__':
jarvis = Jarvis()
jarvis.say_hello()
if jarvis.check is True:
jarvis.y_or_n()
jarvis.ask_main()
jarvis.write_csv()
del jarvis
ファイルがインポートされたときのためにif __name__ == '__main__':
を使います。
ranking.csv
が存在したときのみ、45行目と46行目でJarvis
がおすすめするスポーツが好きかどうか尋ねる質問を実行します。
昨日書いたコードでは、デストラクタにCSVを作成するコードを入れていましたが、書き込みが2つのパターンになるため、write_csv()
関数に切り分けてみました。
書き方はいろいろ
今回は、初期化作業を入れてコードを書きましたが、ファイルの存在をチェックするための関数を一つ作っても問題ないかもしれません。
CSVへの書き込みは、デストラクタに入れてしまっても大丈夫だし、コードの書き方は違っても同じ動作をさせることができます。
正解はないわけなので、間違いを恐れず、どんどん違うコードを書くようにしましょう!
では、明日もGood Python!