| Conditions | 51 |
| Total Lines | 195 |
| Code Lines | 132 |
| Lines | 0 |
| Ratio | 0 % |
| 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.fingerprint.synoname.synoname_toolcode() 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 -*- |
||
| 199 | def synoname_toolcode(lname, fname='', qual='', normalize=0): |
||
| 200 | """Build the Synoname toolcode. |
||
| 201 | |||
| 202 | Cf. :cite:`Getty:1991,Gross:1991`. |
||
| 203 | |||
| 204 | :param str lname: last name |
||
| 205 | :param str fname: first name (can be blank) |
||
| 206 | :param str qual: qualifier |
||
| 207 | :param int normalize: normalization mode (0, 1, or 2) |
||
| 208 | :returns: the transformed last and first names and the synoname toolcode |
||
| 209 | :rtype: tuple |
||
| 210 | |||
| 211 | >>> synoname_toolcode('hat') |
||
| 212 | ('hat', '', '0000000003$$h') |
||
| 213 | >>> synoname_toolcode('niall') |
||
| 214 | ('niall', '', '0000000005$$n') |
||
| 215 | >>> synoname_toolcode('colin') |
||
| 216 | ('colin', '', '0000000005$$c') |
||
| 217 | >>> synoname_toolcode('atcg') |
||
| 218 | ('atcg', '', '0000000004$$a') |
||
| 219 | >>> synoname_toolcode('entreatment') |
||
| 220 | ('entreatment', '', '0000000011$$e') |
||
| 221 | |||
| 222 | >>> synoname_toolcode('Ste.-Marie', 'Count John II', normalize=2) |
||
| 223 | ('ste.-marie ii', 'count john', '0200491310$015b049a127c$smcji') |
||
| 224 | >>> synoname_toolcode('Michelangelo IV', '', 'Workshop of') |
||
| 225 | ('michelangelo iv', '', '3000550015$055b$mi') |
||
| 226 | """ |
||
| 227 | method_dict = {'end': 1, 'middle': 2, 'beginning': 4, |
||
| 228 | 'beginning_no_space': 8} |
||
| 229 | |||
| 230 | lname = lname.lower() |
||
| 231 | fname = fname.lower() |
||
| 232 | qual = qual.lower() |
||
| 233 | |||
| 234 | # Start with the basic code |
||
| 235 | toolcode = ['0', '0', '0', '000', '00', '00', '$', '', '$', ''] |
||
| 236 | |||
| 237 | full_name = ' '.join((lname, fname)) |
||
| 238 | |||
| 239 | # Fill field 0 (qualifier) |
||
| 240 | qual_3 = {'adaptation after', 'after', 'assistant of', 'assistants of', |
||
| 241 | 'circle of', 'follower of', 'imitator of', 'in the style of', |
||
| 242 | 'manner of', 'pupil of', 'school of', 'studio of', |
||
| 243 | 'style of', 'workshop of'} |
||
| 244 | qual_2 = {'copy after', 'copy after?', 'copy of'} |
||
| 245 | qual_1 = {'ascribed to', 'attributed to or copy after', |
||
| 246 | 'attributed to', 'possibly'} |
||
| 247 | |||
| 248 | if qual in qual_3: |
||
| 249 | toolcode[0] = '3' |
||
| 250 | elif qual in qual_2: |
||
| 251 | toolcode[0] = '2' |
||
| 252 | elif qual in qual_1: |
||
| 253 | toolcode[0] = '1' |
||
| 254 | |||
| 255 | # Fill field 1 (punctuation) |
||
| 256 | if '.' in full_name: |
||
| 257 | toolcode[1] = '2' |
||
| 258 | else: |
||
| 259 | for punct in ',-/:;"&\'()!{|}?$%*+<=>[\\]^_`~': |
||
| 260 | if punct in full_name: |
||
| 261 | toolcode[1] = '1' |
||
| 262 | break |
||
| 263 | |||
| 264 | # Fill field 2 (generation) |
||
| 265 | gen_1 = ('the elder', ' sr.', ' sr', 'senior', 'der altere', 'il vecchio', |
||
| 266 | "l'aine", 'p.re', 'padre', 'seniore', 'vecchia', 'vecchio') |
||
| 267 | gen_2 = (' jr.', ' jr', 'der jungere', 'il giovane', 'giovane', 'juniore', |
||
| 268 | 'junior', 'le jeune', 'the younger') |
||
| 269 | |||
| 270 | elderyounger = '' # save elder/younger for possible movement later |
||
| 271 | for gen in gen_1: |
||
| 272 | if gen in full_name: |
||
| 273 | toolcode[2] = '1' |
||
| 274 | elderyounger = gen |
||
| 275 | break |
||
| 276 | else: |
||
| 277 | for gen in gen_2: |
||
| 278 | if gen in full_name: |
||
| 279 | toolcode[2] = '2' |
||
| 280 | elderyounger = gen |
||
| 281 | break |
||
| 282 | |||
| 283 | # do comma flip |
||
| 284 | if normalize: |
||
| 285 | comma = lname.find(',') |
||
| 286 | if comma != -1: |
||
| 287 | lname_end = lname[comma + 1:] |
||
| 288 | while lname_end[0] in {' ', ','}: |
||
| 289 | lname_end = lname_end[1:] |
||
| 290 | fname = lname_end + ' ' + fname |
||
| 291 | lname = lname[:comma].strip() |
||
| 292 | |||
| 293 | # do elder/younger move |
||
| 294 | if normalize == 2 and elderyounger: |
||
| 295 | elderyounger_loc = fname.find(elderyounger) |
||
| 296 | if elderyounger_loc != -1: |
||
| 297 | lname = ' '.join((lname, elderyounger.strip())) |
||
| 298 | fname = ' '.join((fname[:elderyounger_loc].strip(), |
||
| 299 | fname[elderyounger_loc + |
||
| 300 | len(elderyounger):])).strip() |
||
| 301 | |||
| 302 | toolcode[4] = '{:02d}'.format(len(fname)) |
||
| 303 | toolcode[5] = '{:02d}'.format(len(lname)) |
||
| 304 | |||
| 305 | # strip punctuation |
||
| 306 | for char in ',/:;"&()!{|}?$%*+<=>[\\]^_`~': |
||
| 307 | full_name = full_name.replace(char, '') |
||
| 308 | for pos, char in enumerate(full_name): |
||
| 309 | if char == '-' and full_name[pos - 1:pos + 2] != 'b-g': |
||
| 310 | full_name = full_name[:pos] + ' ' + full_name[pos + 1:] |
||
| 311 | |||
| 312 | # Fill field 9 (search range) |
||
| 313 | for letter in [_[0] for _ in full_name.split()]: |
||
| 314 | if letter not in toolcode[9]: |
||
| 315 | toolcode[9] += letter |
||
| 316 | if len(toolcode[9]) == 15: |
||
| 317 | break |
||
| 318 | |||
| 319 | def roman_check(numeral, fname, lname): |
||
| 320 | """Move Roman numerals from first name to last.""" |
||
| 321 | loc = fname.find(numeral) |
||
| 322 | if fname and (loc != -1 and |
||
| 323 | (len(fname[loc:]) == len(numeral)) or |
||
| 324 | fname[loc+len(numeral)] in {' ', ','}): |
||
| 325 | lname = ' '.join((lname, numeral)) |
||
| 326 | fname = ' '.join((fname[:loc].strip(), |
||
| 327 | fname[loc + len(numeral):].lstrip(' ,'))) |
||
| 328 | return fname.strip(), lname.strip() |
||
| 329 | |||
| 330 | # Fill fields 7 (specials) and 3 (roman numerals) |
||
| 331 | for num, special in enumerate(_synoname_special_table): |
||
| 332 | roman, match, extra, method = special |
||
| 333 | if method & method_dict['end']: |
||
| 334 | match_context = ' ' + match |
||
| 335 | loc = full_name.find(match_context) |
||
| 336 | if ((len(full_name) > len(match_context)) and |
||
| 337 | (loc == len(full_name) - len(match_context))): |
||
| 338 | if roman: |
||
| 339 | if not any(abbr in fname for abbr in ('i.', 'v.', 'x.')): |
||
| 340 | full_name = full_name[:loc] |
||
| 341 | toolcode[7] += '{:03d}'.format(num) + 'a' |
||
| 342 | if toolcode[3] == '000': |
||
| 343 | toolcode[3] = '{:03d}'.format(num) |
||
| 344 | if normalize == 2: |
||
| 345 | fname, lname = roman_check(match, fname, lname) |
||
| 346 | else: |
||
| 347 | full_name = full_name[:loc] |
||
| 348 | toolcode[7] += '{:03d}'.format(num) + 'a' |
||
| 349 | if method & method_dict['middle']: |
||
| 350 | match_context = ' ' + match + ' ' |
||
| 351 | loc = 0 |
||
| 352 | while loc != -1: |
||
| 353 | loc = full_name.find(match_context, loc+1) |
||
| 354 | if loc > 0: |
||
| 355 | if roman: |
||
| 356 | if not any(abbr in fname for abbr in |
||
| 357 | ('i.', 'v.', 'x.')): |
||
| 358 | full_name = (full_name[:loc] + |
||
| 359 | full_name[loc + len(match) + 1:]) |
||
| 360 | toolcode[7] += '{:03d}'.format(num) + 'b' |
||
| 361 | if toolcode[3] == '000': |
||
| 362 | toolcode[3] = '{:03d}'.format(num) |
||
| 363 | if normalize == 2: |
||
| 364 | fname, lname = roman_check(match, fname, lname) |
||
| 365 | else: |
||
| 366 | full_name = (full_name[:loc] + |
||
| 367 | full_name[loc + len(match) + 1:]) |
||
| 368 | toolcode[7] += '{:03d}'.format(num) + 'b' |
||
| 369 | if method & method_dict['beginning']: |
||
| 370 | match_context = match + ' ' |
||
| 371 | loc = full_name.find(match_context) |
||
| 372 | if loc == 0: |
||
| 373 | full_name = full_name[len(match) + 1:] |
||
| 374 | toolcode[7] += '{:03d}'.format(num) + 'c' |
||
| 375 | if method & method_dict['beginning_no_space']: |
||
| 376 | loc = full_name.find(match) |
||
| 377 | if loc == 0: |
||
| 378 | toolcode[7] += '{:03d}'.format(num) + 'd' |
||
| 379 | if full_name[:len(match)] not in toolcode[9]: |
||
| 380 | toolcode[9] += full_name[:len(match)] |
||
| 381 | |||
| 382 | if extra: |
||
| 383 | loc = full_name.find(extra) |
||
| 384 | if loc != -1: |
||
| 385 | toolcode[7] += '{:03d}'.format(num) + 'X' |
||
| 386 | # Since extras are unique, we only look for each of them |
||
| 387 | # once, and they include otherwise impossible characters for |
||
| 388 | # this field, it's not possible for the following line to have |
||
| 389 | # ever been false. |
||
| 390 | # if full_name[loc:loc+len(extra)] not in toolcode[9]: |
||
| 391 | toolcode[9] += full_name[loc:loc+len(match)] |
||
| 392 | |||
| 393 | return lname, fname, ''.join(toolcode) |
||
| 394 | |||
| 399 |
This check looks for invalid names for a range of different identifiers.
You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.
If your project includes a Pylint configuration file, the settings contained in that file take precedence.
To find out more about Pylint, please refer to their site.