前提
お初です。
pythonの初心者用の書物で簡易的な会話BOTシステムを作っています。
書物はpythonプログラミングパーフェクトマスターです。
linkはこちらです。
https://www.shuwasystem.co.jp/book/9784798063676.htmlです。
###################################
このシステム主軸となるclassを作るresponder.pyで
正規表現を返す機能を実装中に以下のエラーメッセージが発生しました。
実現したいこと
事前に準備しておいたテキストファイルから正規表現で取得するようにしたいです
発生している問題・エラーメッセージ
Traceback (most recent call last): File "/Users/komadatakahito/Documents/BOT/GUI/mainWindow.py", line 35, in buttonTalkSlot response = self.pityna.dialogue(value) File "/Users/komadatakahito/Documents/BOT/GUI/pityna.py", line 21, in dialogue return self.responder.response(input) File "/Users/komadatakahito/Documents/BOT/GUI/responder.py", line 27, in response self.dictionary.pattern['pattern'], AttributeError: 'dict' object has no attribute 'pattern'``` ### 該当のソースコード
{responder.py}
import random
import re
class Responder(object):
def init(self, name):
self.name = name
def response(self, input):
return ''
class RepeatResponder(Responder):
def init(self, name):
super().init(name)
def response(self, input):
return '{}ってなに?'.format(input)
class RandomResponder(Responder):
def init(self, name, dic_random): ## ランダム辞書を引数にする
super().init(name)
self.random = dic_random
def response(self, input):
return random.choice(self.random) ## random.txtをランダムにチョイスしていく
class PatternResponder(Responder):
def init(self, name, dictionary):
## Dictionaryオブジェクトを引数にして受け取る
super().init(name)
self.dictionary= dictionary #Dictionaryオブジェクトをself.dictionaryとして受け取る
def response(self, input):
for ptn, prs in zip(
self.dictionary.pattern['pattern'],
self.dictionary.pattern['phrases']
):
print(vars(self))
m = re.search(ptn, input)
if m:
resp = random.choice(prs.split('|'))
return re.sub('\t%match%\t', m.group(), resp)
return random.choice(self.dictionary.random)
## もし必要だったらですが ##
{dictionary.py}
class Dictionary(object):
def init(self):
self.random = self.makeRandomList()
self.pattern = self.makePatternDictionary()
def makeRandomList(self):
rfile = open('GUI/dics/random.txt', 'r', encoding='utf-8')
r_line = rfile.readlines()
rfile.close()
randomList = [] for line in r_line: str = line.rstrip('\n') if (str!=''): randomList.append(str) return randomList def makePatternDictionary(self): pfile = open('GUI/dics/patterns.txt', 'r', encoding='utf-8') p_line = pfile.readlines() pfile.close() new_lines = [] for line in p_line: str = line.rstrip('\n') if (str != ''): new_lines.append(str) patternsDictionary = {} ## 辞書作成 for line in new_lines: ptn= line.split('\t') prs = line.split('\t') # print(type(line), line) patternsDictionary.setdefault('pattern', []).append(ptn) patternsDictionary.setdefault('phrases', []).append(prs) return patternsDictionary
## 実行##
{main.py}
import sys
from PyQt5 import QtWidgets
import mainWindow
このファイルが直接実行された場合に
if name == "main":
app = QtWidgets.QApplication(
sys.argv
)
win = mainWindow.MainWindow()
win.show()
ret = app.exec_()
sys.exit(ret)
{mainWindow.py}
from urllib import response
import pityna as pityna
from PyQt5 import QtWidgets
import qt_PitynaUI
#QtWidgets.QMainWindowを継承したサブクラスUI画面の構築を行う
class MainWindow(QtWidgets.QMainWindow):
#初期化のための処理
def init(self):
#スーパークラスのinit()を呼び出す
super().init()
self.pityna = pityna.Pityna('pityna')
#pitynaオブジェクトを生成
self.action = True
#ラジオボタンの状態を初期化
self.ui = qt_PitynaUI.Ui_MainWindow()
#Ui_MainWindow()オブジェクトを生成
self.ui.setupUi(self)
#setupUi()で画面を構築そしてMAINWINDOW自身を引数にすることが大事
def putlog(self, str):
#QListWidgetクラスのaddmin()でログをリストに追加
self.ui.listWidget.addItem(str)
def prompt(self):
p = self.pityna.get_name()
if self.action == True:
p += ':' + self.pityna.get_responder_name()
return p + '> '
def buttonTalkSlot(self):
value = self.ui.lineEdit.text()
if not value:
self.ui.labelResponse.setText('なに?')
else:
response = self.pityna.dialogue(value)
self.ui.labelResponse.setText(response)
self.putlog('> ' + value)
self.putlog(self.prompt() + response)
self.ui.lineEdit.clear()
def closeEvent(self, event):
reply = QtWidgets.QMessageBox.question(
self,
'確認',
"プログラムを終了しますか?",
buttons = QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No
)
if reply == QtWidgets.QMessageBox.Yes:
event.accept()
else:
event.ignore()
def showResponderName(self):
self.action = True
def hiddenResponderName(self):
self.action = False
### 試したこと dictにpatternがないとのことでソースコードから見直してみましたが行き詰まりました ### 補足情報(FW/ツールのバージョンなど) python=3.913