Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolaySimakov committed Jul 1, 2023
2 parents e7ad5fc + b9371af commit 46bfc6e
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 0 deletions.
92 changes: 92 additions & 0 deletions analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import ast
import shutil
from typing import List, Tuple
from pprint import pprint
from enum import Enum


'''
AST analyzer
'''
class Analyzer(ast.NodeVisitor):
def __init__(self) -> None:
self.stats = {
'for': 0,
'import': [],
}

def visit_For(self, node):
for alias in node.names:
self.stats['for'].append(alias.name)
self.generic_visit(node)

def visit_Import(self, node):
for alias in node.names:
self.stats["import"].append(alias.name)
self.generic_visit(node)

def report(self):
pprint(self.stats)


'''
Notation format enum
'''
class NotationFormat(Enum):

BIG_O : str = 'BIG O'
BIG_OMEGA : str = 'BIG Ω (OMEGA)'
BIG_THETA : str = 'BIG Θ (THETA)'

def __str__(self) -> str:
return str(self.value)


'''
Class that contains and represents analysis data
'''
class AnalysisFormatter:

def __init__(
self,
notation_format: NotationFormat,
func_name: str = 'No name',
func_attrs: List[Tuple[str, str]] | None = None,
complexity: str = '1',
memory: str = '1',
) -> None:

self.notation_format = notation_format
self.func_name = func_name
self.func_attrs = func_attrs
self.complexity = complexity
self.memory = memory

def report(self, full=True):

print()

if full:
print('Function name:', self.func_name)

if self.func_attrs:
print('Function attributes:', ', '.join([f'{attr_name}: {attr_type}' for attr_name, attr_type in self.func_attrs]))

terminal_width = shutil.get_terminal_size().columns
indent = max((terminal_width - len(self.notation_format.__str__()) - 2)//2, 0)
print('-' * indent + f' {self.notation_format.__str__()} ' + '-' * indent)

if self.notation_format == NotationFormat.BIG_O:
print('Сomplexity of algorithm: O({})'.format(self.complexity))
print('Memory of algorithm: O({})'.format(self.memory))

if self.notation_format == NotationFormat.BIG_OMEGA:
print('Сomplexity of algorithm: Ω({})'.format(self.complexity))
print('Memory of algorithm: Ω({})'.format(self.memory))

if self.notation_format == NotationFormat.BIG_THETA:
print('Сomplexity of algorithm: Θ({})'.format(self.complexity))
print('Memory of algorithm: Θ({})'.format(self.memory))

print()

109 changes: 109 additions & 0 deletions notations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import ast
import inspect
from typing import List, Tuple

<<<<<<<< HEAD:pycomplexity/notations.py
from pycomplexity.analysis import Analyzer, AnalysisFormatter, NotationFormat
========
from analysis import Analyzer, AnalysisFormatter, NotationFormat
>>>>>>>> b9371afd8058da6c402979f1d0bf20215ea8fbc7:notations.py


'''
Base class of asymptotic notation
'''
class AsymptoticNotation:

def __init__(self, full_report: bool = True) -> None:
self.full_report = full_report

def _code_to_string(self, func) -> str:
code = inspect.getsource(func)
code_lines = code.split('\n')[1:]
modified_code = '\n'.join(code_lines)
return modified_code

def _get_ast(self, func) -> ast.Module:
code_str = self._code_to_string(func)
return ast.parse(code_str)

def analyze(self, func):
analyzer = Analyzer()
tree = self._get_ast(func)
# print(ast.dump(tree, indent=4))

for node in ast.walk(tree):
# print(node)
if isinstance(node, ast.FunctionDef):
func_name = node.name

if isinstance(node, ast.For):
print(node, node.body, node.iter)

# analyzer.visit(tree)
# analyzer.report()

return func_name or 'No name', ...

def report(func):
def wrapper(self, *args, **kwargs):
analysis_formatter: AnalysisFormatter = func(self, *args, **kwargs)
return analysis_formatter.report(full=self.full_report)
return wrapper


'''
Implementation of Big O notation
'''
class BigO(AsymptoticNotation):

def __init__(self) -> None:
super().__init__()

@AsymptoticNotation.report
def complexity(self, func) -> AnalysisFormatter:

func_name, _ = self.analyze(func)

return AnalysisFormatter(
func_name=func_name,
notation_format=NotationFormat.BIG_O,
)


'''
Implementation of Big Omega notation
'''
class BigOmega(AsymptoticNotation):

def __init__(self) -> None:
super().__init__()

@AsymptoticNotation.report
def complexity(self, func) -> AnalysisFormatter:

func_name, _ = self.analyze(func)

return AnalysisFormatter(
func_name=func_name,
notation_format=NotationFormat.BIG_OMEGA,
)


'''
Implementation of Big Theta notation
'''
class BigTheta(AsymptoticNotation):

def __init__(self) -> None:
super().__init__()

@AsymptoticNotation.report
def complexity(self, func) -> AnalysisFormatter:

func_name, _ = self.analyze(func)

return AnalysisFormatter(
func_name=func_name,
notation_format=NotationFormat.BIG_THETA,
)
4 changes: 4 additions & 0 deletions pycomplexity/notations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
import inspect
from typing import List, Tuple

<<<<<<<< HEAD:pycomplexity/notations.py
from pycomplexity.analysis import Analyzer, AnalysisFormatter, NotationFormat
========
from analysis import Analyzer, AnalysisFormatter, NotationFormat
>>>>>>>> b9371afd8058da6c402979f1d0bf20215ea8fbc7:notations.py


'''
Expand Down

0 comments on commit 46bfc6e

Please sign in to comment.