timeit

Програмиране с Python

Курс във Факултета по Математика и Информатика към СУ

Решение на Статичен анализ на python код от Симеон Ролев

Обратно към всички решения

Към профила на Симеон Ролев

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 10 успешни тест(а)
  • 1 неуспешни тест(а)

Код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import ast


def critic(code, line_length=79, forbid_semicolons=True, max_nesting=None,
           indentation_size=4, methods_per_class=None, max_arity=None,
           forbid_trailing_whitespace=True, max_lines_per_function=None):
    result = {}
    rows = code.splitlines()
    tree = ast.parse(code)

    # Line_length check
    for index in range(0, len(rows)):
        if len(rows[index]) > line_length:
            if index + 1 not in result:
                result[index + 1] = set()
            result[index + 1].add('line too long ({} > {})'.format(
                len(rows[index]), line_length))

    # Semicolon check
    if forbid_semicolons:
        for index in range(0, len(rows)):
            if ';' in rows[index]:
                if index + 1 not in result:
                    result[index + 1] = set()
                result[index + 1].add('multiple expressions on the same line')

    # max_nesting check
    for index in range(0, len(rows)):
        row_spaces = len(rows[index]) - len(rows[index].lstrip())
        indent_count = row_spaces / indentation_size
        if max_nesting and indent_count > max_nesting:
            if index + 1 not in result:
                result[index + 1] = set()
            result[index + 1].add(
                'nesting too deep ({} > {})'.format(
                    indentation_size, max_nesting))

    # indentation size check
    for index in range(0, len(rows) - 1):
        row_spaces = len(rows[index]) - len(rows[index].lstrip())
        next_row_spaces = len(rows[index+1]) - len(rows[index+1].lstrip())
        if next_row_spaces % indentation_size != 0:
            if index + 2 not in result:
                result[index + 2] = set()
            result[index + 2].add(
                'indentation is {} instead of {}'.format(
                    next_row_spaces, row_spaces + 4))

    # too many methods per class check
    for node in ast.walk(tree):
        if isinstance(node, ast.ClassDef):
            methods_count = 0
            for elem in node.body:
                if isinstance(elem, ast.FunctionDef):
                    methods_count = methods_count + 1
            if methods_per_class and methods_count > methods_per_class:
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'too many methods in class({} > {})'.format(
                        methods_count, methods_per_class))

    # max_arity check
    for node in ast.walk(tree):
        if isinstance(node, ast.FunctionDef):
            if(max_arity and len(node.args.args) > max_arity):
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'too many arguments({} > {})'.format(
                        len(node.args.args), max_arity))

    # trailing whitespace
    if forbid_trailing_whitespace:
        for index in range(0, len(rows)):
            if rows[index].endswith(" "):
                if index + 1 not in result:
                    result[index + 1] = set()
                result[index + 1].add('trailing whitespace')

    # max_logical lines per function
    for node in ast.walk(tree):
        if isinstance(node, ast.FunctionDef):
            logic_lines = 0
            for elem in node.body:
                logic_lines += 1
            if max_lines_per_function and logic_lines > max_lines_per_function:
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'method with too many lines ({} > {})'.format(
                        logic_lines, max_lines_per_function))

    return result

Лог от изпълнението

F..........
======================================================================
FAIL: test_dict_nesting (test.TestCritic)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/rails/pyfmi-2016/releases/20160307095126/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 2 != 0

----------------------------------------------------------------------
Ran 11 tests in 0.095s

FAILED (failures=1)

История (2 версии и 0 коментара)

Симеон обнови решението на 18.05.2016 16:24 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import ast


def critic(code, line_length=79, forbid_semicolons=True, max_nesting=None,
           indentation_size=4, methods_per_class=None, max_arity=None,
           forbid_trailing_whitespace=True, max_lines_per_function=2):
    result = {}
    rows = code.splitlines()
    tree = ast.parse(code)

    # Line_length check
    for index in range(0, len(rows)):
        if len(rows[index]) > line_length:
            if index + 1 not in result:
                result[index + 1] = set()
            result[index + 1].add('line too long ({} > {})'.format(
                len(rows[index]), line_length))

    # Semicolon check
    if forbid_semicolons:
        for index in range(0, len(rows)):
            if ';' in rows[index]:
                if index + 1 not in result:
                    result[index + 1] = set()
                result[index + 1].add('multiple expressions on the same line')

    # indentation size check

    for index in range(0, len(rows) - 1):
        row_spaces = len(rows[index]) - len(rows[index].lstrip())
        next_row_spaces = len(rows[index+1]) - len(rows[index+1].lstrip())
        if next_row_spaces % indentation_size != 0:
            if index + 2 not in result:
                result[index + 2] = set()
            result[index + 2].add(
                'indentation is {} instead of {}'.format(
                    next_row_spaces, row_spaces + 4))

    # too many methods per class check
    for node in ast.walk(tree):
        if isinstance(node, ast.ClassDef):
            methods_count = 0
            for elem in node.body:
                if isinstance(elem, ast.FunctionDef):
                    methods_count = methods_count + 1
            if methods_per_class and methods_count > methods_per_class:
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'too many methods in class({} > {})'.format(
                        methods_count, methods_per_class))

    # max_arity check
    for node in ast.walk(tree):
        if isinstance(node, ast.FunctionDef):
            if(max_arity and len(node.args.args) > max_arity):
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'too many arguments({} > {})'.format(
                        len(node.args.args), max_arity))

    # trailing whitespace
    if forbid_trailing_whitespace:
        for index in range(0, len(rows)):
            if rows[index].endswith(" "):
                if index + 1 not in result:
                    result[index + 1] = set()
                result[index + 1].add('trailing whitespace')

    # max_logical lines per function
    for node in ast.walk(tree):
        if isinstance(node, ast.FunctionDef):
            logic_lines = 0
            for elem in node.body:
                logic_lines += 1
            print(node.name, logic_lines)
            if max_lines_per_function and logic_lines > max_lines_per_function:
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'method with too many lines ({} > {})'.format(
                        logic_lines, max_lines_per_function))

    return result

Симеон обнови решението на 18.05.2016 16:36 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import ast


def critic(code, line_length=79, forbid_semicolons=True, max_nesting=None,
           indentation_size=4, methods_per_class=None, max_arity=None,
           forbid_trailing_whitespace=True, max_lines_per_function=None):
    result = {}
    rows = code.splitlines()
    tree = ast.parse(code)

    # Line_length check
    for index in range(0, len(rows)):
        if len(rows[index]) > line_length:
            if index + 1 not in result:
                result[index + 1] = set()
            result[index + 1].add('line too long ({} > {})'.format(
                len(rows[index]), line_length))

    # Semicolon check
    if forbid_semicolons:
        for index in range(0, len(rows)):
            if ';' in rows[index]:
                if index + 1 not in result:
                    result[index + 1] = set()
                result[index + 1].add('multiple expressions on the same line')

    # max_nesting check
    for index in range(0, len(rows)):
        row_spaces = len(rows[index]) - len(rows[index].lstrip())
        indent_count = row_spaces / indentation_size
        if max_nesting and indent_count > max_nesting:
            if index + 1 not in result:
                result[index + 1] = set()
            result[index + 1].add(
                'nesting too deep ({} > {})'.format(
                    indentation_size, max_nesting))

    # indentation size check
    for index in range(0, len(rows) - 1):
        row_spaces = len(rows[index]) - len(rows[index].lstrip())
        next_row_spaces = len(rows[index+1]) - len(rows[index+1].lstrip())
        if next_row_spaces % indentation_size != 0:
            if index + 2 not in result:
                result[index + 2] = set()
            result[index + 2].add(
                'indentation is {} instead of {}'.format(
                    next_row_spaces, row_spaces + 4))

    # too many methods per class check
    for node in ast.walk(tree):
        if isinstance(node, ast.ClassDef):
            methods_count = 0
            for elem in node.body:
                if isinstance(elem, ast.FunctionDef):
                    methods_count = methods_count + 1
            if methods_per_class and methods_count > methods_per_class:
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'too many methods in class({} > {})'.format(
                        methods_count, methods_per_class))

    # max_arity check
    for node in ast.walk(tree):
        if isinstance(node, ast.FunctionDef):
            if(max_arity and len(node.args.args) > max_arity):
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'too many arguments({} > {})'.format(
                        len(node.args.args), max_arity))

    # trailing whitespace
    if forbid_trailing_whitespace:
        for index in range(0, len(rows)):
            if rows[index].endswith(" "):
                if index + 1 not in result:
                    result[index + 1] = set()
                result[index + 1].add('trailing whitespace')

    # max_logical lines per function
    for node in ast.walk(tree):
        if isinstance(node, ast.FunctionDef):
            logic_lines = 0
            for elem in node.body:
                logic_lines += 1
            if max_lines_per_function and logic_lines > max_lines_per_function:
                if node.lineno not in result:
                    result[node.lineno] = set()
                result[node.lineno].add(
                    'method with too many lines ({} > {})'.format(
                        logic_lines, max_lines_per_function))

    return result