Source code for namedex.namedex

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
An implementation of the soundex algorithm as mentioned in
https://www.wikiwand.com/en/Soundex.

"""
# Soundex constants
LETTER_TO_DROP = ['a', 'e', 'i', 'o', 'u', 'y', 'h', 'w']
LETTER_REPLACE_1 = ['b', 'f', 'p', 'v']
LETTER_REPLACE_2 = ['c', 'g', 'j', 'k', 'q', 's', 'x', 'z']
LETTER_REPLACE_3 = ['d', 't']
LETTER_REPLACE_4 = ['l']
LETTER_REPLACE_5 = ['m', 'n']
LETTER_REPLACE_6 = ['r']


[docs]def command_line(): """Run namedex in the commandline This function runs when the module is ran as a script. It only prints the results, it does not output to stout. """ name = input("Enter name: ") print(create_soundex(name)) return 0
[docs]def create_soundex(entered_name): """Creates the soundex for the given name and returns it. :param entered_name: The name to be converted into a soundex. :type entered_name: str :return: A soundex. :rtype: str """ initial = [] name = make_into_list(entered_name) # Append the first letter of the name to initial initial.append(name[0].upper()) name = convert_to_number(name) name = remove_adjacent_letters(name) name = remove_first_number(name) name = remove_dropped_letters(name) name = strip_and_pad(name) name.insert(0, initial[0]) name = ''.join(name) return name
[docs]def make_into_list(name): """Lower cases the name and converts it into a list. Takes the string passed in and lowercase it. Then it converts it to a list. :param name: A name as a string. :type name: str :return: The name all lower cased and made into a list. :rtype: list """ name = name.lower() return list(name)
[docs]def convert_to_number(name): """Replaces letters to corresponding numbers to build the soundex. :param name: The letters of the name split into a list. :type name: list :return: The corresponding numbers for the consonants. :rtype: list """ soundex = [] for letter in name: if letter in LETTER_REPLACE_1: soundex.append('1') elif letter in LETTER_REPLACE_2: soundex.append('2') elif letter in LETTER_REPLACE_3: soundex.append('3') elif letter in LETTER_REPLACE_4: soundex.append('4') elif letter in LETTER_REPLACE_5: soundex.append('5') elif letter in LETTER_REPLACE_6: soundex.append('6') else: soundex.append(letter) return soundex
[docs]def remove_adjacent_letters(name): """Removes digits that repeats. Removes duplicate digits that are adjacent to each other with a few exceptions. Duplicate digit that are adjacent are removed. If duplicate digits are separated by a 'w' or 'h' then remove one of the digits. If duplicate digits are separated by a 'w' or 'h' then remove one of the digits. If duplicate digits are separated by a 'w' or 'h' then remove one of the digits. If duplicate digits are separated by a vowel then leave the duplicate numbers. >>> remove_adjacent_letters(['4', '2', '2']) ['4', '2'] >>> remove_adjacent_letters(['4', '2', 'h', '2']) ['4', 'h', '2'] >>> remove_adjacent_letters(['4', '2', 'a', '2']) ['4', '2', 'a', '2'] :param name: A list of soudex numbers and vowels including 'w' and 'h'. :type name: list :return: Soundex numbers with duplicated numbers removed. :rtype: list """ if name == []: return [] last_letter = name[0] # Starts on index 1 because last_letter was initialized with index 0 for index, element in enumerate(name[1:]): # If the letter being compared is the same as last_letter, remove it. if element == last_letter: name.pop(index) last_letter = element # If duplicated number is separated by 'w' or 'h' then pop the second. elif element in ('h', 'w'): if name[index] == name[index + 2]: name.pop(index) last_letter = element else: last_letter = element return name
[docs]def remove_first_number(name): """Removes the first digit from list The first digit has to be removed at this point as required by the soundex algorithm. :param name: The name list :type name: list :return: The name list with the first digit removed. :rtype: list """ name.pop(0) return name
[docs]def remove_dropped_letters(name): """Remove the vowels, 'y', 'h', and 'w' from name. Removes all vowels and the the letters 'y', 'h', and 'w' from _name_. :param name: The name to be processed. :type name: list :return: name without vowels, 'y', 'h', or 'w' letters. :rtype: list """ for letter in name[:]: if letter in LETTER_TO_DROP: name.remove(letter) return name
[docs]def strip_and_pad(name): """Makes the list 3 digits long. If the _name_ list is passed in with more than three digits then only the first three digits are kept. If the _name_ list is shorter than three digits then the _name_ list is padded with '0' until it is three digits long. :param name: The name list :return: A list that is only 3 digits long. """ if not name: return ['0', '0', '0'] if len(name) > 3: name = name[:3] elif len(name) < 3: while len(name) < 3: name.append('0') return name
if __name__ == '__main__': command_line()