Exemple #1
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
Exemple #2
0
class TestWordCycleFunctions(unittest.TestCase):
    BASE_NAME="testfile"
    DICT_FILE=BASE_NAME + "." + FilteredDictionary.DICT_EXT

    # Runs at the beginning of the test suit
    @classmethod
    def setUpClass(cls):
        """
        Creates a dict file with different content
        """
        content={
            "1":('v', 'group1', ['Abc', 'Adef', 'Aghij', 'Aklmnopq', 'A'], 'aaa' ),
            "2":('a', 'group1', ['Bcd', 'Befg', 'Bhijk'], 'bbb'),
            "3":('n', 'group1', ['Cde'], 'ccc'),
            "4":('b', 'group1', ['Def'], 'ddd')
        }

        # write into the test file the words
        with open( TestWordCycleFunctions.DICT_FILE, "w" ) as f:
            print(*[FilteredDictionary.RECORD_SPLITTER.join(
                [v[0]]+
                [v[1]]+
                [", ".join(v[2])]+
                [v[3]]
                ) for k, v in content.items()]
                , sep='\n', file=f)

    #Runs before every testcase
    def setUp(self): 
        pass
        #self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish') 

    def test_get_points_same_size_stat( self ):
        """
        Tests if a list of statistics have back the right points.
        The list and the expected points are the following:
            (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=3))}
            myFilteredDictionary.word_dict={
                "1":('v', ['AAA'], 'aaa', ''),
                "2":('v', ['BBB'], 'bbb', ''),
                "3":('v', ['CCC'], 'ccc', ''),
                "4":('v', ['DDD'], 'ddd', ''),
                "5":('v', ['EEE'], 'aaa', ''),
                "6":('v', ['FFF'], 'bbb', ''),
                "7":('v', ['GGG'], 'ccc', ''),
                "8":('v', ['HHH'], 'ddd', '')
            }
            expected_list=[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 )
            #print()
            #print(*[str(k) + "->" + str(myFilteredDictionary.get_points(v)) for k,v in myFilteredDictionary.recent_stat_list.items()], sep="\n")


    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 )
            #print()
            #print(*[str(k) + "->" + str(myFilteredDictionary.get_points(v)) for k,v in myFilteredDictionary.recent_stat_list.items()], sep="\n")


    def test_get_random_id_equal_chances_all( self ):
        """
        Tests if there is about 50%/50% chance to get the words
        which had not got good answer yet
        """
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish') 
        
        stat_list={
            "a": [0,0,0],   # no good answer
            "b": [0,0,0],   # no good answer
        } 

        result=Counter( [self.myFilteredDictionary.get_random_id(stat_list) for i in range(40000)] )
        self.assertAlmostEqual( result["b"] / result["a"], 1.0, delta=0.08)

    def test_get_random_id_equal_chances_some( self ):
        """
        Tests if there is 0.0% chance to get the word
        which had got a good answer
        """

        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish') 
        
        stat_list={
            "a": [0,0,0],   # no good answer
            "b": [0,1,0],   # there was 1 good answer
        }

        result=Counter( [self.myFilteredDictionary.get_random_id(stat_list) for i in range(40000)] )
        self.assertAlmostEqual( result["b"] / result["a"], 0.0, delta=0.0)

    def test_get_random_id_wighted_chance( self ):
        """
        Tests if the chance to get the words
        are proportional to the point (weight) what they have.
        """
       # 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={
                "a": [1,1,1],   # 1 point  (weight)
                "b": [0,1,1],   # 2 points (weight)
            }
            myFilteredDictionary.word_dict={
                "1":('v', ['AAA'], 'aaa', ''),
                "2":('v', ['BBB'], 'aaa', '')             
            }

            result=Counter( [myFilteredDictionary.get_random_id(myFilteredDictionary.recent_stat_list) for i in range(40000)] )
            self.assertAlmostEqual( result["b"] / result["a"], 2.0, delta=0.08)

    def test_get_next_random_record_only_one_good_answer( self ):
        """
        Tests if there is about same chance to get the words
        which had not got good answer yet
        """

        # 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={
                "1":[0,0,0],
                "2":[0,0,0],
                "3":[0,1,0],
                "4":[0,0,0],
            }
            myFilteredDictionary.word_dict={
                "1":('v', ['AAA'], 'aaa', ''),
                "2":('v', ['BBB'], 'bbb', ''),
                "3":('v', ['CCC'], 'ccc', ''),
                "4":('v', ['DDD'], 'ddd', '')
            }

            loop=300000
            result=Counter([myFilteredDictionary.get_next_random_record().base_word for i in range(loop)])
            self.assertAlmostEqual( loop/3, result['aaa'], delta=600)
            self.assertAlmostEqual( loop/3, result['bbb'], delta=600)
            self.assertAlmostEqual( 0.0, result['ccc'], delta=0)
            self.assertAlmostEqual( loop/3, result['ddd'], delta=600)

    def test_get_next_has_good_answer( self ):
        """
        Tests if the chance to get the words
        are proportional to the point (weight) what they have.
        It means: 10%/20%/30%/40% in sequence
        """

        # 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={
                "1":[1,1,1],    # 1 point => 1/20 probability
                "2":[0,1,1],    # 2 points => 2/20 probability
                "3":[1,0,1],    # 4 points => 4/20 probability
                "4":[0,1,0],    # 6 points => 6/20 probability
                "5":[1,0,0],    # 7 points => 7/20 probability
            }
            myFilteredDictionary.word_dict={
                "1":('v', ['AAA'], 'aaa', ''),
                "2":('v', ['BBB'], 'bbb', ''),
                "3":('v', ['CCC'], 'ccc', ''),
                "4":('v', ['DDD'], 'ddd', ''),
                "5":('v', ['EEE'], 'eee', '')
            }

            loop=40000

            result=Counter([myFilteredDictionary.get_next_random_record().base_word for i in range(loop)])

            self.assertAlmostEqual(result['aaa']/loop, 1/20, delta=0.01)
            self.assertAlmostEqual(result['bbb']/loop, 2/20, delta=0.01)
            self.assertAlmostEqual(result['ccc']/loop, 4/20, delta=0.01)
            self.assertAlmostEqual(result['ddd']/loop, 6/20, delta=0.01)
            self.assertAlmostEqual(result['eee']/loop, 7/20, delta=0.01)
    
    def test_check_answer_true( self ):
        """
        Checks if I get True return and empty differece list 
        when all answer equals to the base
        """
        
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        
        answer=['Abc', 'Adef', 'Aghij', 'Aklmnopq', 'A']
        result=self.myFilteredDictionary.get_next_random_record().check_answer(answer)
        self.assertTrue(result[0])
        self.assertEqual(sum([1 for i in result[1] if len(i) != 0]), 0 )
 
    def test_check_answer_false_shorter_list( self ):
        """
        Checks if I get False return and the corresponding difference list
        when some answers are different to the bases
        """

        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        
        answer=['Adc', 'Adef', 'Adhlj', 'Aklmnopq']
        result=self.myFilteredDictionary.get_next_random_record().check_answer(answer)
        self.assertFalse(result[0])
        self.assertEqual(result[1][0],[1])
        self.assertEqual(result[1][1],[])
        self.assertEqual(result[1][2],[1,3])
        self.assertEqual(result[1][4],[0])

    def test_check_answer_false_longer_list( self ):
        """
        Checks if I get False return and the corresponding difference list
        when the answer list is longer than the base
        """

        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        
        answer=['Abc', 'Adef', 'Aghij', 'Aklmnopq', 'A', 'Abcd']
        result=self.myFilteredDictionary.get_next_random_record().check_answer(answer)
        self.assertFalse(result[0])
        self.assertEqual(result[1][0],[])
        self.assertEqual(result[1][1],[])
        self.assertEqual(result[1][2],[])
        self.assertEqual(result[1][3],[])
        self.assertEqual(result[1][4],[])
        self.assertEqual(result[1][5],[0, 1, 2, 3])

    def test_check_answer_false_shorter_answer( self ):
        """
        Checks if I get False return and the corresponding difference list
        when the answer list has at least one shorter answer than the base
        """
        
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        
        answer=['Abc', 'Adef', 'Agh', 'Aklmnopq', 'A']
        result=self.myFilteredDictionary.get_next_random_record().check_answer(answer)
        self.assertFalse(result[0])
        self.assertEqual(result[1][0],[])
        self.assertEqual(result[1][1],[])
        self.assertEqual(result[1][2],[3,4])
        self.assertEqual(result[1][3],[])
        self.assertEqual(result[1][4],[])

    def test_check_answer_false_longer_answer( self ):
        """
        Checks if I get False return and the corresponding difference list
        when the answer list has at least one longer answer than the base
        """        
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v')
        answer=['Abc', 'Adef', 'Aghijkl', 'Aklmnopq', 'A']
        result=self.myFilteredDictionary.get_next_random_record().check_answer(answer)
        self.assertFalse(result[0])
        self.assertEqual(result[1][0],[])
        self.assertEqual(result[1][1],[])
        self.assertEqual(result[1][2],[5,6])
        self.assertEqual(result[1][3],[])
        self.assertEqual(result[1][4],[])

    def test_check_answer_false_empty_answer( self ):
        """
        Checks if I get False return and the corresponding difference list
        when the answer list has at least one empty answer
        """        
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v')
        answer=['Abc', '', 'Aghij', 'Aklmnopq', 'A']
        result=self.myFilteredDictionary.get_next_random_record().check_answer(answer)
        self.assertFalse(result[0])
        self.assertEqual(result[1][0],[])
        self.assertEqual(result[1][1],[0,1,2,3])
        self.assertEqual(result[1][2],[])
        self.assertEqual(result[1][3],[])
        self.assertEqual(result[1][4],[])

    def test_recent_stat_of_one_word( self ):
        """
        Tests if the get_recent_stat() method gives back the right values
        """
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        
        record=self.myFilteredDictionary.get_next_random_record()
        self.myFilteredDictionary.add_result_to_stat(record.word_id, True)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, True)
        self.assertEqual( record.get_recent_stat(), [1,0,1] )
       
    def test_recent_stat_of_all_words(self):
        """
        Tests if the get_recent_stat_list() method gives back the right values
        """
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='') 
        
        record=self.myFilteredDictionary.get_next_random_record()
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, True)

        record=self.myFilteredDictionary.get_next_random_record()
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, True)

        record=self.myFilteredDictionary.get_next_random_record()
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, True)

        record=self.myFilteredDictionary.get_next_random_record()
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)
        self.myFilteredDictionary.add_result_to_stat(record.word_id, False)

        res_stat=self.myFilteredDictionary.get_recent_stat_list()
        self.assertEqual(res_stat[0], 13)
        self.assertEqual(res_stat[1], 3)
        self.assertEqual(res_stat[2], 1)

    def test_there_is_only_base_word(self):
        pass

    def _test_say_out_base(self):
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        self.myFilteredDictionary.get_next_random_record().say_out_base()

    def _test_say_out_learning(self):
        self.myFilteredDictionary=FilteredDictionary(TestWordCycleFunctions.BASE_NAME, 'hungarian', 'swedish', part_of_speach_filter='v') 
        self.myFilteredDictionary.get_next_random_record().say_out_learning()

    #Runs after every testcase - anyway	
    def tearDown(self): 
        pass

    # Runs at the end of the test suit
    @classmethod
    def tearDownClass(cls): 
        """
        Removes the dict file and the generated stat files
        """
        os.remove(TestWordCycleFunctions.DICT_FILE)
        os.remove(TestWordCycleFunctions.BASE_NAME+".bak")
        os.remove(TestWordCycleFunctions.BASE_NAME+".dat")
        os.remove(TestWordCycleFunctions.BASE_NAME+".dir")
Exemple #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()