示例#1
0
 def test_get_last_tree(self):
     WordsData(self.WORDS)
     word_tuple = (
         Words(
             {
                 "word": "古池",
                 "vowel": "ウウイエ",
                 "length": 4,
                 "part": "名詞"
             }
         ),
         Words(
             {
                 "word": "蛙",
                 "vowel": "アエウ",
                 "length": 3,
                 "part": "名詞"
             }
         ),
         Words(
             {
                 "word": "あ",
                 "vowel": "ア",
                 "length": 1,
                 "part": "名詞"
             }
         )
     )
     root = PhraseTree.define_root(possible_next_words=list(self.SUCCESS_CHAINS.keys()))
     next_tree = PhraseTree(current_words=word_tuple)
     root.next_tree = next_tree
     self.assertEqual(
         root.get_last_tree(root),
         next_tree
     )
示例#2
0
    def test_construct_syllable(self):
        WordsData.words_data = self.SUCCESS_WORDS_TWELVE
        ChainsData.chains_data = self.SUCCESS_CHAINS_TWELVE
        haiker = Haiker()
        root = PhraseTree.define_root(
            possible_next_words=list(self.SUCCESS_CHAINS_TWELVE.keys()))

        self.assertIsInstance(haiker.construct_syllable(root, self.TWELVE),
                              PhraseTree)

        pt = haiker.construct_syllable(root, self.TWELVE)
        self.assertEqual(PhraseTree.count_phrase_len(pt), self.TWELVE)
示例#3
0
    def construct_syllable(self, phrase_tree, expected_vowel_len, noun=False):
        """
        最初の音節を作成する.

        Args:
          phrase_tree: PhraseTree クラスオブジェクト
          expected_vowel_len: 音節の読みの長さ
        Returns:
          音節
        """
        # phrase_tree には,current と next が格納済み
        while True:
            if self._is_empty_first_node(phrase_tree):
                raise ConstructionError('First node has become empty.')
            while True:
                # 単語タプルをランダムに1つ取得
                try:
                    PhraseTree.disclose(phrase_tree, "construct ---------")
                    phrase_tree, phrase_tree.next_tree = self._get_word(
                        phrase_tree)
                    PhraseTree.disclose(phrase_tree, "construct 2 ---------")
                except ValueError:
                    logger.info('*** Cnstruction failed ***')
                    raise
                if phrase_tree.next_tree is None:
                    break

                text_vowel_len = PhraseTree.count_phrase_len(
                    phrase_tree.next_tree)

                if phrase_tree.possible_next_words == list():
                    try:
                        phrase_tree = self._back_prev_word_list(phrase_tree)
                    except ValueError:
                        logger.info('*** Cnstruction failed ***')
                        raise
                elif self._is_n_char(expected_vowel_len, text_vowel_len):
                    assert phrase_tree is not None, "phrase_tree is None"
                    self._post_proc(phrase_tree.next_tree)
                    return phrase_tree.next_tree
                elif self._is_less_than_n_char(expected_vowel_len,
                                               text_vowel_len):
                    # 次の単語タプルを取得する前の処理
                    phrase_tree = phrase_tree.next_tree
                    assert phrase_tree is not None, "phrase_tree is None"
                    break
                else:
                    # 5文字より長くなったら別の単語を取得しなおす
                    # 現在の next_tree を破棄する
                    pass
示例#4
0
 def _back_prev_word_list(self, phrase_tree):
     """
     単語リストが空になったら,前の単語リストに戻る
     """
     if PhraseTree.is_root(phrase_tree):
         raise ValueError('Impossible to back prev word list')
     return phrase_tree.parent
示例#5
0
    def compose(self):
        """
        俳句を詠む.
        """
        first_loop_limit = 500
        first_current_loop = 0
        while True:
            logger.debug('+++ current loop: {} +++'.format(first_current_loop))

            first_current_loop += 1
            if first_current_loop == first_loop_limit:
                return "***** だめでした *****"

            try:
                root = PhraseTree.define_root(
                    possible_next_words=self._get_word_list())
                first_phrase_tree = self.construct_syllable(root, self.FIVE)
                first_text_list = Phrase.text_list
                PhraseTree.disclose(first_phrase_tree, "first -------------")
            except ValueError:
                logger.debug('***** first ValueError *****')
                continue

            try:
                root = PhraseTree.define_root(
                    possible_next_words=first_phrase_tree.possible_next_words)
                second_phrase_tree = self.construct_syllable(root, self.SEVEN)
                second_last_vowel = Phrase.last_vowel
                second_text_list = Phrase.text_list
                PhraseTree.disclose(second_phrase_tree, "second -------------")
            except ValueError:
                logger.debug('***** second ValueError *****')
                continue

            try:
                root = PhraseTree.define_root(
                    possible_next_words=second_phrase_tree.possible_next_words)
                third_phrase_tree = self.construct_syllable(root, self.FIVE)
                third_last_vowel = Phrase.last_vowel
                third_text_list = Phrase.text_list
                PhraseTree.disclose(third_phrase_tree, "third -------------")
            except ValueError:
                logger.debug('***** third ValueError *****')
                continue

            if Rhymer.is_rhymed(second_last_vowel, third_last_vowel):
                haiku = "".join(first_text_list + second_text_list +
                                third_text_list)
                logger.debug("[Haiku] >>> {}".format(haiku))

                return haiku
示例#6
0
    def _post_proc(self, phrase_tree):
        """
        句生成完了後の処理.
        - 最後の3語を保持
        - 生成した句の読みを保持
        - 生成した句をリストとして保持

        - 生成した句を保持

        Args:
          最後の PhraseTree インスタンス
        Returns:
          Phrase インスタンス
        """
        assert phrase_tree is not None
        assert not PhraseTree.is_root(phrase_tree), "phrase_tree is not root"
        Phrase.text_list = PhraseTree.get_text_list(phrase_tree)
        Phrase.last_words = PhraseTree.get_last_words(phrase_tree)
        Phrase.last_vowel = PhraseTree.get_text_vowel(phrase_tree)
示例#7
0
    def test_construct_syllable_initialize_empty(self):
        """
        生成中,単語の候補リストが空担った場合
        """
        WordsData.words_data = self.EMPTY_LIST
        ChainsData.chains_data = self.EMPTY_DICT
        haiker = Haiker()
        root = PhraseTree.define_root(
            possible_next_words=list(ChainsData.chains_data.keys()))

        with self.assertRaises(ValueError):
            haiker.construct_syllable(root, self.TWELVE)
示例#8
0
 def test_get_text_list_first_and_last(self):
     """
     最初のツリー(root の次)に対して
     """
     WordsData.words_data = self.SUCCESS_WORDS_TWELVE
     root = PhraseTree.define_root(possible_next_words=list(self.SUCCESS_CHAINS_TWELVE.keys()))
     word_tuple = (
         Words(
             {
                 "word": "ああああ",
                 "vowel": "アアアア",
                 "length": 4,
                 "part": "名詞"
             }
         ),
         Words(
             {
                 "word": "いいいい",
                 "vowel": "イイイイ",
                 "length": 4,
                 "part": "名詞"
             }
         ),
         Words(
             {
                 "word": "うううう",
                 "vowel": "ウウウウ",
                 "length": 4,
                 "part": "名詞"
             }
         )
     )
     next_pt = PhraseTree(current_words=word_tuple,
                          possible_next_words=list(self.SUCCESS_CHAINS_TWELVE.keys()),
                          parent=root)
     root.next_tree = next_pt
     self.assertEqual(
         root.get_text_list(next_pt),
         ['ああああ', 'いいいい', 'うううう']
     )
示例#9
0
    def _get_word(self, phrase_tree, seed=None, max_iterations=100):
        """
        単語リストからランダムに1つ取得.
        next_tree を取得的ない場合,None が代入される.
        """
        next_tree = None
        for index in range(max_iterations):
            if not phrase_tree.possible_next_words:
                # possible_next_words が None, []
                if PhraseTree.is_root(phrase_tree):
                    raise ValueError(
                        "Impossible to get word cause of Root Tree doesn't have any possible next words"
                    )
                return phrase_tree.parent, None
            else:
                if seed is None:
                    random.shuffle(phrase_tree.possible_next_words)
                    seed = phrase_tree.possible_next_words[
                        -1]  # if 文外で remove するため pop ではない
                phrase_tree.possible_next_words.remove(seed)

                if seed in self._get_word_list() and \
                   ChainsData.chains_data[seed] != [None]:
                    if ChainsData.chains_data[seed] == [None]:
                        # この時点では,seed は文字列のタプルであり,Words クラスのタプルではない
                        pass
                    assert ChainsData.chains_data[seed] != [
                        None
                    ], "ChainsData.chains_data: {}".format(
                        ChainsData.chains_data)
                    next_tree = PhraseTree(
                        current_words=seed,
                        possible_next_words=ChainsData.chains_data[seed],
                        parent=phrase_tree)
                    break
            seed = None

        assert phrase_tree is not None, "phrase_tree is None"
        return phrase_tree, next_tree
示例#10
0
    def test_post_proc(self):
        """
        Phrase クラスが関連するテストは
        Phrase のメンバ変数を初期化してから行う.
        """
        WordsData.words_data = self.SUCCESS_WORDS
        ChainsData.chains_data = self.SUCCESS_CHAINS
        haiker = Haiker()
        word_tuple = (Words({
            "word": "古池",
            "vowel": "ウウイエ",
            "length": 4,
            "part": "名詞"
        }), Words({
            "word": "蛙",
            "vowel": "アエウ",
            "length": 3,
            "part": "名詞"
        }), Words({
            "word": "あ",
            "vowel": "ア",
            "length": 1,
            "part": "名詞"
        }))
        root = PhraseTree.define_root(
            possible_next_words=list(ChainsData.chains_data.keys()))
        second_tree = PhraseTree(current_words=word_tuple, parent=root)
        root.next_tree = second_tree

        # 中間処理
        haiker._post_proc(second_tree)

        # Phrase 代入済み
        self.assertNotEqual(Phrase.text_list, list())
        self.assertNotEqual(Phrase.last_words, tuple())
        self.assertIsInstance(Phrase.last_vowel, str)
示例#11
0
 def test_construct_syllable_failure(self):
     WordsData.words_data = [{
         "word": "あ",
         "vowel": "ア",
         "length": 1,
         "part": "名詞"
     }, {
         "word": "い",
         "vowel": "イ",
         "length": 1,
         "part": "名詞"
     }]
     ChainsData.chains_data = {"あ": ["い"]}
     haiker = Haiker()
     root = PhraseTree.define_root(
         possible_next_words=list(ChainsData.chains_data.keys()))
     with self.assertRaises(ValueError):
         haiker.construct_syllable(root, self.TWELVE)
示例#12
0
    def test_get_last_words(self):
        WordsData(self.WORDS)
        word_tuple = (
            Words(
                {
                    "word": "古池",
                    "vowel": "ウウイエ",
                    "length": 4,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "蛙",
                    "vowel": "アエウ",
                    "length": 3,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "あ",
                    "vowel": "ア",
                    "length": 1,
                    "part": "名詞"
                }
            )
        )
        pt = PhraseTree(word_tuple)

        next_word_tuple = (
            Words(
                {
                    "word": "蛙",
                    "vowel": "アエウ",
                    "length": 3,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "あ",
                    "vowel": "ア",
                    "length": 1,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "い",
                    "vowel": "イ",
                    "length": 1,
                    "part": "名詞"
                }
            )
        )
        next_pt = PhraseTree(next_word_tuple, parent=pt)
        pt.next_tree = next_pt

        self.assertEqual(
            PhraseTree.get_last_words(pt),
            next_word_tuple
        )
示例#13
0
    def test_count_phrase_len(self):
        WordsData(self.WORDS)
        word_tuple = (
            Words(
                {
                    "word": "古池",
                    "vowel": "ウウイエ",
                    "length": 4,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "蛙",
                    "vowel": "アエウ",
                    "length": 3,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "あ",
                    "vowel": "ア",
                    "length": 1,
                    "part": "名詞"
                }
            )
        )
        root = PhraseTree.define_root(possible_next_words=list(self.SUCCESS_CHAINS.keys()))
        second_tree = PhraseTree(current_words=word_tuple,
                                 parent=root)
        root.next_tree = second_tree
        self.assertEqual(
            root.count_phrase_len(second_tree),
            8
        )

        next_word_tuple = (
            Words(
                {
                    "word": "蛙",
                    "vowel": "アエウ",
                    "length": 3,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "あ",
                    "vowel": "ア",
                    "length": 1,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "いい",
                    "vowel": "イイ",
                    "length": 2,
                    "part": "名詞"
                }
            )
        )
        third_tree = PhraseTree(next_word_tuple,
                                parent=second_tree)
        self.assertEqual(
            PhraseTree.count_phrase_len(third_tree),
            10
        )
示例#14
0
    def test_get_text_list(self):
        WordsData(self.WORDS)
        word_tuple = (
            Words(
                {
                    "word": "古池",
                    "vowel": "ウウイエ",
                    "length": 4,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "蛙",
                    "vowel": "アエウ",
                    "length": 3,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "あ",
                    "vowel": "ア",
                    "length": 1,
                    "part": "名詞"
                }
            )
        )
        root = PhraseTree.define_root(possible_next_words=list(self.SUCCESS_CHAINS.keys()))
        second_tree = PhraseTree(current_words=word_tuple,
                                 parent=root)
        root.next_tree = second_tree
        self.assertEqual(
            PhraseTree.get_text_list(second_tree),
            ['古池', '蛙', 'あ']
        )

        next_word_tuple = (
            Words(
                {
                    "word": "蛙",
                    "vowel": "アエウ",
                    "length": 3,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "あ",
                    "vowel": "ア",
                    "length": 1,
                    "part": "名詞"
                }
            ),
            Words(
                {
                    "word": "いい",
                    "vowel": "イイ",
                    "length": 2,
                    "part": "名詞"
                }
            )
        )
        third_tree = PhraseTree(current_words=next_word_tuple,
                                possible_next_words=list(self.SUCCESS_CHAINS.keys()),
                                parent=second_tree)
        second_tree.next_tree = third_tree
        self.assertEqual(
            PhraseTree.get_text_list(third_tree),
            ['古池', '蛙', 'あ', 'いい']
        )