参考資料としても紹介しているPythonの入門本をやっています。そこで、対話型のボットをゴリゴリ作っているので、ソースコードに自分の解釈をコメントアウトで入れたものをアウトプットします。
やっていること
メインのソースコードは、pybot.py です。ここから、様々な関数をimportするために外部ファイルを用意しています。(eto.py, date_time.py, random_random.py)
その中で、
- if文(条件分岐)
- for文(繰り返し)
- 辞書
- 関数(def)
- 例外処理( try ~ except と isdigit()メソッド)
- ユーザーからのコマンドを受け付け、そのコマンドに対応したレスポンスをボットが返す
といったあたりを行っています。
コードとコメントアウトを見ながらで理解できるようにしておりますので、超入門で(Pythonって、こんな感じなんだ〜)が分かってもらえると嬉しいです。
pybot.py
# eto.pyで定義した、eto_command関数を利用できるようにする。
from eto import eto_command
# random.pyで定義した、choice_command関数とdice_command関数を利用できるようにする。
from random_random import choice_command, dice_command
# datetime.pyで定義した、today_command関数とnow_command関数とweekday_command関数を利用できるようにする。
from date_time import today_command, now_command, weekday_command
def heisei_command(command):
# 文字列を分割して、それぞれ heisei, year_str に代入
heisei, year_str = command.split()
# try ~ except : year_str に数字の文字列以外が入力された際の例外処理
#try:
# try ~ except を使わずに例外処理を作る。 isdigit()メソッド
if year_str.isdigit():
# int型に変換した year_strを year に代入
year = int(year_str)
if year >= 1989 and year < 2020:
heisei_year = year - 1988
response = '西暦{}年ハ、平成{}年デス'.format(year, heisei_year)
else:
response = '西暦{}年ハ、平成デハアリマセン...'.format(year)
# 例外として、以下をレスポンスさせる。
#except ValueError:
# try ~ except ではなく、elseで例外処理
else:
response = '数値ヲ指定シテクダサイ'
return response
def len_command(command):
# 文字列を分割して、それぞれ heisei, year_str に代入
cmd, text = command.split()
# int型に変換した year_strを year に代入
length = len(text)
response = '文字列ノ長サハ {} 文字デス'.format(length)
return response
# 別ファイル hello.txt をUTF-8でファイルオープン
command_file = open('hello.txt', encoding='utf-8')
# 開いたファイルを読む
raw_data = command_file.read()
# 読んだファイルを閉じる
command_file.close()
# 行ごとの文字列に分割し、linesに代入
lines = raw_data.splitlines()
# 挨拶用の空の辞書を作成
bot_dict = {}
for line in lines:
word_list = line.split(',')
key = word_list[0]
response = word_list[1]
bot_dict[key] = response
while True:
command = input('pybot> ')
response = ""
try:
for key in bot_dict:
if key in command:
response = bot_dict[key]
break
# もし平成が含まれていたら
if '平成' in command:
response = heisei_command(command)
# もし長さが含まれていたら
if '長さ' in command:
response = len_command(command)
# もし 干支 が含まれていたら
if '干支' in command:
response = eto_command(command)
# もし 選ぶ が含まれていたら
if '選ぶ' in command:
response = choice_command(command)
# もし さいころ が含まれていたら
if 'さいころ' in command:
response = dice_command()
# もし 今日 が含まれていたら
if '今日' in command:
response = today_command()
# もし 現在 が含まれていたら
if '現在' in command:
response = now_command()
# もし 曜日 が含まれていたら
if '曜日' in command:
response = weekday_command(command)
if not response:
response = 'イミワカラン'
print(response)
if 'さようなら' in command:
response = 'サヨウナラ'
break
except Exception as e:
print('予期セヌ エラーガ 発生シマシタ...')
print('* 種類:', type(e))
print('* 内容:', e)
eto.py
入力した年の干支を答えてくれる関数です。
# 関数を作成
def eto_command(command):
eto, year = command.split()
eto_list = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
eto_number = (int(year) + 8) % 12
eto_name = eto_list[eto_number]
response = '{}年生マレノ干支ハ【{}】デス。'.format(year, eto_name)
return response
date_time.py
時刻、日付を答えてくれる関数です。
# datetimeモジュールをインポート
# https://docs.python.org/ja/3/library/datetime.html
from datetime import date, datetime
# 今日の日付を返す today_command関数を作成
def today_command():
today = date.today()
response = '今日ノ日付ハ {} デス'.format(today)
return response
# 今の日時を返す now_command関数を作成
def now_command():
now = datetime.now()
response = '現在ノ日時ハ {} デス'.format(now)
return response
# weekday_command関数を作成(日付を作成)
def weekday_command(command):
# 例外処理のために try ~ except
try:
# コマンドできたものを分割して data に代入
# 想定「曜日 2020 3 20」みたいな感じ
data = command.split()
# 分割した文字列を数値に変換してそれぞれの変数に代入
year = int(data[1])
month = int(data[2])
day = int(data[3])
# 日付データの生成 date()
one_day = date(year, month, day)
# 曜日の文字列を作成
weekday_str = '月火水木金土日'
# 曜日の順番をweekday()メソッドで取得し、曜日の文字列を生成。
weekday = weekday_str[one_day.weekday()]
# 出力
response = '{} ハ {} 曜日デス'.format(one_day, weekday)
except IndexError:
response = '3ツノ値(年月日)ヲ指定シテクダサイ'
except ValueError:
response = '正シイ日付ヲ指定シテクダサイ'
return response
random_random.py
入力した文字をランダムで、返してくれる関数です。
import random
def choice_command(command):
data = command.split()
# リストの1番目以降を渡す(スライス)
choiced = random.choice(data[1:])
response = '【{}】が選バレマシタ。'.format(choiced)
return response
def dice_command():
num = random.randrange(1, 7)
response = '【{}】ガ出マシタ。'.format(num)
return response