def IPA_exact_query(self, phoneme_string):
        """Returns a list of languages containing this phoneme."""

        phoneme = set.union(*IPAParser.parsePhon(phoneme_string))
        result = {}
        if 'vowel' in phoneme:
            if phoneme.intersection({'apical', 'diphthong', 'triphthong'}):
                phoneme_key = frozenset(phoneme)
                if phoneme_key in self.non_systematic:
                    return self.non_systematic[phoneme_key][1]
                else:
                    return []
            height = phoneme.intersection(self.vow_rows).pop()
            y_coord = self.vow_y_coords[height]
            row = phoneme.intersection(self.vow_cols).pop()
            x_coord = self.vow_x_coords[row]
            for key in self.vow_table[y_coord][x_coord]:
                if key == phoneme:
                    return self.vow_table[y_coord][x_coord][key][1]
            return []         
        else:
            manner = phoneme.intersection(self.cons_rows).pop()
            y_coord = self.cons_y_coords[manner]
            place = phoneme.intersection(self.cons_cols).pop()
            x_coord = self.cons_x_coords[place]
            for key in self.cons_table[y_coord][x_coord]:
                if key == phoneme:
                    return self.cons_table[y_coord][x_coord][key][1]
            return []
        raise Exception("Unreachable!")
    def IPA_query(self, phoneme_string):
        """Returns a dictionary with languages containing this phoneme and its derivatives."""

        phoneme = set.union(*IPAParser.parsePhon(phoneme_string))
        result = {}
        if 'vowel' in phoneme:
            if phoneme.intersection({'apical', 'diphthong', 'triphthong'}):
                for key in self.non_systematic:
                    if key.issuperset(phoneme):
                        glyph = self.non_systematic[key][0]
                        langs = self.non_systematic[key][1]
                        result[glyph] = langs
                return result
            height = phoneme.intersection(self.vow_rows).pop()
            y_coord = self.vow_y_coords[height]
            row = phoneme.intersection(self.vow_cols).pop()
            x_coord = self.vow_x_coords[row]
            for key in self.vow_table[y_coord][x_coord]:
                if key.issuperset(phoneme):
                    glyph = self.vow_table[y_coord][x_coord][key][0]
                    langs = self.vow_table[y_coord][x_coord][key][1]
                    result[glyph] = langs
            return result
        else:
            manner = phoneme.intersection(self.cons_rows).pop()
            y_coord = self.cons_y_coords[manner]
            place = phoneme.intersection(self.cons_cols).pop()
            x_coord = self.cons_x_coords[place]
            for key in self.cons_table[y_coord][x_coord]:
                if key.issuperset(phoneme):
                    glyph = self.cons_table[y_coord][x_coord][key][0]
                    langs = self.cons_table[y_coord][x_coord][key][1]
                    result[glyph] = langs
            return result
        raise Exception("Unreachable!")
 def add_language(self, lang_name, phonemes):
     self.all_langs.add(lang_name)
     self.inv_dic[lang_name] = set()
     # We do not account for polyphthongs and apical vowels for now -- todo!
     for phoneme in phonemes:
         glyph = phoneme
         phoneme = set.union(*IPAParser.parsePhon(phoneme))
         phoneme_key = frozenset(phoneme)
         self.inv_dic[lang_name].add(phoneme_key)
         if phoneme_key not in self.all_phonemes:
             self.all_phonemes[phoneme_key] = glyph
         if 'vowel' in phoneme:
             if phoneme.intersection({'apical', 'diphthong', 'triphthong'}):
                 if phoneme_key not in self.non_systematic:
                     self.non_systematic[phoneme_key] = [glyph, []]
                 self.non_systematic[phoneme_key][1].append(lang_name)
                 continue
             height = phoneme.intersection(VOW_ROW_NAMES).pop()
             y_coord = self.vow_y_coords[height]
             row = phoneme.intersection(VOW_COL_NAMES).pop()
             x_coord = self.vow_x_coords[row]
             if phoneme_key not in self.vow_table[y_coord][x_coord]:
                 self.vow_table[y_coord][x_coord][phoneme_key] = (glyph, [])
             self.vow_table[y_coord][x_coord][phoneme_key][1].append(lang_name)
         else:
             try:
                 manner = phoneme.intersection(CONS_ROW_NAMES).pop()
             except KeyError:
                 raise Exception("A consonant does not have a manner:", phoneme)
             y_coord = self.cons_y_coords[manner]
             place = phoneme.intersection(CONS_COL_NAMES).pop()
             x_coord = self.cons_x_coords[place]
             if phoneme_key not in self.cons_table[y_coord][x_coord]:
                 self.cons_table[y_coord][x_coord][phoneme_key] = (glyph, [])
             self.cons_table[y_coord][x_coord][phoneme_key][1].append(lang_name)
    def IPA_query(self, phoneme_string):
        """Returns a dictionary with languages containing this phoneme and its derivatives."""

        phoneme = set.union(*IPAParser.parsePhon(phoneme_string))
        result = {}
        if 'vowel' in phoneme:
            if phoneme.intersection({'apical', 'diphthong', 'triphthong'}):
                for key in self.non_systematic:
                    if key.issuperset(phoneme):
                        glyph = self.non_systematic[key][0]
                        langs = self.non_systematic[key][1]
                        result[glyph] = langs
                return result
            height = phoneme.intersection(self.vow_rows).pop()
            y_coord = self.vow_y_coords[height]
            row = phoneme.intersection(self.vow_cols).pop()
            x_coord = self.vow_x_coords[row]
            for key in self.vow_table[y_coord][x_coord]:
                if key.issuperset(phoneme):
                    glyph = self.vow_table[y_coord][x_coord][key][0]
                    langs = self.vow_table[y_coord][x_coord][key][1]
                    result[glyph] = langs
            return result
        else:
            manner = phoneme.intersection(self.cons_rows).pop()
            y_coord = self.cons_y_coords[manner]
            place = phoneme.intersection(self.cons_cols).pop()
            x_coord = self.cons_x_coords[place]
            for key in self.cons_table[y_coord][x_coord]:
                if key.issuperset(phoneme):
                    glyph = self.cons_table[y_coord][x_coord][key][0]
                    langs = self.cons_table[y_coord][x_coord][key][1]
                    result[glyph] = langs
            return result
        raise Exception("Unreachable!")
    def IPA_exact_query(self, phoneme_string):
        """Returns a list of languages containing this phoneme."""

        phoneme = set.union(*IPAParser.parsePhon(phoneme_string))
        result = {}
        if 'vowel' in phoneme:
            if phoneme.intersection({'apical', 'diphthong', 'triphthong'}):
                phoneme_key = frozenset(phoneme)
                if phoneme_key in self.non_systematic:
                    return self.non_systematic[phoneme_key][1]
                else:
                    return []
            height = phoneme.intersection(self.vow_rows).pop()
            y_coord = self.vow_y_coords[height]
            row = phoneme.intersection(self.vow_cols).pop()
            x_coord = self.vow_x_coords[row]
            for key in self.vow_table[y_coord][x_coord]:
                if key == phoneme:
                    return self.vow_table[y_coord][x_coord][key][1]
            return []         
        else:
            manner = phoneme.intersection(self.cons_rows).pop()
            y_coord = self.cons_y_coords[manner]
            place = phoneme.intersection(self.cons_cols).pop()
            x_coord = self.cons_x_coords[place]
            for key in self.cons_table[y_coord][x_coord]:
                if key == phoneme:
                    return self.cons_table[y_coord][x_coord][key][1]
            return []
        raise Exception("Unreachable!")
 def add_language(self, lang_name, phonemes):
     self.all_langs.add(lang_name)
     self.inv_dic[lang_name] = set()
     # We do not account for polyphthongs and apical vowels for now -- todo!
     for phoneme in phonemes:
         glyph = phoneme
         phoneme = set.union(*IPAParser.parsePhon(phoneme))
         phoneme_key = frozenset(phoneme)
         self.inv_dic[lang_name].add(phoneme_key)
         if phoneme_key not in self.all_phonemes:
             self.all_phonemes[phoneme_key] = glyph
         if 'vowel' in phoneme:
             if phoneme.intersection({'apical', 'diphthong', 'triphthong'}):
                 if phoneme_key not in self.non_systematic:
                     self.non_systematic[phoneme_key] = [glyph, []]
                 self.non_systematic[phoneme_key][1].append(lang_name)
                 continue
             height = phoneme.intersection(VOW_ROW_NAMES).pop()
             y_coord = self.vow_y_coords[height]
             row = phoneme.intersection(VOW_COL_NAMES).pop()
             x_coord = self.vow_x_coords[row]
             if phoneme_key not in self.vow_table[y_coord][x_coord]:
                 self.vow_table[y_coord][x_coord][phoneme_key] = (glyph, [])
             self.vow_table[y_coord][x_coord][phoneme_key][1].append(lang_name)
         else:
             try:
                 manner = phoneme.intersection(CONS_ROW_NAMES).pop()
             except KeyError:
                 raise Exception("A consonant does not have a manner:", phoneme)
             y_coord = self.cons_y_coords[manner]
             place = phoneme.intersection(CONS_COL_NAMES).pop()
             x_coord = self.cons_x_coords[place]
             if phoneme_key not in self.cons_table[y_coord][x_coord]:
                 self.cons_table[y_coord][x_coord][phoneme_key] = (glyph, [])
             self.cons_table[y_coord][x_coord][phoneme_key][1].append(lang_name)
 def feature_rating(self, feature):
     feature_havers = {}
     for lang in self.features_query(feature):
         counter = 0
         for phon in engine.lang_dic[lang]:
             if feature in set.union(*IPAParser.parsePhon(phon)):
                 counter += 1
         feature_havers[lang] = counter
     rating = []
     for key, value in feature_havers.items():
         rating.append((value, key))
     rating.sort(reverse = True)
     return rating
 def feature_rating(self, feature):
     feature_havers = {}
     for lang in self.features_query(feature):
         counter = 0
         for phon in engine.lang_dic[lang]:
             if feature in set.union(*IPAParser.parsePhon(phon)):
                 counter += 1
         feature_havers[lang] = counter
     rating = []
     for key, value in feature_havers.items():
         rating.append((value, key))
     rating.sort(reverse = True)
     return rating