Esempio n. 1
0
 def test_get_points_different_size_stat( self ):
     """
     Tests if a list of statistics have back the right points.
     The list and the expected points are the following:
         (0,)->6
         (1,)->3
         (0, 0)->8
         (0, 1)->4
         (1, 0)->5
         (1, 1)->2
         (0, 0, 0)->10
         (0, 0, 1)->6
         (0, 1, 0)->6
         (0, 1, 1)->2
         (1, 0, 0)->7
         (1, 0, 1)->4
         (1, 1, 0)->4
         (1, 1, 1)->1
     """
     # Mock the __ini__
     with patch.object(FilteredDictionary, "__init__", lambda x: None):
         myFilteredDictionary=FilteredDictionary()
         myFilteredDictionary.base_language="hungarian"
         myFilteredDictionary.learning_language="swedish"
         myFilteredDictionary.recent_stat_list={i:list(i) for i in list(itertools.product([0,1], repeat=1)) + list(itertools.product([0,1], repeat=2)) + list(itertools.product([0,1], repeat=3))}
         myFilteredDictionary.word_dict={"1":('v', ['AAA'], 'aaa', '') }
         expected_list=[6,3,8,4,5,2,10,6,6,2,7,4,4,1]
         # run with all statuses -> result zipped with the expected valus -> pairs substracted from each other -> sum -> it must be 0
         self.assertEqual( sum( [ j[0]-j[1] for j in zip( [myFilteredDictionary.get_points(i) for i in myFilteredDictionary.recent_stat_list], expected_list) ] ), 0 )
Esempio n. 2
0
class ConsolePrala(object):
    COLOR_DEFAULT = "\033[00m"
    COLOR_POS = "\033[1;33m"  #yellow
    COLOR_QUESTION = "\033[1;37m"  #white
    COLOR_INPUT = "\033[1;34m"  #ligth blue
    #COLOR_RESULT_STATUS_WRONG="\033[0;31m"  #red
    COLOR_RESULT_STATUS_WRONG = "\033[41m\033[1;37m"  #red background-white foreground
    #COLOR_RESULT_STATUS_RIGHT="\033[0;32m"  #green
    COLOR_RESULT_STATUS_RIGHT = "\033[42m\033[1;37m"  #green background-white foreground
    COLOR_GOOD_ANSWER_WRONG = "\033[1;31m"  #light red
    COLOR_GOOD_ANSWER_RIGHT = "\033[0;32m"  #green
    COLOR_STAT = "\033[1;33m"  #yellow
    COLOR_CORRECTION_RIGHT = "\033[0;32m"  #green
    COLOR_CORRECTION_WRONG = "\033[1;31m"  #light red
    COLOR_NUMBER_OF_WORDS = "\033[1;32m"  #light green
    COLOR_NOTE = "\033[0;37m"  #gray

    POSITION_POS = "\033[9;10H"
    POSITION_QUESTION = "\033[10;10H"
    POSITION_INPUT = "\033[14;10H"
    POSITION_RESULT_STATUS = "\033[12;10H"
    POSITION_CORRECTION = "\033[14;10H"
    POSITION_GOOD_ANSWER = "\033[15;10H"
    POSITION_STAT = "\033[21;10H"

    STATUS_WRONG = "WRONG"
    STATUS_RIGHT = "RIGHT"

    TEMPLATE_INI_FILE_NAME = "template.in"
    TEMPLATE_DICT_FILE_NAME = "template.dict"

    #    INI_FILE_NAME="config.ini"

    def __init__(self, file_name, part_of_speech_filter="", extra_filter=""):

        config_ini = ConfigIni.getInstance()
        language = config_ini.getLanguage()
        base_language = to_name(config_ini.getBaseLanguage()).lower()
        learning_language = to_name(config_ini.getLearningLanguage()).lower()
        self.say_out = config_ini.isSayOut(),
        self.show_pattern = config_ini.isShowPattern(),
        self.show_note = config_ini.isShowNote()

        self.myFilteredDictionary = FilteredDictionary(file_name,
                                                       base_language,
                                                       learning_language,
                                                       part_of_speech_filter,
                                                       extra_filter)

    def round(self, wrong_record=None):
        """
        It is a round of asking question

            Input
                wrong_record
                    - It is unrelevant until all words was answerd
                    - If it is EMPTY then the chance depends on the points
                    - If it is NOT EMPTY the the same question will be asked until it answered

        """

        self.clear_console()

        record = self.myFilteredDictionary.get_next_random_record(wrong_record)

        # show the part of speech
        self.out_pos(record.part_of_speach)

        # shows the question word
        self.out_question(record.base_word + " - ",
                          "(" + str(len(record.learning_words)) + ")",
                          " " + record.note if self.show_note else "")

        # show stat
        overall = self.myFilteredDictionary.get_recent_stat_list()
        overall_str = str(overall[1]) + "/" + str(overall[0]) + (
            "/" + str(overall[2]) if overall[2] > 0 else "") + " (" + (str(
                int(100 * overall[1] /
                    overall[0])) if overall[0] > 0 else "") + "%)"
        actual = record.get_recent_stat()
        points = self.myFilteredDictionary.get_points(actual)
        self.out_stat(overall_str, actual, points)

        # say out the question
        if self.say_out:
            record.say_out_base()

        # replace every alphabetic character to _ to show under cursor
        if self.show_pattern:
            template = re.sub(r"[^, \!]", "_",
                              ", ".join(record.learning_words))
        else:
            template = ""

        # cut the answer by the separator -> list
        line = [i.strip() for i in self.get_input(template).split(",")]

        # shows the difference between the the answer and the good answer -> tuple
        # [0] -> False/True
        # [1] -> list of list of the positions of the difference in the words
        result = record.check_answer(line)

        # write back the stat
        self.myFilteredDictionary.add_result_to_stat(record.word_id, result[0])

        # good answer
        if result[0]:
            self.out_good_answer_right(record.learning_words)
        # wrong answer
        else:
            self.out_correction(result[1], line, record.learning_words)
            self.out_good_answer_wrong(record.learning_words)

        #shows statistics
        overall = self.myFilteredDictionary.get_recent_stat_list()
        overall_str = str(overall[1]) + "/" + str(overall[0]) + (
            "/" + str(overall[2]) if overall[2] > 0 else "") + " (" + str(
                int(100 * overall[1] / overall[0])) + "%)"
        actual = record.get_recent_stat()
        points = self.myFilteredDictionary.get_points(actual)
        self.out_stat(overall_str, actual, points)

        # say out the right answer
        if self.say_out:
            record.say_out_learning()

        #waitin for a click to continue
        input()

        return None if result[0] else record

    def clear_console(self):
        sys.stdout.write("\033[2J")

    def out_question(self, question, number_of_words, note):
        sys.stdout.write(type(self).POSITION_QUESTION)
        sys.stdout.write(type(self).COLOR_QUESTION)
        print(question, end="")

        sys.stdout.write(type(self).COLOR_NUMBER_OF_WORDS)
        print(number_of_words, end="")

        sys.stdout.write(type(self).COLOR_NOTE)
        print(note)

        sys.stdout.write(type(self).COLOR_DEFAULT)

    def get_input(self, template):
        sys.stdout.write(type(self).POSITION_INPUT)
        sys.stdout.write(type(self).COLOR_INPUT)
        print(template)
        sys.stdout.write(type(self).POSITION_INPUT)

        return input()

    def out_result_status(self, status):
        sys.stdout.write(type(self).POSITION_RESULT_STATUS)
        if status:
            sys.stdout.write(type(self).COLOR_RESULT_STATUS_RIGHT)
            print(type(self).STATUS_RIGHT)
        else:
            sys.stdout.write(type(self).COLOR_RESULT_STATUS_WRONG)
            print(type(self).STATUS_WRONG)

        sys.stdout.write(type(self).COLOR_DEFAULT)

    def out_pos(self, pos):
        sys.stdout.write(type(self).POSITION_POS)
        sys.stdout.write(type(self).COLOR_POS)
        print(pos, sep=", ")

    def out_good_answer_right(self, answer):
        #sys.stdout.write(type(self).POSITION_GOOD_ANSWER)
        #sys.stdout.write(type(self).COLOR_GOOD_ANSWER_RIGHT)
        #print( *answer, sep=", ")
        #sys.stdout.write(type(self).COLOR_DEFAULT)
        self.out_result_status(True)

    def out_good_answer_wrong(self, answer):
        sys.stdout.write(type(self).POSITION_GOOD_ANSWER)
        sys.stdout.write(type(self).COLOR_GOOD_ANSWER_WRONG)
        print(*answer, sep=", ")

        sys.stdout.write(type(self).COLOR_DEFAULT)
        self.out_result_status(False)

    def out_stat(self, overall, specific, points):
        sys.stdout.write(type(self).POSITION_STAT)
        sys.stdout.write(type(self).COLOR_STAT)

        print(overall, specific, "(" + str(points) + ")")

        sys.stdout.write(type(self).COLOR_DEFAULT)

    def out_correction(self, result, line, learning_words):
        sys.stdout.write(type(self).POSITION_CORRECTION)

        zipped_list = list(
            zip(
                line + ["_" * len(i) for i in learning_words][len(line):],
                learning_words + [" " * len(i)
                                  for i in line][len(learning_words):]))
        for word_failed_position_pair in zip(
            [i[0] + ("_" * len(i[1]))[len(i[0]):] for i in zipped_list],
                result):
            for pos in range(len(word_failed_position_pair[0])):
                if pos in word_failed_position_pair[1]:
                    sys.stdout.write(type(self).COLOR_CORRECTION_WRONG)
                else:
                    sys.stdout.write(type(self).COLOR_CORRECTION_RIGHT)
                print(word_failed_position_pair[0][pos], end="")
            print(", ", end="")
        sys.stdout.write(type(self).COLOR_DEFAULT)

    # this need to use the class with "with"
    def __enter__(self):
        return self

    # this need to us the class with "with"
    # the reason of using it "with" is to get back the default coursor color at the end
    def __exit__(self, exc_type, value, traceback):
        sys.stdout.write(type(self).COLOR_DEFAULT)
        print("")
        return isinstance(
            value, KeyboardInterrupt)  #Supress the KeyboardInterrupt exception
Esempio n. 3
0
class AskingCanvas(QWidget):
    FIELD_DISTANCE = 3

    def __init__(self, status_bar, file_name, part_of_speech_filter,
                 extra_filter):
        super().__init__()

        config_ini = ConfigIni.getInstance()
        self.status_bar = status_bar

        self.myFilteredDictionary = FilteredDictionary(
            file_name, config_ini.getBaseLanguage(),
            config_ini.getLearningLanguage(), part_of_speech_filter,
            extra_filter)

        good_answer = [""]

        self.pos_field = TextLabel("",
                                   font="Courier New",
                                   size=10,
                                   color=Qt.gray)

        self.question_field = TextLabel("",
                                        font="Courier New",
                                        size=13,
                                        color=QColor(212, 140, 95))

        self.note_field = TextLabel("",
                                    font="Courier New",
                                    size=10,
                                    color=Qt.gray,
                                    bold=True,
                                    italic=True)

        self.answer_field = AnswerComplexField(
            good_answer,
            spacing=AskingCanvas.FIELD_DISTANCE,
            font="Courier new",
            size=15,
            color=Qt.blue,
            bg=self.palette().color(QPalette.Background))
        #self.answer_field.disableText()

        self.good_answer_field = ExpectedAnswerComplexField(
            good_answer,
            spacing=AskingCanvas.FIELD_DISTANCE,
            font="Courier new",
            size=15,
            color=Qt.black,
            bg=self.palette().color(QPalette.Background))

        self.result_lamp = ResultLamp(failed_position_list=None)

        self.ok_button = OKButton(self)

        # --------------------
        # general grid setting
        # --------------------
        #
        grid = QGridLayout()
        self.setLayout(grid)
        grid.setSpacing(1)  # space between the fields

        # --------------------
        # Fields location
        # --------------------

        fields_columns = 4

        # PART OF SPEECH field
        grid.addWidget(self.pos_field, 0, 0, 1, fields_columns)

        # QUESTION field
        grid.addWidget(self.question_field, 1, 0, 1, fields_columns - 1)

        # NOTE field
        grid.addWidget(self.note_field, 1, fields_columns - 1, 1, 1,
                       Qt.AlignRight)

        # ANSWER field
        grid.addWidget(self.answer_field, 5, 0, 1, fields_columns - 1)

        # EXPECTED ANSWER field
        grid.addWidget(self.good_answer_field, 6, 0, 1, fields_columns - 1)

        # OK buttn
        grid.addWidget(self.ok_button, 5, fields_columns - 1, 1, 1,
                       Qt.AlignRight)

        # RESULT lamp
        grid.addWidget(self.result_lamp, 6, fields_columns - 1, 1, 1,
                       Qt.AlignRight)


#        self.setGeometry(300, 300, 450, 150)
#        self.setWindowTitle(_("TITLE_WINDOW"))
#        self.show()

    def showStat(self):
        overall = self.myFilteredDictionary.get_recent_stat_list()

        good = str(overall[1])
        all = str(overall[0])
        remains = str(overall[2]) if overall[2] > 0 else ""
        success = str(int(100 * overall[1] /
                          overall[0])) + "%" if overall[0] != 0 else ""
        recent_stat = self.record.get_recent_stat()
        sequence = ", ".join([str(i) for i in recent_stat])
        points = str(self.myFilteredDictionary.get_points(recent_stat))

        message = good + "/" + all + (
            "/" + remains if len(remains.strip()) > 0 else
            "") + " | " + success + " | " + points + " | " + sequence
        self.status_bar.showMessage(message)

    def round(self, wrong_record=None):
        """
            Frame of asking word.
            The other part of hte round is in the OKButton's on_click() method

            -calculates the the new word to ask
            -fill up the POS field
            -fill up the QUESTION field
            -fill up the ANSWER field
            -fill up the EXPECTED ANSWER field
            -say out the question
            -waiting for the user response

            Input
                wrong_record
                    - It is unrelevant until all words was answerd
                    - If it is EMPTY then the chance depends on the points
                    - If it is NOT EMPTY the the same question will be asked until it answered
            
        """

        # hides the result lamp
        self.result_lamp.set_result(None)

        self.record = self.myFilteredDictionary.get_next_random_record(
            wrong_record)
        good_answer = self.record.learning_words

        # pos field
        self.pos_field.setText(self.record.part_of_speach)

        # question
        self.question_field.setText(self.record.base_word)

        config_ini = ConfigIni.getInstance()

        # note field
        if config_ini.isShowNote():
            self.note_field.setText(self.record.note)

        # answer
        self.answer_field.setExpectedWordList(good_answer)
        self.answer_field.enableText()

        # expected answer
        self.good_answer_field.setExpectedWordList(good_answer)

        # say out the question in a thread
        if config_ini.isSayOut():
            Thread(target=self.record.say_out_base, args=()).start()

        self.answer_field.setFirstFocus()

        # shows statistics
        self.showStat()