#! /usr/bin/env python
# coding:utf-8


import abc
from logging import getLogger


class Module(metaclass=abc.ABCMeta):
    """
    message の形式
    message:
        "id"
        "text"
        "user":
            "name"
            "screen_name"
    """
    def is_fire(self):
        return True

    @abc.abstractmethod
    def reses(self, message, master):
        pass


class Kovot:

    def __init__(
        self,
        target,
        stream,
        master,
        logger=None
    ):
        self.target = target
        self.stream = stream
        self.master = master
        self.logger = logger if logger else getLogger(__file__)
        self.modules = []

    def is_message(self, message):
        """
        Check essage format:
            "id"
            "text"
            "user":
                "name"
                "screen_name"
        """
        return (
            "text" in message and
            "user" in message and
            "id" in message and
            "name" in message["user"] and
            "screen_name" in message["user"]
        )

    def add_module(self, module):
        self.modules.append(module)

    def reses(self, message):
        modules = [module for module in self.modules if module.is_fire()]
        reses = []
        for module in modules:
            reses.extend(module.reses(message, self.master))
        return reses

    def run(self):
        for message in self.stream:
            if not self.is_message(message):
                continue
            elif self.stream.is_tweet_needed(message):
                reses = self.reses(message)

                self.stream.say(
                    message,
                    sorted(reses, reverse=True),
                    num=5
                )

@@ -74,16 +74,88 @@
 tLogger%0A
+from selector import Selector%0Afrom postprocessing import PostProcessing%0A
 %0A%0Aclass 
@@ -331,20 +331,162 @@
 def 
-is_fire(self
+__init__(%0A        self,%0A        logger=None,%0A    ):%0A        self.logger = logger if logger else getLogger(__file__)%0A%0A    def is_fire(self, message, master
 ):%0A 
@@ -581,16 +581,79 @@
   pass%0A%0A
+    def __str__(self):%0A        return self.__class__.__name__%0A%0A
 %0Aclass K
@@ -695,24 +695,8 @@
 lf,%0A
-        target,%0A
     
@@ -735,113 +735,233 @@
     
-logger=None%0A    ):%0A        self.target = target%0A        self.stream = stream%0A        self.master = master
+selector=Selector(),%0A        postprocessing=PostProcessing(),%0A        logger=None%0A    ):%0A        self.stream = stream%0A        self.master = master%0A        self.selector = selector%0A        self.postprocessing = postprocessing%0A
 %0A   
@@ -1531,36 +1531,38 @@
 odule)%0A%0A    def 
-rese
+answer
 s(self, message)
@@ -1582,22 +1582,47 @@
 ules = %5B
-module
+%0A            module%0A           
  for mod
@@ -1663,162 +1663,317 @@
 ire(
-)%5D%0A        reses = %5B%5D%0A        for module in modules:%0A            reses.extend(module.reses(message, self.master))%0A        return reses%0A%0A    def run(self):
+message, self.master)%0A        %5D%0A%0A        return sum(%0A            %5Bmodule.reses(message, self.master) for module in modules%5D,%0A            %5B%5D%0A        )%0A%0A    def run(self):%0A        self.logger.info(%22using modules:%5Cn%7B%7D%22.format(%0A            %22%5Cn%22.join(%22    - %7B%7D%22.format(str(mod)) for mod in self.modules)%0A        ))
 %0A   
@@ -2093,38 +2093,93 @@
   el
-if self.stream.is_tweet_needed
+se:%0A                # get answers from modules%0A                answers = self.answers
 (mes
@@ -2175,33 +2175,33 @@
 answers(message)
-:
+%0A
 %0A               
@@ -2205,98 +2205,375 @@
     
-reses = self.reses(message)%0A%0A                self.stream.say(%0A                    message,
+# select answers by using a Selector instance%0A                post_answers = %5B%0A                    self.postprocessing.convert(message, answer, self.master)%0A                    for answer in self.selector.select(answers, num=10)%0A                %5D%0A%0A                # log%0A                if post_answers:%0A                    self.logger.info(%22### aswer candidates ###%22)
 %0A   
@@ -2593,35 +2593,342 @@
     
-sorted(reses, reverse=True)
+for prob, text, source, info in post_answers:%0A                        self.logger.info(%0A                            %22%5B%7B%7D%5D %7B:.4%7D %7B%7D%22.format(source, prob, text)%0A                        )%0A                    self.logger.info(%22########################%22)%0A%0A                # post%0A                self.stream.say(%0A                    message
 ,%0A  
@@ -2949,13 +2949,20 @@
     
-num=5
+post_answers
 %0A   

Update kovot.py