| Conditions | 51 | 
| Total Lines | 223 | 
| Code Lines | 128 | 
| Lines | 0 | 
| Ratio | 0 % | 
| Tests | 110 | 
| CRAP Score | 51 | 
| 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.SynonameToolcode.fingerprint() 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 -*-  | 
            ||
| 270 | 1 | def fingerprint(self, lname, fname='', qual='', normalize=0):  | 
            |
| 271 | """Build the Synoname toolcode.  | 
            ||
| 272 | |||
| 273 | Parameters  | 
            ||
| 274 | ----------  | 
            ||
| 275 | lname : str  | 
            ||
| 276 | Last name  | 
            ||
| 277 | fname : str  | 
            ||
| 278 | First name (can be blank)  | 
            ||
| 279 | qual : str  | 
            ||
| 280 | Qualifier  | 
            ||
| 281 | normalize : int  | 
            ||
| 282 | Normalization mode (0, 1, or 2)  | 
            ||
| 283 | |||
| 284 | Returns  | 
            ||
| 285 | -------  | 
            ||
| 286 | tuple  | 
            ||
| 287 | The transformed names and the synoname toolcode  | 
            ||
| 288 | |||
| 289 | Examples  | 
            ||
| 290 | --------  | 
            ||
| 291 | >>> st = SynonameToolcode()  | 
            ||
| 292 |         >>> st.fingerprint('hat') | 
            ||
| 293 |         ('hat', '', '0000000003$$h') | 
            ||
| 294 |         >>> st.fingerprint('niall') | 
            ||
| 295 |         ('niall', '', '0000000005$$n') | 
            ||
| 296 |         >>> st.fingerprint('colin') | 
            ||
| 297 |         ('colin', '', '0000000005$$c') | 
            ||
| 298 |         >>> st.fingerprint('atcg') | 
            ||
| 299 |         ('atcg', '', '0000000004$$a') | 
            ||
| 300 |         >>> st.fingerprint('entreatment') | 
            ||
| 301 |         ('entreatment', '', '0000000011$$e') | 
            ||
| 302 | |||
| 303 |         >>> st.fingerprint('Ste.-Marie', 'Count John II', normalize=2) | 
            ||
| 304 |         ('ste.-marie ii', 'count john', '0200491310$015b049a127c$smcji') | 
            ||
| 305 |         >>> st.fingerprint('Michelangelo IV', '', 'Workshop of') | 
            ||
| 306 |         ('michelangelo iv', '', '3000550015$055b$mi') | 
            ||
| 307 | |||
| 308 | """  | 
            ||
| 309 | 1 | lname = lname.lower()  | 
            |
| 310 | 1 | fname = fname.lower()  | 
            |
| 311 | 1 | qual = qual.lower()  | 
            |
| 312 | |||
| 313 | # Start with the basic code  | 
            ||
| 314 | 1 | toolcode = ['0', '0', '0', '000', '00', '00', '$', '', '$', '']  | 
            |
| 315 | |||
| 316 | 1 | full_name = ' '.join((lname, fname))  | 
            |
| 317 | |||
| 318 | 1 | if qual in self.qual_3:  | 
            |
| 319 | 1 | toolcode[0] = '3'  | 
            |
| 320 | 1 | elif qual in self.qual_2:  | 
            |
| 321 | 1 | toolcode[0] = '2'  | 
            |
| 322 | 1 | elif qual in self.qual_1:  | 
            |
| 323 | 1 | toolcode[0] = '1'  | 
            |
| 324 | |||
| 325 | # Fill field 1 (punctuation)  | 
            ||
| 326 | 1 | if '.' in full_name:  | 
            |
| 327 | 1 | toolcode[1] = '2'  | 
            |
| 328 | else:  | 
            ||
| 329 | 1 |             for punct in ',-/:;"&\'()!{|}?$%*+<=>[\\]^_`~': | 
            |
| 330 | 1 | if punct in full_name:  | 
            |
| 331 | 1 | toolcode[1] = '1'  | 
            |
| 332 | 1 | break  | 
            |
| 333 | |||
| 334 | 1 | elderyounger = '' # save elder/younger for possible movement later  | 
            |
| 335 | 1 | for gen in self.gen_1:  | 
            |
| 336 | 1 | if gen in full_name:  | 
            |
| 337 | 1 | toolcode[2] = '1'  | 
            |
| 338 | 1 | elderyounger = gen  | 
            |
| 339 | 1 | break  | 
            |
| 340 | else:  | 
            ||
| 341 | 1 | for gen in self.gen_2:  | 
            |
| 342 | 1 | if gen in full_name:  | 
            |
| 343 | 1 | toolcode[2] = '2'  | 
            |
| 344 | 1 | elderyounger = gen  | 
            |
| 345 | 1 | break  | 
            |
| 346 | |||
| 347 | # do comma flip  | 
            ||
| 348 | 1 | if normalize:  | 
            |
| 349 | 1 |             comma = lname.find(',') | 
            |
| 350 | 1 | if comma != -1:  | 
            |
| 351 | 1 | lname_end = lname[comma + 1 :]  | 
            |
| 352 | 1 |                 while lname_end[0] in {' ', ','}: | 
            |
| 353 | 1 | lname_end = lname_end[1:]  | 
            |
| 354 | 1 | fname = lname_end + ' ' + fname  | 
            |
| 355 | 1 | lname = lname[:comma].strip()  | 
            |
| 356 | |||
| 357 | # do elder/younger move  | 
            ||
| 358 | 1 | if normalize == 2 and elderyounger:  | 
            |
| 359 | 1 | elderyounger_loc = fname.find(elderyounger)  | 
            |
| 360 | 1 | if elderyounger_loc != -1:  | 
            |
| 361 | 1 | lname = ' '.join((lname, elderyounger.strip()))  | 
            |
| 362 | 1 | fname = ' '.join(  | 
            |
| 363 | (  | 
            ||
| 364 | fname[:elderyounger_loc].strip(),  | 
            ||
| 365 | fname[elderyounger_loc + len(elderyounger) :],  | 
            ||
| 366 | )  | 
            ||
| 367 | ).strip()  | 
            ||
| 368 | |||
| 369 | 1 |         toolcode[4] = '{:02d}'.format(len(fname)) | 
            |
| 370 | 1 |         toolcode[5] = '{:02d}'.format(len(lname)) | 
            |
| 371 | |||
| 372 | # strip punctuation  | 
            ||
| 373 | 1 |         for char in ',/:;"&()!{|}?$%*+<=>[\\]^_`~': | 
            |
| 374 | 1 | full_name = full_name.replace(char, '')  | 
            |
| 375 | 1 | for pos, char in enumerate(full_name):  | 
            |
| 376 | 1 | if char == '-' and full_name[pos - 1 : pos + 2] != 'b-g':  | 
            |
| 377 | 1 | full_name = full_name[:pos] + ' ' + full_name[pos + 1 :]  | 
            |
| 378 | |||
| 379 | # Fill field 9 (search range)  | 
            ||
| 380 | 1 | for letter in [_[0] for _ in full_name.split()]:  | 
            |
| 381 | 1 | if letter not in toolcode[9]:  | 
            |
| 382 | 1 | toolcode[9] += letter  | 
            |
| 383 | 1 | if len(toolcode[9]) == 15:  | 
            |
| 384 | 1 | break  | 
            |
| 385 | |||
| 386 | 1 | def roman_check(numeral, fname, lname):  | 
            |
| 387 | """Move Roman numerals from first name to last.  | 
            ||
| 388 | |||
| 389 | Parameters  | 
            ||
| 390 | ----------  | 
            ||
| 391 | numeral : str  | 
            ||
| 392 | Roman numeral  | 
            ||
| 393 | fname : str  | 
            ||
| 394 | First name  | 
            ||
| 395 | lname : str  | 
            ||
| 396 | Last name  | 
            ||
| 397 | |||
| 398 | Returns  | 
            ||
| 399 | -------  | 
            ||
| 400 | tuple  | 
            ||
| 401 | First and last names with Roman numeral moved  | 
            ||
| 402 | |||
| 403 | """  | 
            ||
| 404 | 1 | loc = fname.find(numeral)  | 
            |
| 405 | 1 | if fname and (  | 
            |
| 406 | loc != -1  | 
            ||
| 407 | and (len(fname[loc:]) == len(numeral))  | 
            ||
| 408 |                 or fname[loc + len(numeral)] in {' ', ','} | 
            ||
| 409 | ):  | 
            ||
| 410 | 1 | lname = ' '.join((lname, numeral))  | 
            |
| 411 | 1 | fname = ' '.join(  | 
            |
| 412 | (  | 
            ||
| 413 | fname[:loc].strip(),  | 
            ||
| 414 |                         fname[loc + len(numeral) :].lstrip(' ,'), | 
            ||
| 415 | )  | 
            ||
| 416 | )  | 
            ||
| 417 | 1 | return fname.strip(), lname.strip()  | 
            |
| 418 | |||
| 419 | # Fill fields 7 (specials) and 3 (roman numerals)  | 
            ||
| 420 | 1 | for num, special in enumerate(self.synoname_special_table):  | 
            |
| 421 | 1 | roman, match, extra, method = special  | 
            |
| 422 | 1 | if method & self.method_dict['end']:  | 
            |
| 423 | 1 | match_context = ' ' + match  | 
            |
| 424 | 1 | loc = full_name.find(match_context)  | 
            |
| 425 | 1 | if (len(full_name) > len(match_context)) and (  | 
            |
| 426 | loc == len(full_name) - len(match_context)  | 
            ||
| 427 | ):  | 
            ||
| 428 | 1 | if roman:  | 
            |
| 429 | 1 | if not any(  | 
            |
| 430 |                             abbr in fname for abbr in ('i.', 'v.', 'x.') | 
            ||
| 431 | ):  | 
            ||
| 432 | 1 | full_name = full_name[:loc]  | 
            |
| 433 | 1 |                             toolcode[7] += '{:03d}'.format(num) + 'a' | 
            |
| 434 | 1 | if toolcode[3] == '000':  | 
            |
| 435 | 1 |                                 toolcode[3] = '{:03d}'.format(num) | 
            |
| 436 | 1 | if normalize == 2:  | 
            |
| 437 | 1 | fname, lname = roman_check(match, fname, lname)  | 
            |
| 438 | else:  | 
            ||
| 439 | 1 | full_name = full_name[:loc]  | 
            |
| 440 | 1 |                         toolcode[7] += '{:03d}'.format(num) + 'a' | 
            |
| 441 | 1 | if method & self.method_dict['middle']:  | 
            |
| 442 | 1 | match_context = ' ' + match + ' '  | 
            |
| 443 | 1 | loc = 0  | 
            |
| 444 | 1 | while loc != -1:  | 
            |
| 445 | 1 | loc = full_name.find(match_context, loc + 1)  | 
            |
| 446 | 1 | if loc > 0:  | 
            |
| 447 | 1 | if roman:  | 
            |
| 448 | 1 | if not any(  | 
            |
| 449 |                                 abbr in fname for abbr in ('i.', 'v.', 'x.') | 
            ||
| 450 | ):  | 
            ||
| 451 | 1 | full_name = (  | 
            |
| 452 | full_name[:loc]  | 
            ||
| 453 | + full_name[loc + len(match) + 1 :]  | 
            ||
| 454 | )  | 
            ||
| 455 | 1 |                                 toolcode[7] += '{:03d}'.format(num) + 'b' | 
            |
| 456 | 1 | if toolcode[3] == '000':  | 
            |
| 457 | 1 |                                     toolcode[3] = '{:03d}'.format(num) | 
            |
| 458 | 1 | if normalize == 2:  | 
            |
| 459 | 1 | fname, lname = roman_check(  | 
            |
| 460 | match, fname, lname  | 
            ||
| 461 | )  | 
            ||
| 462 | else:  | 
            ||
| 463 | 1 | full_name = (  | 
            |
| 464 | full_name[:loc]  | 
            ||
| 465 | + full_name[loc + len(match) + 1 :]  | 
            ||
| 466 | )  | 
            ||
| 467 | 1 |                             toolcode[7] += '{:03d}'.format(num) + 'b' | 
            |
| 468 | 1 | if method & self.method_dict['beginning']:  | 
            |
| 469 | 1 | match_context = match + ' '  | 
            |
| 470 | 1 | loc = full_name.find(match_context)  | 
            |
| 471 | 1 | if loc == 0:  | 
            |
| 472 | 1 | full_name = full_name[len(match) + 1 :]  | 
            |
| 473 | 1 |                     toolcode[7] += '{:03d}'.format(num) + 'c' | 
            |
| 474 | 1 | if method & self.method_dict['beginning_no_space']:  | 
            |
| 475 | 1 | loc = full_name.find(match)  | 
            |
| 476 | 1 | if loc == 0:  | 
            |
| 477 | 1 |                     toolcode[7] += '{:03d}'.format(num) + 'd' | 
            |
| 478 | 1 | if full_name[: len(match)] not in toolcode[9]:  | 
            |
| 479 | 1 | toolcode[9] += full_name[: len(match)]  | 
            |
| 480 | |||
| 481 | 1 | if extra:  | 
            |
| 482 | 1 | loc = full_name.find(extra)  | 
            |
| 483 | 1 | if loc != -1:  | 
            |
| 484 | 1 |                     toolcode[7] += '{:03d}'.format(num) + 'X' | 
            |
| 485 | # Since extras are unique, we only look for each of them  | 
            ||
| 486 | # once, and they include otherwise impossible characters  | 
            ||
| 487 | # for this field, it's not possible for the following line  | 
            ||
| 488 | # to have ever been false.  | 
            ||
| 489 | # if full_name[loc:loc+len(extra)] not in toolcode[9]:  | 
            ||
| 490 | 1 | toolcode[9] += full_name[loc : loc + len(match)]  | 
            |
| 491 | |||
| 492 | 1 | return lname, fname, ''.join(toolcode)  | 
            |
| 493 | |||
| 542 |