Conditions | 33 |
Total Lines | 118 |
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 | Parameters |
||
51 | ---------- |
||
52 | word : str |
||
53 | The word to transform |
||
54 | max_length : int |
||
55 | The length of the code returned (defaults to 4) |
||
56 | zero_pad : bool |
||
57 | Pad the end of the return value with 0s to achieve a max_length |
||
58 | string |
||
59 | |||
60 | Returns |
||
61 | ------- |
||
62 | str |
||
63 | The Phonex value |
||
64 | |||
65 | Examples |
||
66 | -------- |
||
67 | >>> pe = Phonex() |
||
68 | >>> pe.encode('Christopher') |
||
69 | 'C623' |
||
70 | >>> pe.encode('Niall') |
||
71 | 'N400' |
||
72 | >>> pe.encode('Schmidt') |
||
73 | 'S253' |
||
74 | >>> pe.encode('Smith') |
||
75 | 'S530' |
||
76 | |||
77 | """ |
||
78 | 1 | name = unicode_normalize('NFKD', text_type(word.upper())) |
|
79 | 1 | name = name.replace('ß', 'SS') |
|
80 | |||
81 | # Clamp max_length to [4, 64] |
||
82 | 1 | if max_length != -1: |
|
83 | 1 | max_length = min(max(4, max_length), 64) |
|
84 | else: |
||
85 | 1 | max_length = 64 |
|
86 | |||
87 | 1 | name_code = last = '' |
|
88 | |||
89 | # Deletions effected by replacing with next letter which |
||
90 | # will be ignored due to duplicate handling of Soundex code. |
||
91 | # This is faster than 'moving' all subsequent letters. |
||
92 | |||
93 | # Remove any trailing Ss |
||
94 | 1 | while name[-1:] == 'S': |
|
95 | 1 | name = name[:-1] |
|
96 | |||
97 | # Phonetic equivalents of first 2 characters |
||
98 | # Works since duplicate letters are ignored |
||
99 | 1 | if name[:2] == 'KN': |
|
100 | 1 | name = 'N' + name[2:] # KN.. == N.. |
|
101 | 1 | elif name[:2] == 'PH': |
|
102 | 1 | name = 'F' + name[2:] # PH.. == F.. (H ignored anyway) |
|
103 | 1 | elif name[:2] == 'WR': |
|
104 | 1 | name = 'R' + name[2:] # WR.. == R.. |
|
105 | |||
106 | 1 | if name: |
|
107 | # Special case, ignore H first letter (subsequent Hs ignored |
||
108 | # anyway) |
||
109 | # Works since duplicate letters are ignored |
||
110 | 1 | if name[0] == 'H': |
|
111 | 1 | name = name[1:] |
|
112 | |||
113 | 1 | if name: |
|
114 | # Phonetic equivalents of first character |
||
115 | 1 | if name[0] in self._uc_vy_set: |
|
116 | 1 | name = 'A' + name[1:] |
|
117 | 1 | elif name[0] in {'B', 'P'}: |
|
118 | 1 | name = 'B' + name[1:] |
|
119 | 1 | elif name[0] in {'V', 'F'}: |
|
120 | 1 | name = 'F' + name[1:] |
|
121 | 1 | elif name[0] in {'C', 'K', 'Q'}: |
|
122 | 1 | name = 'C' + name[1:] |
|
123 | 1 | elif name[0] in {'G', 'J'}: |
|
124 | 1 | name = 'G' + name[1:] |
|
125 | 1 | elif name[0] in {'S', 'Z'}: |
|
126 | 1 | name = 'S' + name[1:] |
|
127 | |||
128 | 1 | name_code = last = name[0] |
|
129 | |||
130 | # Modified Soundex code |
||
131 | 1 | for i in range(1, len(name)): |
|
132 | 1 | code = '0' |
|
133 | 1 | if name[i] in {'B', 'F', 'P', 'V'}: |
|
134 | 1 | code = '1' |
|
135 | 1 | elif name[i] in {'C', 'G', 'J', 'K', 'Q', 'S', 'X', 'Z'}: |
|
136 | 1 | code = '2' |
|
137 | 1 | elif name[i] in {'D', 'T'}: |
|
138 | 1 | if name[i + 1 : i + 2] != 'C': |
|
139 | 1 | code = '3' |
|
140 | 1 | elif name[i] == 'L': |
|
141 | 1 | if name[i + 1 : i + 2] in self._uc_vy_set or i + 1 == len( |
|
142 | name |
||
143 | ): |
||
144 | 1 | code = '4' |
|
145 | 1 | elif name[i] in {'M', 'N'}: |
|
146 | 1 | if name[i + 1 : i + 2] in {'D', 'G'}: |
|
147 | 1 | name = name[: i + 1] + name[i] + name[i + 2 :] |
|
148 | 1 | code = '5' |
|
149 | 1 | elif name[i] == 'R': |
|
150 | 1 | if name[i + 1 : i + 2] in self._uc_vy_set or i + 1 == len( |
|
151 | name |
||
152 | ): |
||
153 | 1 | code = '6' |
|
154 | |||
155 | 1 | if code != last and code != '0' and i != 0: |
|
156 | 1 | name_code += code |
|
157 | |||
158 | 1 | last = name_code[-1] |
|
159 | |||
160 | 1 | if zero_pad: |
|
161 | 1 | name_code += '0' * max_length |
|
162 | 1 | if not name_code: |
|
163 | 1 | name_code = '0' |
|
164 | 1 | return name_code[:max_length] |
|
165 | |||
205 |