質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1847閲覧

sre_constans.error: nothing ti repeat at position 0 のエラーが分かりません

elesuS_

総合スコア5

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/09/19 09:18

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\tkinter_init_.py", line 1699, in call
return self.func(*args)
File "H:\Atom\AI\AIForm.py", line 65, in talk
response = AI.dialogue(value)
File "H:\Atom\AI\AI.py", line 37, in dialogue
self.emotion.update(input)
File "H:\Atom\AI\AI.py", line 99, in update
if ptn_item.match(input):
File "H:\Atom\AI\dictionary.py", line 199, in match
return re.search(self.pattern, str)
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\re.py", line 182, in search
return _compile(pattern, flags).search(string)
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\re.py", line 301, in _compile
p = sre_compile.compile(pattern, flags)
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\sre_compile.py", line 562, in compile
p = sre_parse.parse(p, flags)
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\sre_parse.py", line 856, in parse
p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, False)
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\sre_parse.py", line 415, in _parse_sub
itemsappend(_parse(source, state, verbose))
File "C:\Users\i201720\AppData\Local\Programs\Python\Python36\lib\sre_parse.py", line 615, in _parse
source.tell() - here + len(this))
sre_constants.error: nothing to repeat at position 0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

elesuS_

2019/09/19 09:19

import random import re from analyzer import * class Dictionary: def __init__(self): self.random = [] # (1) # ランダム辞書ファイルオープン rfile = open('dics/random.txt', 'r', encoding = 'utf_8') # 各行を要素としてリストに格納 r_lines = rfile.readlines() rfile.close() # 末尾の改行と空白文字を取り除いて # インスタンス変数(リスト)に格納 for line in r_lines: str = line.rstrip('\n') if (str!=''): self.random.append(str) # 辞書を保持 self.pattern = [] # パターン辞書オープン pfile = open('dics/pattern.txt', 'r', encoding = 'utf_8') # 各行を要素としてリストに格納 p_lines = pfile.readlines() pfile.close() # 末尾の改行と空白文字を取り除いて # インスタンス変数(リスト)に格納 self.new_lines = [] for line in p_lines: str = line.rstrip('\n') if (str!=''): self.new_lines.append(str) # 辞書をタブで分ける # ptn 正規表現 # prs 応答例 # ParseItemオブジェクトを生成(引数はptn、prs)して # インスタンス変数pattern(リスト)に追加 for line in self.new_lines: ptn, prs = line.split('\t') self.pattern.append(ParseItem(ptn, prs)) # テンプレート辞書を保持 self.temp = {} # パターン辞書ファイルオープン tfile = open('dics/temp.txt', 'r', encoding = 'utf_8') # 要素をリストに格納 t_lines =tfile.readlines() #print(t_lines) tfile.close() #末尾の改行を無くし 変数(リスト)に格納 self.new_t_lines = [] for line in t_lines: str = line.rstrip('\n') if (str!=''): self.new_t_lines.append(str) #print(self.new_t_lines) # 辞書の行をタブで分ける # count %noun%の出現回数 for line in self.new_t_lines: # テンプレート行をタブでcount, templateに分ける count, temp = line.split('\t') # countがされない場合 空のリストに追加 if not count in self.temp: self.temp[count] = [] # countのリストにtempの文字列を追加 self.temp[count].append(temp) def study(self, input, parts): # インプット文字列の末尾の改行 input = input.rstrip('\n') self.study_random(input) self.study_pattern(input, parts) self.study_temp(parts) def study_random(self, input): # 発言を学習する # ランダム辞書に存在しない場合 selfで追加 if not input in self.random: self.random.append(input) def study_pattern(self, input, parts): # ユーザーの発言を学習する # 2つのパラメーターにリストの要素を取り出す for word, part in parts: # Trueの場合 if (keyword_check(part)): depend = False # ParseItemオブジェクトを保持 # 反復処理 for ptn_item in self.pattern: m = re.search(ptn_item.pattern, word) # 元々あるパターンなら # リストからParseItemオブジェクトを取得 if(re.search(ptn_item.pattern, word)): depend = ptn_item break #マッチしたら止める # 元々あるパターンとマッチしたParseItemオブジェクトから # add_phraseを呼ぶ if depend: depend.add_phrase(input) # インプット文字列 else: # パターンに存在しない名詞であれば # ParseItemオブジェクトにpatternリストに追加 self.pattern.append(ParseItem(word, input)) def study_temp(self, parts): temp = '' count = 0 for word, part in parts: # 名詞であるか確認 if (keyword_check(part)): word = '%word%' count += 1 temp += word # self.tempにcountが無ければ # countを空のリストに追加 if count > 0: count = str(count) if not count in self.temp: self.temp[count] = [] # countのリストに文字列を追加 if not temp in self.temp[count]: self.temp[count].append(temp) def save(self): """ self.randomの内容をまるごと辞書に書き込む """ # 各要素の末尾に改行を追加 for index, element in enumerate(self.random): self.random[index] = element +'\n' # ランダム辞書に書き込む with open('dics/random.txt', 'w', encoding = 'utf_8') as f: f.writelines(self.random) # 辞書にデータを保持 pattern = [] for ptn_item in self.pattern: # make_line()で行データ作成 pattern.append(ptn_item.make_line() + '\n') # パターン辞書ファイルに書き込む with open('dics/pattern.txt', 'w', encoding = 'utf_8') as f: f.writelines(pattern) temp = [] # self.templateのすべての値を取得し反復処理を行う for key, val in self.temp.items(): for v in val: temp.append(key + '\t' + v + '\n') # リスト内のテンプレートを読み込み temp.sort() # テンプレ辞書に書き込む with open('dics/temp.txt', 'w', encoding = 'utf_8') as f: f.writelines(temp) class ParseItem: SEPARATOR = '^((-?\d+)##)?(.*)$' def __init__(self, pattern, phrases): """ @param pattern パターン @param phrases 応答例 """ # 辞書のパターンの部分にSEPARATORをパターンマッチさせる m = re.findall(ParseItem.SEPARATOR, pattern) # インスタンス変数modifyに0を代入 self.modify = 0 # マッチ結果の整数の部分が空でなければ値を代入 if m[0][1]: self.modify =int(m[0][1]) # インスタンス変数patternにマッチ結果のパターン部分を代入 self.pattern = m[0][2] self.phrases = [] # 応答例を保持するインスタンス変数 self.dic = {} # インスタンス変数 # 引数で渡された応答例を'|'で分割し、 # 個々の要素に対してSEPARATORをパターンマッチさせる # self.phrases[ 'need' : 応答例の整数部分 # 'phrase': 応答例の文字列部分 ] for phrase in phrases.split('|'): # 応答例に対してパターンマッチを行う m = re.findall(ParseItem.SEPARATOR, phrase) # 整数部分m[0][1]にする # 応答文字列m[0][2]にする self.dic['need'] = 0 if m[0][1]: self.dic['need'] = int(m[0][1]) self.dic['phrase'] = m[0][2] # 作成した辞書をphrasesリストに追加 self.phrases.append(self.dic.copy()) def match(self, str): """self.pattern(各行ごとの正規表現)を インプット文字列にパターンマッチ """ return re.search(self.pattern, str) def choice(self, mood): """インスタンス変数phrases(リスト)の 要素('need''phrase'の辞書) 'need':数値を @ptam mood 現在の機嫌値 """ choices = [] # self.phrasesが保持するリストの要素(辞書)を反復処理する for p in self.phrases: # self.phrasesの'need'キーの数値と # パラメーターmoodをsuitable()に渡す # 結果がTrueであればchoicesリストに'phrase'キーの応答例を追加 if (self.suitable(p['need'], mood)): choices.append(p['phrase']) # choicesリストが空であればNoneを返す if (len(choices) == 0): return None # choicesリストが空でなければランダムに # 応答文字列を選択して返す return random.choice(choices) def suitable(self, need, mood): #機嫌値 # 必要機嫌値が0であればTrueを返す if (need == 0): return True # 必要機嫌値がプラスの場合は機嫌値が必要機嫌値を超えているか判定 elif (need > 0): return (mood > need) # 応答例の数値がマイナスの場合は機嫌値が下回っているか判定 else: return (mood < need) def add_phrase(self, phrase): #応答例 # インプット文字列がリストの応答例に合うか # self.phrases マッチした応答フレーズの辞書リスト for p in self.phrases: #print('phrases===',p) # 終了 if p['phrase'] == phrase: return # phrasesリストに辞書を追加 # {'need' :0, 'phrase':インプット文字列} self.phrases.append({'need': 0, 'phrase': phrase}) def make_line(self): """パターン辞書1行ぶんのデータを作る """ # 必要機嫌値 + '##' + パターン pattern = str(self.modify) + '##' + self.pattern phrases= [] for p in self.phrases: resp = str(p['need']) + '##' + str(p['phrase']) phrases.append(str(p['need']) + '##' + str(p['phrase'])) line = pattern + '\t' + '|'.join(phrases) return pattern + '\t' + '|'.join(phrases) 辞書ファイル部分です
elesuS_

2019/09/19 09:20

import random import re from analyzer import * class Responder: """ 応答クラスのスーパークラス """ def __init__(self, name, dictionary): self.name = name self.dictionary = dictionary def response(self, input, mood): """ response()メソッド input 入力された文字列 mood 機嫌値 戻り値 空の文字列 """ return '' def get_name(self): return self.name class RepeatResponder(Responder): """ オウム返しのための行うクラス """ def response(self, input, mood, parts): return '{}ってなに?'.format(input) class RandomResponder(Responder): """ ランダムな応答のための行うサブクラス """ def response(self, input, mood, parts): return random.choice(self.dictionary.random) class PatternResponder(Responder): """ パターンに反応するためのサブクラス """ def response(self, input, mood, parts): self.resp = None for ptn_item in self.dictionary.pattern: m = ptn_item.match(input) # マッチした場合は機嫌値moodを引数にしてchoice()を実行、 # 戻り値の応答文字列、またはNoneを取得 if (m): self.resp = ptn_item.choice(mood) # choice()の戻り値がNoneでない場合は # 応答例の中の%match%をインプットされた文字列内の # マッチした文字列に置き換える if self.resp != None: return re.sub('%match%', m.group(), self.resp) # パターンマッチしない場合はランダム辞書から返す return random.choice(self.dictionary.random) class tempResponder(Responder): """ テンプレートの反応のためのクラス """ def responce(self, input, mood, parts): """ テンプレートを使い応答フレーズ部分を作成 input 文字列 parts 形態要素解析結果 mood アプデ後の機嫌値 """ # 文字列の名詞のみ格納 keywords = [] # テンプレを格納 temp = '' #partsの wordが文字列 partが品詞情報 for word, part in parts: #名詞であるかを確認しkeywordsで格納する if (keyword_check(part)): keywords.append(word) # keywordsへ格納した名詞の数を得る count = len(keywords) #1つ以上名詞があり、テンプレがあるかどうかを確認する if (count > 0) and (str(count) in self.dictionary.temp): #テンプレをランダムに抽出 temp = random.choice(self.dictionary.temp[str(count)]) #空欄%word%にkeywordsの名詞を入れる for word in keywords: temp = temp.replace('%word%', word, 1) return temp return random.choice(self.dictionary.random) 応答部分です
elesuS_

2019/09/19 09:21

from responder import * from dictionary import * from analyzer import * class AI: """ ピティナの本体クラス """ def __init__(self, name): """ AIオブジェクトの名前をnameに格納 応答オブジェクトをランダムに生成してresponderに格納 @param name Ptnaオブジェクトの名前 """ self.name = name # Dictionaryを生成 self.dictionary = Dictionary() # Emotionを生成 self.emotion = Emotion(self.dictionary) # RandomResponderを生成 self.res_random = RandomResponder('Random', self.dictionary) # RepeatResponderを生成 self.res_what = RepeatResponder('Repeat', self.dictionary) # PatternResponderを生成 self.res_pattern = PatternResponder('Pattern', self.dictionary) # TempResponderを生成 self.resp_temp = tempResponder('temp', self.dictionary) def dialogue(self, input): """ 応答オブジェクトのresponse()を呼び出して 応答文字列を取得する @param input ユーザーによって入力された文字列 戻り値 応答文字列 """ #機嫌値 self.emotion.update(input) # 文字列を解析 parts = analyze(input) # 1から100をランダムに生成 x = random.randint(1, 100) # 40以下ならPatternResponderオブジェクトにする if x <= 40: self.responder = self.res_pattern # 41~90以下ならTempResponderオブジェクトにする elif 41 <= x <= 70: self.responder = self.res_temp # 71~90以下ならRandomResponderオブジェクトにする elif 71 <= x <= 70: self.responder = self.res_random # それ以外はRepeatResponderオブジェクトにする else: self.responder = self.res_what # 応答フレーズ resp = self.responder.response(input, self.emotion.mood, parts) # 学習メゾット self.dictionary.study(input, parts) # 応答フレーズ return resp def save(self): """ Dictionaryのsave()を呼ぶメゾット """ self.dictionary.save() class Emotion: """ ピティナの感情モデル """ # 機嫌値の上限/加減と回復値を設定 MOOD_MIN = -15 MOOD_MAX = 15 MOOD_RECOVERY = 0.5 def __init__(self, dictionary): """ Dictionaryオブジェクトをdictionaryに格納 機嫌値moodを0で初期化 @param dictionary Dictionaryオブジェクト """ self.dictionary = dictionary # 機嫌値を保持するインスタンス変数 self.mood = 0 def update(self, input): """ ユーザーからの入力をパラメーターinputで受け取り パターン辞書にマッチさせて機嫌値を変動させる @param input ユーザーからの入力 """ # 機嫌を徐々にもとに戻す処理 if self.mood < 0: self.mood += Emotion.MOOD_RECOVERY elif self.mood > 0: self.mood -= Emotion.MOOD_RECOVERY # パターン辞書の各行を繰り返しパターンマッチさせる for ptn_item in self.dictionary.pattern: # パターンマッチすればadjust_mood()で機嫌値を変動させる if ptn_item.match(input): self.adjust_mood(ptn_item.modify) break def adjust_mood(self, val): """ 機嫌値を増減させる @param val 機嫌変動値 """ # 機嫌値moodの値を機嫌変動値によって増減する self.mood += int(val) # MOOD_MAXとMOOD_MINと比較して、機嫌値が取り得る範囲に収める if self.mood > Emotion.MOOD_MAX: self.mood = Emotion.MOOD_MAX elif self.mood < Emotion.MOOD_MIN: self.mood = Emotion.MOOD_MIN 本体のクラスです
elesuS_

2019/09/19 09:26 編集

正規表現のプログラムが間違えているのかと思ったのですがさっぱり分かりませんでした。 又、Tkinterを使っているのですがコンパイルはできているみたいで、言葉を打ち、会話のボタンを押すとエラーが起きます。
LouiS0616

2019/09/19 11:57 編集

客観的に見てみて、この質問は果たして読み易いでしょうか? 質問は投稿後修正可能です。次のページを一通り読んで改善して下さい。 https://teratail.com/help/question-tips
elesuS_

2019/09/19 13:17

すみませんケータイで投稿しましたので、PCの方で投稿し直します すみません。
guest

回答1

0

google翻訳
位置0で繰り返すものはありません

投稿2019/09/19 11:10

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問