Conditions | 33 |
Total Lines | 111 |
Code Lines | 61 |
Lines | 0 |
Ratio | 0 % |
Tests | 59 |
CRAP Score | 33 |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like abydos.phonetic._phonex.Phonex.encode() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # -*- coding: utf-8 -*- |
||
47 | 1 | def encode(self, word, max_length=4, zero_pad=True): |
|
48 | """Return the Phonex code for a word. |
||
49 | |||
50 | Args: |
||
51 | word (str): The word to transform |
||
52 | max_length (int): The length of the code returned (defaults to 4) |
||
53 | zero_pad (bool): pad the end of the return value with 0s to achieve |
||
54 | a max_length string |
||
55 | |||
56 | Returns: |
||
57 | str: The Phonex value |
||
58 | |||
59 | Examples: |
||
60 | >>> pe = Phonex() |
||
61 | >>> pe.encode('Christopher') |
||
62 | 'C623' |
||
63 | >>> pe.encode('Niall') |
||
64 | 'N400' |
||
65 | >>> pe.encode('Schmidt') |
||
66 | 'S253' |
||
67 | >>> pe.encode('Smith') |
||
68 | 'S530' |
||
69 | |||
70 | """ |
||
71 | 1 | name = unicode_normalize('NFKD', text_type(word.upper())) |
|
72 | 1 | name = name.replace('ß', 'SS') |
|
73 | |||
74 | # Clamp max_length to [4, 64] |
||
75 | 1 | if max_length != -1: |
|
76 | 1 | max_length = min(max(4, max_length), 64) |
|
77 | else: |
||
78 | 1 | max_length = 64 |
|
79 | |||
80 | 1 | name_code = last = '' |
|
81 | |||
82 | # Deletions effected by replacing with next letter which |
||
83 | # will be ignored due to duplicate handling of Soundex code. |
||
84 | # This is faster than 'moving' all subsequent letters. |
||
85 | |||
86 | # Remove any trailing Ss |
||
87 | 1 | while name[-1:] == 'S': |
|
88 | 1 | name = name[:-1] |
|
89 | |||
90 | # Phonetic equivalents of first 2 characters |
||
91 | # Works since duplicate letters are ignored |
||
92 | 1 | if name[:2] == 'KN': |
|
93 | 1 | name = 'N' + name[2:] # KN.. == N.. |
|
94 | 1 | elif name[:2] == 'PH': |
|
95 | 1 | name = 'F' + name[2:] # PH.. == F.. (H ignored anyway) |
|
96 | 1 | elif name[:2] == 'WR': |
|
97 | 1 | name = 'R' + name[2:] # WR.. == R.. |
|
98 | |||
99 | 1 | if name: |
|
100 | # Special case, ignore H first letter (subsequent Hs ignored |
||
101 | # anyway) |
||
102 | # Works since duplicate letters are ignored |
||
103 | 1 | if name[0] == 'H': |
|
104 | 1 | name = name[1:] |
|
105 | |||
106 | 1 | if name: |
|
107 | # Phonetic equivalents of first character |
||
108 | 1 | if name[0] in self._uc_vy_set: |
|
109 | 1 | name = 'A' + name[1:] |
|
110 | 1 | elif name[0] in {'B', 'P'}: |
|
111 | 1 | name = 'B' + name[1:] |
|
112 | 1 | elif name[0] in {'V', 'F'}: |
|
113 | 1 | name = 'F' + name[1:] |
|
114 | 1 | elif name[0] in {'C', 'K', 'Q'}: |
|
115 | 1 | name = 'C' + name[1:] |
|
116 | 1 | elif name[0] in {'G', 'J'}: |
|
117 | 1 | name = 'G' + name[1:] |
|
118 | 1 | elif name[0] in {'S', 'Z'}: |
|
119 | 1 | name = 'S' + name[1:] |
|
120 | |||
121 | 1 | name_code = last = name[0] |
|
122 | |||
123 | # Modified Soundex code |
||
124 | 1 | for i in range(1, len(name)): |
|
125 | 1 | code = '0' |
|
126 | 1 | if name[i] in {'B', 'F', 'P', 'V'}: |
|
127 | 1 | code = '1' |
|
128 | 1 | elif name[i] in {'C', 'G', 'J', 'K', 'Q', 'S', 'X', 'Z'}: |
|
129 | 1 | code = '2' |
|
130 | 1 | elif name[i] in {'D', 'T'}: |
|
131 | 1 | if name[i + 1 : i + 2] != 'C': |
|
132 | 1 | code = '3' |
|
133 | 1 | elif name[i] == 'L': |
|
134 | 1 | if name[i + 1 : i + 2] in self._uc_vy_set or i + 1 == len( |
|
135 | name |
||
136 | ): |
||
137 | 1 | code = '4' |
|
138 | 1 | elif name[i] in {'M', 'N'}: |
|
139 | 1 | if name[i + 1 : i + 2] in {'D', 'G'}: |
|
140 | 1 | name = name[: i + 1] + name[i] + name[i + 2 :] |
|
141 | 1 | code = '5' |
|
142 | 1 | elif name[i] == 'R': |
|
143 | 1 | if name[i + 1 : i + 2] in self._uc_vy_set or i + 1 == len( |
|
144 | name |
||
145 | ): |
||
146 | 1 | code = '6' |
|
147 | |||
148 | 1 | if code != last and code != '0' and i != 0: |
|
149 | 1 | name_code += code |
|
150 | |||
151 | 1 | last = name_code[-1] |
|
152 | |||
153 | 1 | if zero_pad: |
|
154 | 1 | name_code += '0' * max_length |
|
155 | 1 | if not name_code: |
|
156 | 1 | name_code = '0' |
|
157 | 1 | return name_code[:max_length] |
|
158 | |||
192 |