辞書をMySqlに変更したdictionary.py (2017.02.14更新)

辞書をMySqlにしたばあいのdictionary.pyは次のようになった。ただし、テンプレート型までしかいれていない。python2用であり、python3でやると不都合が起きると思う。なお、テキストブックの方は、python3用になっていた。
####################################

# -*- coding: utf-8 -*-

import MySQLdb
from analyzer import *
import re

"""
様々な辞書を処理するクラス
金城俊哉著「Pythonプログラミングパーフェクトマスター」を参照した
2017年2月12日 作成
"""

class Dictionary:
    def __init__(self):
        print "Dictionary を初期化します"
        self.conn = MySQLdb.connect(
            user='washida',
            passwd='robotcomedian',
            host='localhost',
            db='dictionary',
            charset="utf8"
            )
        self.c = self.conn.cursor()
        # 辞書データを全て取得する
        # ランダムフレーズの取得
        sql = 'select * from random'
        self.c.execute(sql)
        self.random = [] #
        print 'ランダムフレーズの取得 >> ',
        count = 0
        for row in self.c.fetchall():
            #print 'id:', row[0], 'Phrase:', row[1], "\n"
            if (row[1] != ''):
                count += 1
                self.random.append(row[1])
        print "終了 総数 = ",str(count)

        # パターンフレーズの取得
        sql = 'select * from pattern'
        self.c.execute(sql)
        # 辞書型のインスタンスを用意
        # self.pattern = {}
        self.pattern = []
        print 'パターンフレーズの取得 >> ',
        count = 0
        for row in self.c.fetchall():
            # print 'id:', row[0], 'Pattern:', row[1], 'Phrase:', row[2], "\n"
            if row[1] != '' and row[2] != '':
                count += 1;
                #self.pattern.setdefault('pattern', []).append(row[1])
                #self.pattern.setdefault('phrases', []).append(row[2])
                self.pattern.append({'pattern':row[1],'phrases':row[2]})
        print "終了 総数 = ",str(count)
        # 終了時に、データの更新が必要なpatternオブジェクト
        self.update_pattern = []
        # 終了時に新規追加が必要なpatternオブジェクト
        self.newitem_pattern = []

        # テンプレートデータの取得
        print 'テンプレートフレーズの取得 >> ',
        self.template = {}
        sql = 'select max(nounnum) from template'
        self.c.execute(sql)
        #print "sql = ",sql
        row = self.c.fetchone()
        print '名詞最大数 = ', row[0],
        count = 0
        for i in range(int(row[0])):
            j = i+1
            sql = "select * from template where nounnum = '" + str(j) + "'"
            self.c.execute(sql)
            for row in self.c.fetchall():
                #print 'id:', row[0], 'Nounnum:', row[1], 'Template:', row[2], "\n"
                if row[1] != '' and row[2] != '':
                    if not row[1] in self.template:
                        self.template[row[1]] = []
                self.template[row[1]].append(row[2])
                count += 1;
        print "終了 総数 = ",str(count)
        # 終了時に、データの更新が必要なtemplateオブジェクト
        self.update_template = []
        # 終了時に新規追加が必要なtemplateオブジェクト
        self.newitem_template = []

        self.c.close()
        self.conn.close()

    def study(self, input, parts):
        """ study_random()とstudy_pattern()を呼ぶ

            @param input  ユーザーの発言
            @param parts  形態素解析結果
        """
        # インプット文字列末尾の改行は取り除いておく
        input = input.rstrip('\n')
        # インプット文字列と解析結果を引数に、パターン辞書の登録メソッドを呼ぶ
        self.study_pattern(input, parts)
        # テンプレート辞書の登録メソッドを呼ぶ
        self.study_template(parts)

    def study_pattern(self, input, parts):
        """ ユーザーの発言を学習する

            @param input  インプット文字列
            @param parts  形態素解析の結果(リスト)
        """
        print "学習を開始します"
        # 多重リストの要素を2つのパラメーターに取り出す
        for word, part in parts:
            # analyzerのkeyword_check()関数による名詞チェックが
            # Trueの場合
            if (keyword_check(part)):
                print "キーワードが存在しました!!"
                depend = False # パターンオブジェクトを保持する変数
                # patternリストのpattern辞書オブジェクトを反復処理
                for ptn_item in self.pattern:
                    # インプットされた名詞が既存のパターンとマッチしたら
                    # patternリストからマッチしたParseItemオブジェクトを取得
                    if(re.search(ptn_item['pattern'], word)):
                        depend = ptn_item
                        break   #マッチしたら止める
                # 既存パターンとマッチしたParseItemオブジェクトから
                # add_phraseを呼ぶ
                if depend:
                    print "キーワードが既存のパターンにマッチするものでした!"
                    #depend.add_phrase(input) # 引数はインプット文字列
                    if(re.search(depend['phrases'], input)):
                        # すでにフレーズも含まれている場合は、なにもしない
                        pass
                    else:
                        # 既存のパターンに合致するが、フレーズに含まれていないものについては、フレーズに加えるだけにする
                        depend['phrases'] += ('|'+input)
                        # 終了時に更新すべきオブジェクトに位置付ける
                        self.update_pattern.append(depend)
                else:
                    print "キーワードが既存のパターンにマッチしないものでした!"
                    # 既存パターンに存在しない名詞であれば
                    # 新規のParseItemオブジェクトを
                    # patternリストに追加
                    newitem = {'pattern':word, 'phrases':input}
                    self.pattern.append(newitem)
                    # 終了時に新規追加しなければならない
                    self.newitem_pattern.append(newitem)

    def study_template(self, parts):
        """ テンプレートを学習する

            @param parts  形態素解析の結果(リスト)
        """
        template = ''
        count = 0
        for word, part in parts:
            # 名詞であるかをチェック
            if (keyword_check(part)):
                word = '%noun%'
                count += 1
            template += word

        # self.templateのキーにcount(出現回数)が存在しなければ
        # countをキーにして空のリストを要素として追加
        if count > 0:
            count = str(count)

            if not count in self.template:
                self.template[count] = []
                self.newitem_template.append(count)
            # countキーのリストにテンプレート文字列を追加
            if not template in self.template[count]:
                self.template[count].append(template)
                self.update_template.append({'nounnum':count,'template':template})

    def closeDict(self):
        # データベースへの変更を保存、あれば
        self.conn = MySQLdb.connect(
            user='washida',
            passwd='robotcomedian',
            host='localhost',
            db='dictionary',
            charset="utf8"
            )
        self.c = self.conn.cursor()
        # 辞書データを更新する
        print "辞書データベースを更新します"
        for item in self.update_pattern:
            #
            sql = "update pattern set phrases = '" + item['phrases'] + "' where pattern = '" + item['pattern'] + "'"
            print "sql = ",sql
            self.c.execute(sql)

        for item in self.newitem_pattern:
            #
            sql = "insert into pattern (pattern, phrases) values ('" + item['pattern'] + "', '" + item['phrases'] + "')"
            print "sql = ",sql
            self.c.execute(sql)

        for item in self.update_template:
            # アップデートすべきtemplateだけがはいっているので、全部加える
            sql = "insert into template (nounnum, template) values ('" + item['nounnum'] + "', '" + item['template'] + "')"
            print "sql = ",sql
            self.c.execute(sql)
        for num in self.newitem_template:
            # 新規なので、全部加える 新規の番号の文字列だけが入っている
            for tmp in self.template[num]:
                sql = "insert into template (nounnum, template) values  ('" + num + "', '" + tmp + "')"
                print "sql = ",sql
                self.c.execute(sql)


        self.conn.commit()
        #データベースを閉じる
        self.c.close()
        self.conn.close()