timeit

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

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

Решение на Статичен анализ на python код от Ивелина Христова

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

Към профила на Ивелина Христова

Резултати

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

Код

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
import ast

#Split code by \n
# -> check all lines if they are longer that the allowed and display error
# -> -> check if trimmed line is shorter than not trimmed. If true and if whitespacing is disabled display error


#Go trough all class definitions
# -> Go trough all method definitions
# -> -> Count methods and display errors if a lot
# -> -> -> Check the count of the arguments;
# -> -> -> -> split functions body to count the lined - if too much - display error.

ERRORS = {
  'too_long_line': 'line too long (%d > %d)',
  'semicolon': 'multiple expressions on the same line',
  'deep_nesting': 'nesting too deep (%d > %d)',
  'wrong_indentation': 'indentation is %d instead of %d',
  'too_many_methods': 'too many methods in class(%d > %d)',
  'too_many_arguments': 'too many arguments(%d > %d)',
  'trailing_whitespace': 'trailing whitespace',
  'too_many_lines':  'method with too many lines (%d > %d)',
}

class ClassVisitor(ast.NodeVisitor):
    def visit_ClassDef(self, node):
        return [child for child in node.body 
          if isinstance(child, ast.FunctionDef)]

def critic(code, **rules):
    errors = {}
    line_length = rules['line_length']
    forbid_trailing_whitespace = rules['forbid_trailing_whitespace']
    print(line_length)
    lines = [s for s in code.splitlines()]
    lines_long = {index:lines[index] for index in range(len(lines)) 
    if len(lines[index]) > line_length}
    if forbid_trailing_whitespace:
      lines_trailing_whitespace = {index:lines[index] 
      for index in range(len(lines)) 
      if len(lines[index]) > len(lines[index].rstrip()) and len(lines[index].strip()) > 0}

    for line, text in lines_long.items():
      errors.setdefault(line,[]).append(ERRORS['too_long_line'] 
        % (len(text), line_length))

    for line, text in lines_trailing_whitespace.items():
      errors.setdefault(line,[]).append(ERRORS['trailing_whitespace'])

    node = ast.parse(code)
    ClassVisitor().visit(node)

    return errors

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

EEEEEEEEEEE
======================================================================
ERROR: 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
KeyError: 'line_length'

======================================================================
ERROR: test_forbid_trailing_whitespace (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
KeyError: 'line_length'

======================================================================
ERROR: test_indentation (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
KeyError: 'line_length'

======================================================================
ERROR: test_line_too_long (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
KeyError: 'line_length'

======================================================================
ERROR: test_long_line_with_several_statements (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
KeyError: 'line_length'

======================================================================
ERROR: test_max_lines_per_function (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
KeyError: 'line_length'

======================================================================
ERROR: test_multiple_issues_all_over_the_place (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
KeyError: 'line_length'

======================================================================
ERROR: test_no_issues (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
KeyError: 'line_length'

======================================================================
ERROR: test_too_deep_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
KeyError: 'line_length'

======================================================================
ERROR: test_too_many_arguments (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
KeyError: 'line_length'

======================================================================
ERROR: test_two_statements_on_one_line (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
KeyError: 'line_length'

----------------------------------------------------------------------
Ran 11 tests in 0.084s

FAILED (errors=11)

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

Ивелина обнови решението на 18.05.2016 06:56 (преди над 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
import ast

#Split code by \n
# -> check all lines if they are longer that the allowed and display error
# -> -> check if trimmed line is shorter than not trimmed. If true and if whitespacing is disabled display error


#Go trough all class definitions
# -> Go trough all method definitions
# -> -> Count methods and display errors if a lot
# -> -> -> Check the count of the arguments;
# -> -> -> -> split functions body to count the lined - if too much - display error.

ERRORS = {
  'too_long_line': 'line too long (%d > %d)',
  'semicolon': 'multiple expressions on the same line',
  'deep_nesting': 'nesting too deep (%d > %d)',
  'wrong_indentation': 'indentation is %d instead of %d',
  'too_many_methods': 'too many methods in class(%d > %d)',
  'too_many_arguments': 'too many arguments(%d > %d)',
  'trailing_whitespace': 'trailing whitespace',
  'too_many_lines':  'method with too many lines (%d > %d)',
}

class ClassVisitor(ast.NodeVisitor):
    def visit_ClassDef(self, node):
        return [child for child in node.body 
          if isinstance(child, ast.FunctionDef)]

def critic(code, **rules):
    errors = {}
    line_length = rules['line_length']
    forbid_trailing_whitespace = rules['forbid_trailing_whitespace']
    print(line_length)
    lines = [s for s in code.splitlines()]
    lines_long = {index:lines[index] for index in range(len(lines)) 
    if len(lines[index]) > line_length}
    if forbid_trailing_whitespace:
      lines_trailing_whitespace = {index:lines[index] 
      for index in range(len(lines)) 
      if len(lines[index]) > len(lines[index].rstrip()) and len(lines[index].strip()) > 0}

    for line, text in lines_long.items():
      errors.setdefault(line,[]).append(ERRORS['too_long_line'] 
        % (len(text), line_length))

    for line, text in lines_trailing_whitespace.items():
      errors.setdefault(line,[]).append(ERRORS['trailing_whitespace'])

    node = ast.parse(code)
    ClassVisitor().visit(node)

    return errors