Passed
Push — master ( c506d9...10bb29 )
by Ken M.
01:43
created

unix_match   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 83
Duplicated Lines 15.66 %

Importance

Changes 0
Metric Value
eloc 64
dl 13
loc 83
rs 10
c 0
b 0
f 0
wmc 20

7 Functions

Rating   Name   Duplication   Size   Complexity  
A find_matching_left_bracket() 0 4 3
A translate_non_pattern() 0 2 1
A find_non_brackets() 0 12 5
A translate_pattern() 0 7 4
A unix_match() 0 8 1
A find_brackets() 0 7 3
A translate_brackets() 0 11 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
from itertools import pairwise
2
from re import search, match
3
from typing import Tuple
4
5
6
def translate_brackets(pattern: str, pair: Tuple[int, int]) -> Tuple[int, str]:
7
    if pair[1] - pair[0] == 1:
8
        return pair[0], ''
9
    else:
10
        sub_pattern = pattern[pair[0]:pair[1] + 1]
11
        if sub_pattern.startswith('[!'):
12
            return pair[0], '[^' + pattern[pair[0] + 1:pair[1]].replace('.', r'\.').replace('*', r'\*').replace('?',
13
                                                                                                                r'\?') + ']'
14
        else:
15
            return pair[0], '[' + pattern[pair[0] + 1:pair[1]].replace('.', r'\.').replace('*', r'\*').replace('?',
16
                                                                                                               r'\?') + ']'
17
18
19
def translate_non_pattern(pattern: str, pair: Tuple[int, int]) -> Tuple[int, str]:
20
    return pair[0], pattern[pair[0]:pair[1]].replace('.', '\.').replace('*', '.*').replace('?', '.').replace('[', '\[').replace(']', '\]')
21
22
23
def find_matching_left_bracket(string: str, right_bracket_index: int, stop_index: int) -> (int, int):
24
    for i in range(right_bracket_index, stop_index - 1, -1):
25
        if string[i] == '[':
26
            return i, right_bracket_index
27
28
29
def find_non_brackets(pattern: str, brackets: Tuple[Tuple[int, int]]) -> Tuple[Tuple[int, int]]:
30
    non_brackets = [(0, len(pattern))] * (len(brackets) + 1)
31
    if len(brackets) == 0:
32
        return non_brackets
33
    for i in range(len(non_brackets)):
34
        if i == 0:
35
            non_brackets[i] = (non_brackets[i][0], brackets[i][0])
36
        elif i == len(non_brackets) - 1:
37
            non_brackets[i] = (brackets[i - 1][1]+1, non_brackets[i][1])
38
        else:
39
            non_brackets[i] = (brackets[i - 1][1] + 1, brackets[i][0])
40
    return tuple([i for i in non_brackets if i[0] < i[1]])
41
42
43
def find_brackets(pattern: str) -> Tuple[Tuple[int, int]]:
44
    right_brackets = [k for k, v in enumerate(pattern) if v == ']']
45
    brackets_index_pairs = tuple(filter(lambda x: x, map(lambda x: find_matching_left_bracket(pattern, x[1], x[0]),
46
                                                         pairwise([0] + right_brackets))))
47
    print(right_brackets)
48
    print(brackets_index_pairs)
49
    return brackets_index_pairs
50
51
52
def translate_pattern(pattern: str) -> str:
53
    brackets_index_pairs = find_brackets(pattern)
54
    brackets = list(map(lambda x: translate_brackets(pattern, x), brackets_index_pairs))
55
    non_brackets_index_pair = find_non_brackets(pattern, brackets_index_pairs)
56
    print(non_brackets_index_pair)
57
    non_brackets = list(map(lambda x: translate_non_pattern(pattern, x), non_brackets_index_pair))
58
    return ''.join(map(lambda x: x[1], sorted(non_brackets + brackets)))
59
60
61
def unix_match(filename: str, pattern: str) -> bool:
62
    translated_pattern = translate_pattern(pattern)
63
    print(filename)
64
    print(pattern)
65
    print(translated_pattern)
66
    a = match(translated_pattern, filename)
67
    print(a)
68
    return '[]' not in pattern and bool(search(translated_pattern, filename))
69
70 View Code Duplication
if __name__ == '__main__':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
71
    print("Example:")
72
    print(unix_match('somefile.txt', '*'))
73
74
    # These "asserts" are used for self-checking and not for an auto-testing
75
    assert unix_match('somefile.txt', '*') == True
76
    assert unix_match('other.exe', '*') == True
77
    assert unix_match('my.exe', '*.txt') == False
78
    assert unix_match('log1.txt', 'log?.txt') == True
79
    assert unix_match('log1.txt', 'log[1234567890].txt') == True
80
    assert unix_match('log12.txt', 'log?.txt') == False
81
    assert unix_match('log12.txt', 'log??.txt') == True
82
    print("Coding complete? Click 'Check' to earn cool rewards!")
83