Exemplo n.º 1
0
 def testFindRoot(self):
     """ Test finding the tree root of a word """
     # Search for biology, since it's in two trees
     db = self.getDB()
     # First get references to the words
     num_trees, matched_words = cf.searchDB(db, "biology")
     test_source = matched_words[0][1]
     test_root = matched_words[0][0]
     self.assertEqual(num_trees, 2)
     # Find the root
     tree_root = cf.findRoot(test_source)
     tree_root_details = cf.loadWordDetails(tree_root)
     # Confirm it's right
     self.assertEqual(tree_root_details["lang"], "PIE")
     self.assertEqual(tree_root_details["morpheme"], "gweie")
     self.assertEqual(test_root, tree_root)
     # Now try the other biology tree
     test_source = matched_words[1][1]
     test_root = matched_words[1][0]
     # Find the root
     tree_root = cf.findRoot(test_source)
     tree_root_details = cf.loadWordDetails(tree_root)
     # Confirm it's right
     self.assertEqual(tree_root_details["lang"], "PIE")
     self.assertEqual(tree_root_details["morpheme"], "leg")
     self.assertEqual(test_root, tree_root)
Exemplo n.º 2
0
def choose_word_from_many(words):
    """ From a list of matched words, prompts the user to select which one

        words is a list of tuples, each tuple is (tree,word).
        Returns the one (tree,word) tuple.

    """
    # Find the morphemes,language for each instance
    mor_lan = []
    word_text = cf.loadWordDetails(words[0][1])['text'][0]
    for item in words:
        word = item[1]
        word_details = cf.loadWordDetails(word)
        mor_lan.append( (word_details['morpheme'], word_details['lang']) )

    print('For the word {0}, {1} options are available:'.format(
        word_text, len(mor_lan)))
    for item in enumerate(mor_lan, 1):
        print('  {0}: In {1}, choose the {2} morpheme'.format(
            item[0], item[1][1], item[1][0]))
    item_select = get_num_choice(min_num=1, max_num=len(mor_lan))

    print('{0} morpheme of {1} chosen'.format(
        mor_lan[item_select-1][0], word_text))
    return words[item_select-1]
Exemplo n.º 3
0
    def UpdateWordDetails(self):
        """ Update various widgets when a tree item has been selected """
        # Set the 'word details' widgets
        nodeDetails = cf.loadWordDetails(self.current_node)
        alt_text = ', '.join(nodeDetails['text'])
        self.langbox.ChangeValue(nodeDetails['lang'])
        self.defbox.ChangeValue(nodeDetails['def'])
        self.altbox.ChangeValue(alt_text)

#        # Update the search word if applicable
#        if self.search_on_select:
#            self.search_word = node.xpath('text')[0].text
#            self.searchbox.SetValue(self.search_word)
#            # TODO: bold, debold the tree control

        # Highlight matching alternates, if applicable
        if self.search_word in alt_text:
            # Set the style
            bold_style = self.altbox.GetDefaultStyle()
            bold_font = bold_style.GetFont()
            bold_font.SetWeight(wx.FONTWEIGHT_BOLD)
            bold_style.SetFont(bold_font)
            # Find the start/end indices
            str_start = alt_text.find(self.search_word)
            # Bold the word
            self.altbox.SetStyle(str_start,
                    str_start+len(self.search_word),bold_style)
Exemplo n.º 4
0
 def testReadWordDetails(self):
     """ Test reading the details of a word """
     chosen_word = self.getWord("horse")
     wordDets = cf.loadWordDetails(chosen_word)
     self.assertEqual(wordDets["lang"], "Middle English")
     self.assertEqual(wordDets["def"], "A horse that you feed oats")
     self.assertEqual(wordDets["text"], ["horse", "hors", "horce", "horsse", "horis", "hos", "ors"])
Exemplo n.º 5
0
 def MenuTreeItem(self, event):
     """ Right-click menu for a tree item """
     self.current_node = self.treebox.GetPyData(event.GetItem())
     # Create the menu
     menu = wx.Menu()
     www_item_id = wx.NewId()
     menu.Append(www_item_id, 'Lookup on etymonline')
     menu.AppendSeparator()
     child_item_id = wx.NewId()
     menu.Append(child_item_id, 'Add child word')
     sib_item_id = wx.NewId()
     menu.Append(sib_item_id, 'Add sibling word')
     del_item_id = wx.NewId()
     menu.Append(del_item_id, 'Delete word')
     # Disable items if not in edit mode
     if not self.edit_mode:
         menu.Enable(child_item_id, False)
         menu.Enable(sib_item_id, False)
         menu.Enable(del_item_id, False)
     # Disable add sibling if we're on the root word (no parent)
     if cf.loadWordDetails(self.current_node)['tag'] == 'tree':
         menu.Enable(sib_item_id, False)
     # Bind events
     menu.Bind(wx.EVT_MENU, self.TreeItemLookupWWW, id=www_item_id)
     menu.Bind(wx.EVT_MENU, self.TreeItemAddChild, id=child_item_id)
     menu.Bind(wx.EVT_MENU, self.TreeItemAddSib, id=sib_item_id)
     menu.Bind(wx.EVT_MENU, self.TreeItemDelete, id=del_item_id)
     # Show the menu
     self.treebox.PopupMenu(menu)
Exemplo n.º 6
0
    def DisplayTree(self, root, nodes, select=None):
        """ Displays the tree in the wx.TreeCtrl object 

            root is the ElementTree root node.
            nodes is a list of ElementTree word nodes to emphasize.
            If root is None, then is displays an empty tree message.
            select is a word that is selected (focused), this overrides
            focusing on any emphasized nodes.
        """
        self.treebox.DeleteAllItems()
        if root is None:
            self.treebox.AddRoot('No matches found')
            self.editchk.Disable()
            self.editchk.SetValue(False)
            self.editbtn_save.Disable()
            self.editbtn_revert.Disable()
            self.langbox.ChangeValue('')
            self.defbox.ChangeValue('')
            self.altbox.ChangeValue('')
            self.selected_node = None
        else:
            root_details = cf.loadWordDetails(root)
            root_elem = self.treebox.AddRoot(root_details['text'][0],
                    data = wx.TreeItemData(root))
            if type(nodes) is not list:
                nodes = [nodes]
            self._populate_tree(root, root_elem, nodes, select)
            self.treebox.ExpandAll()
            self.editchk.Enable()
Exemplo n.º 7
0
    def _populate_tree(self, node, node_elem, emph_nodes, select):
        """ Recursive private function to fill in the rest of the tree control 

            node: the ElementTree element we're working on.
            node_elem: the corresponding object in the TreeCtrl class.
            emph_nodes: a list of ElementTree elements, 
            these will be emphasized.
            select: an element that will be selected (focused). If not None
            then it overrides focusing on emphasized nodes.

        """
        # len() of a node returns how many children it has
        if cf.countWordChildren(node) > 0:
            for child in cf.loadWordChildren(node):
                child_details = cf.loadWordDetails(child)
                # Just display the first alternate
                child_label = child_details['text'][0] 
                child_elem = self.treebox.AppendItem(node_elem, child_label,
                        data = wx.TreeItemData(child))
                if child in emph_nodes and select is None:
                    # Emphasize the node
                    self.treebox.SetItemBold(child_elem)
                    # Select the node
                    self.treebox.SelectItem(child_elem)
                if select is not None and child == select:
                    self.treebox.SelectItem(child_elem)
                # Recurse!
                self._populate_tree(child, child_elem, emph_nodes, select)
Exemplo n.º 8
0
    def testCreateWord(self):
        """ Test creating a new word """
        # Try some bad inputs
        word_dets = None
        self.assertRaises(cf.EtymExceptWord, cf.createWord, word_dets)
        word_dets = {}
        self.assertRaises(cf.EtymExceptWord, cf.createWord, word_dets)
        word_dets = {"lang": "English"}
        self.assertRaises(cf.EtymExceptWord, cf.createWord, word_dets)
        word_dets = {"lang": "English", "text": "banana", "morpheme": "bannana", "def": "A fruity thing"}
        self.assertRaises(cf.EtymExceptWord, cf.createWord, word_dets)

        # Now a good input, test the output
        word_dets = {
            "lang": "English",
            "text": ["banana", "pineapple"],
            "morpheme": "bannana",
            "def": "A fruity thing",
            "tag": "word",
        }
        new_word = cf.createWord(word_dets)
        new_word_details = cf.loadWordDetails(new_word)
        self.assertEqual(word_dets, new_word_details)

        # Try creating a word with a specified parent/children
        child_dets = {"lang": "Spanglish", "text": ["strawberry"], "morpheme": "strawberry", "def": "A fruity thing"}
        parent_dets = {"lang": "Fromesian", "text": ["raspberry"], "morpheme": "raspberry", "def": "A fruity thing"}
        word_dets = {"lang": "English", "text": ["banana"], "morpheme": "banana", "def": "A fruity thing"}
        new_child = cf.createWord(child_dets)
        new_parent = cf.createWord(parent_dets)
        new_word = cf.createWord(word_dets, word_parent=new_parent, word_children=new_child)
        self.assertEqual(cf.loadWordChildren(new_word)[0], new_child)
        self.assertEqual(cf.loadWordParents(new_word), new_parent)
Exemplo n.º 9
0
    def testAddTree(self):
        """ Test adding a tree """
        # Create a test word to attach to the new tree
        word_dets = {
            "lang": "English",
            "text": ["banana", "pineapple"],
            "morpheme": "banana",
            "def": "A fruity thing",
            "tag": "word",
        }
        new_word = cf.createWord(word_dets)
        new_word_details = cf.loadWordDetails(new_word)
        self.assertEqual(word_dets, new_word_details)
        # Create the new tree
        db = self.getDB()
        tree_dets = {"lang": "PIE", "text": ["bane"], "morpheme": "bane", "def": "Some fruit", "tag": "tree"}
        cf.addTree(db, tree_dets, [new_word])
        # Test that it was created
        num_trees, matched_words = cf.searchDB(db, "banana")
        search_word = matched_words[0][1]
        search_root = matched_words[0][0]
        search_root_dets = cf.loadWordDetails(search_root)
        self.assertEqual(search_word, new_word)
        self.assertEqual(search_root_dets["lang"], "PIE")
        self.assertEqual(search_root_dets["def"], "Some fruit")
        self.assertEqual(search_root_dets["morpheme"], "bane")
        self.assertEqual(search_root_dets["text"], ["bane"])

        # Okay, now test some bad input
        # second arg not a list
        self.assertRaises(cf.EtymExceptWord, cf.addTree, db, tree_dets, new_word)
        # No word given
        self.assertRaises(cf.EtymExceptWord, cf.addTree, db, tree_dets, [None])
        self.assertRaises(cf.EtymExceptWord, cf.addTree, db, tree_dets, [])
        # Invalid db
        self.assertRaises(cf.EtymExceptDB, cf.addTree, None, tree_dets, [new_word])
        # Bad tree details
        tree_dets = {"lang": "PIE", "text": "bane", "morpheme": "bane", "tag": "tree"}
        self.assertRaises(cf.EtymExceptWord, cf.addTree, db, tree_dets, [new_word])
Exemplo n.º 10
0
 def testReadWordChildren(self):
     """ Test reading the children of a word """
     # This word shouldn't have any children
     chosen_word = self.getWord("hross")
     word_children = cf.loadWordChildren(chosen_word)
     self.assertEqual(word_children, [])
     self.assertRaises(cf.EtymExceptWord, cf.loadWordDetails, word_children)
     # This word should have one child
     chosen_word = self.getWord("far")
     word_children = cf.loadWordChildren(chosen_word)
     wordDets = cf.loadWordDetails(word_children[0])
     self.assertEqual(wordDets["text"][0], "farrow")
     self.assertEqual(wordDets["lang"], "Modern English")
     self.assertEqual(wordDets["def"], "An obsolete word for a pig")
Exemplo n.º 11
0
def display_tree(tree, word, search_word):
    """ For a given word and tree, display the rest of the tree 

        The search_word is emphasized.

    """
    # Encapsulate word in a list if it isn't already
    if type(word) is not list:
        word = [word]

    tree_details = cf.loadWordDetails(tree)
    print('Root: {0} ({1})'.format(tree_details['text'][0],
        tree_details['lang']))
    display_children(tree, 1, word, search_word)
Exemplo n.º 12
0
 def testReadWordParents(self):
     """ Test reading the parents of a word """
     # The root shouldn't have any parents
     # TODO: Re-enable this once I can search for roots
     #        chosen_word = self.getWord('khursa')
     #        word_parents = cf.loadWordParents(chosen_word)
     #        self.assertEqual(word_parents, None)
     #        self.assertRaises(cf.EtymExceptWord, cf.loadWordDetails, word_parents[0])
     # This word should have one parent
     chosen_word = self.getWord("horse")
     word_parents = cf.loadWordParents(chosen_word)
     wordDets = cf.loadWordDetails(word_parents)
     self.assertEqual(wordDets["text"][0], "hors")
     self.assertEqual(wordDets["lang"], "Old English")
     self.assertEqual(wordDets["def"], "A man-eating beast")
Exemplo n.º 13
0
    def testEditWordDetails(self):
        """ Test editing a word details """
        chosen_word = self.getWord("horse")
        orig_wordDets = cf.loadWordDetails(chosen_word)
        new_wordDets = orig_wordDets.copy()
        new_wordDets["lang"] = "Elvish"
        new_wordDets["def"] = "A helpful friend"
        new_wordDets["text"] = ["horsey", "neigh"]
        new_wordDets["morpheme"] = "horsey"

        # Try purposefully giving incorrect details
        test_wordDets = {}
        self.assertRaises(cf.EtymExceptWord, cf.editWordDetails, chosen_word, test_wordDets)

        # Try refreshing the word
        cf.editWordDetails(chosen_word, orig_wordDets)
        test_wordDets = cf.loadWordDetails(chosen_word)
        self.assertEqual(orig_wordDets, test_wordDets)

        # Try new details
        cf.editWordDetails(chosen_word, new_wordDets)
        test_wordDets = cf.loadWordDetails(chosen_word)
        self.assertEqual(new_wordDets, test_wordDets)
        self.assertNotEqual(orig_wordDets, test_wordDets)
Exemplo n.º 14
0
 def testChangeParent(self):
     """ Tests modifying the parent of a word """
     # This word has a parent, 'equinus'
     chosen_word = self.getWord("equine")
     # Make sure it can read the parent
     test_parent = cf.loadWordParents(chosen_word)
     parent_details = cf.loadWordDetails(test_parent)
     self.assertEqual(parent_details["text"], ["equinus"])
     self.assertEqual(parent_details["lang"], "Latin")
     # Add a new word and set its parent
     word_dets = {"lang": "English", "text": ["banana", "pineapple"], "morpheme": "bannana", "def": "A fruity thing"}
     new_word = cf.createWord(word_dets)
     cf.editWordParent(new_word, test_parent)
     self.assertEqual(cf.countWordChildren(test_parent), 2)
     self.assertEqual(cf.countWordChildren(chosen_word), 0)
     cf.editWordParent(new_word, chosen_word)
     self.assertEqual(cf.countWordChildren(chosen_word), 1)
     # Add a new word and it to be parent to a word
     new_word = cf.createWord(word_dets)
     cf.editWordParent(chosen_word, new_word)
     self.assertEqual(new_word, cf.loadWordParents(chosen_word))
Exemplo n.º 15
0
    def OnSearch(self, event):
        """ Searches for a word, displays results """
        self.search_word = self.searchbox.GetValue()
        if self.search_word is not '': # Simple validation for now
            num_trees, matched_words = cf.searchDB(self.words_tree,
                    self.search_word)
            self.treebox.DeleteAllItems() # Clear the tree control out
            self.searchchoice.Clear() # Clear out the choice box
            self.searchchoice.Disable()
            wx.xrc.XRCCTRL(self.frame, 'et_txtLang').SetEditable(self.edit_mode)
            wx.xrc.XRCCTRL(self.frame, 'et_txtDef').SetEditable(self.edit_mode)
            wx.xrc.XRCCTRL(self.frame, 'et_txtAlt').SetEditable(self.edit_mode)
            if num_trees == 0:
                chosen_root = chosen_word = None
            elif num_trees > 1:
                # Populate the tree with the first match
                chosen_root = matched_words[0][0]
                chosen_word = [match[1] for match in matched_words]
                # Populate the choice button
                for item in matched_words:
                    word = item[1]
                    word_details = cf.loadWordDetails(word)
                    choice_text = '{0} ({1})'.format(
                            word_details['morpheme'], word_details['lang'])
                    self.searchchoice.Append(choice_text, item)

                self.searchchoice.Enable()
                self.searchchoice.SetSelection(0)
            else:
                # Extract the tree and all matched words separately
                # Just pick the first entry (m_w[...][0] are the 
                # same in this case)
                chosen_root = matched_words[0][0]
                chosen_word = [match[1] for match in matched_words]

            self.search_root = chosen_root
            self.search_words = chosen_word
            self.DisplayTree(self.search_root, self.search_words)
Exemplo n.º 16
0
def display_children(node, depth, word, search_word):
    """ Recursive function to display children of a node

        depth is what level we're on.
        word is the word element we're looking for (it will be emphasized
        in the tree).
        search_word is the word text we're looking for.

    """
    # The len() of a node returns how many children it has
    if cf.countWordChildren(node) > 0:
        for child in cf.loadWordChildren(node):
            depth_marker = '  '*depth
            child_markup = ''
            child_details = cf.loadWordDetails(child)
            if child in word:
                # First we have the emphasized word
                # Then the other matches, if there
                child_markup = ', '.join(['*{0}*'.format(text_var)
                    for text_var in child_details['text'] 
                    if text_var == search_word])
                child_markup_rest = ', '.join(['{0}'.format(text_var)
                    for text_var in child_details['text'] 
                    if text_var != search_word])
                if child_markup_rest is not '':
                    child_markup = ', '.join([child_markup, child_markup_rest])
            else:
                child_markup = ', '.join(['{0}'.format(text_var)
                    for text_var in child_details['text']])

            print(u'{0}Child: {1} ({2}, "{3}")'.format(
                depth_marker, child_markup, child_details['lang'],
                child_details['def']))
            display_children(child, depth+1, word, search_word)
    else:
        # The base of the recursion simply does nothing
        pass
Exemplo n.º 17
0
 def TreeItemLookupWWW(self, event):
     """ Lookup an entry on etymonline """
     lookup_word = cf.loadWordDetails(self.current_node)
     wx.LaunchDefaultBrowser('http://www.etymonline.com/index.php?' 
                             'term={0}'.format(lookup_word['morpheme']))