From e7b847e379a0d08e1184d648c44581d89b498f7a Mon Sep 17 00:00:00 2001 From: Nikolay Simakov <n.simakoff@gmail.com> Date: Sun, 2 Jul 2023 00:04:16 +0300 Subject: [PATCH 1/4] NotationFormat moved to enums file --- pycomplexity/analysis.py | 14 +------------- pycomplexity/enums.py | 13 +++++++++++++ pycomplexity/notations.py | 3 ++- 3 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 pycomplexity/enums.py diff --git a/pycomplexity/analysis.py b/pycomplexity/analysis.py index df04339..2fddbc5 100644 --- a/pycomplexity/analysis.py +++ b/pycomplexity/analysis.py @@ -2,7 +2,7 @@ import shutil from typing import List, Tuple from pprint import pprint -from enum import Enum +from .enums import NotationFormat ''' @@ -29,18 +29,6 @@ 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 diff --git a/pycomplexity/enums.py b/pycomplexity/enums.py new file mode 100644 index 0000000..b445e65 --- /dev/null +++ b/pycomplexity/enums.py @@ -0,0 +1,13 @@ +from enum import Enum + +''' +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) \ No newline at end of file diff --git a/pycomplexity/notations.py b/pycomplexity/notations.py index 0b25362..eab5790 100644 --- a/pycomplexity/notations.py +++ b/pycomplexity/notations.py @@ -2,7 +2,8 @@ import inspect from typing import List, Tuple -from .analysis import Analyzer, AnalysisFormatter, NotationFormat +from .analysis import Analyzer, AnalysisFormatter +from .enums import NotationFormat ''' Base class of asymptotic notation From 7ce19aa559bec9aec4b81837a735098411494b1b Mon Sep 17 00:00:00 2001 From: Nikolay Simakov <n.simakoff@gmail.com> Date: Sun, 2 Jul 2023 00:10:19 +0300 Subject: [PATCH 2/4] AnalysisFormatter moved to formatters file --- pycomplexity/analysis.py | 54 -------------------------------------- pycomplexity/formatters.py | 52 ++++++++++++++++++++++++++++++++++++ pycomplexity/notations.py | 3 ++- 3 files changed, 54 insertions(+), 55 deletions(-) create mode 100644 pycomplexity/formatters.py diff --git a/pycomplexity/analysis.py b/pycomplexity/analysis.py index 2fddbc5..5d3db33 100644 --- a/pycomplexity/analysis.py +++ b/pycomplexity/analysis.py @@ -1,8 +1,5 @@ import ast -import shutil -from typing import List, Tuple from pprint import pprint -from .enums import NotationFormat ''' @@ -27,54 +24,3 @@ def visit_Import(self, node): def report(self): pprint(self.stats) - - - -''' -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() - \ No newline at end of file diff --git a/pycomplexity/formatters.py b/pycomplexity/formatters.py new file mode 100644 index 0000000..5281b8d --- /dev/null +++ b/pycomplexity/formatters.py @@ -0,0 +1,52 @@ +import shutil +from typing import List, Tuple +from .enums import NotationFormat + +''' +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() + \ No newline at end of file diff --git a/pycomplexity/notations.py b/pycomplexity/notations.py index eab5790..474ebad 100644 --- a/pycomplexity/notations.py +++ b/pycomplexity/notations.py @@ -2,7 +2,8 @@ import inspect from typing import List, Tuple -from .analysis import Analyzer, AnalysisFormatter +from .analysis import Analyzer +from .formatters import AnalysisFormatter from .enums import NotationFormat ''' From b66e4cc0e295617ab46bb117e117de968fbc8f4c Mon Sep 17 00:00:00 2001 From: Nikolay Simakov <n.simakoff@gmail.com> Date: Sun, 2 Jul 2023 02:36:22 +0300 Subject: [PATCH 3/4] Add common Big O complexities --- pycomplexity/enums.py | 28 +++++++++- pycomplexity/notations.py | 114 +++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 2 deletions(-) diff --git a/pycomplexity/enums.py b/pycomplexity/enums.py index b445e65..ea2b8c9 100644 --- a/pycomplexity/enums.py +++ b/pycomplexity/enums.py @@ -10,4 +10,30 @@ class NotationFormat(Enum): BIG_THETA : str = 'BIG Θ (THETA)' def __str__(self) -> str: - return str(self.value) \ No newline at end of file + return self.value + + +''' +The most common Big O complexity notations enum +''' +class CommonBigO(Enum): + + NON_COMMON : str = 'Non common' + CONSTANT : str = '1' + LINEAR : str = 'N' + LOGARITHMIC : str = 'log(N)' + LINEARITHMIC : str = 'N*log(N)' + QUADRATIC : str = 'N^2' + CUBIC : str = 'N^3' + EXPONENTIAL : str = '2^N' + FACTORIAL : str = 'N!' + + def __str__(self) -> str: + if self is not self.NON_COMMON: + return f'O({self.value})' + return self.value + + def __repr__(self) -> str: + _lower = self.name.replace('_', ' ').lower() + _formatted = _lower[0].upper() + _lower[1:] + return f'{_formatted} time complexity' \ No newline at end of file diff --git a/pycomplexity/notations.py b/pycomplexity/notations.py index 474ebad..9435537 100644 --- a/pycomplexity/notations.py +++ b/pycomplexity/notations.py @@ -4,7 +4,7 @@ from .analysis import Analyzer from .formatters import AnalysisFormatter -from .enums import NotationFormat +from .enums import NotationFormat, CommonBigO ''' Base class of asymptotic notation @@ -56,6 +56,118 @@ class BigO(AsymptoticNotation): def __init__(self) -> None: super().__init__() + + def constant(self, func) -> CommonBigO: + is_constant = False + + ''' + TODO: function that checks if algorithm has constant complexity + ''' + + if is_constant: + return CommonBigO.CONSTANT + return CommonBigO.NON_COMMON + + def linear(self, func) -> CommonBigO: + is_linear = False + + ''' + TODO: function that checks if algorithm has linear complexity + ''' + + if is_linear: + return CommonBigO.LINEAR + return CommonBigO.NON_COMMON + + def logarithmic(self, func) -> CommonBigO: + is_logarithmic = False + + ''' + TODO: function that checks if algorithm has logarithmic complexity + ''' + + if is_logarithmic: + return CommonBigO.LOGARITHMIC + return CommonBigO.NON_COMMON + + def linearithmic(self, func) -> CommonBigO: + is_linearithmic = False + + ''' + TODO: function that checks if algorithm has linearithmic complexity + ''' + + if is_linearithmic: + return CommonBigO.LINEARITHMIC + return CommonBigO.NON_COMMON + + def quadratic(self, func) -> CommonBigO: + is_quadratic = False + + ''' + TODO: function that checks if algorithm has quadratic complexity + ''' + + if is_quadratic: + return CommonBigO.QUADRATIC + return CommonBigO.NON_COMMON + + def cubic(self, func) -> CommonBigO: + is_cubic = False + + ''' + TODO: function that checks if algorithm has cubic complexity + ''' + + if is_cubic: + return CommonBigO.CUBIC + return CommonBigO.NON_COMMON + + def exponential(self, func) -> CommonBigO: + is_exponential = False + + ''' + TODO: function that checks if algorithm has exponential complexity + ''' + + if is_exponential: + return CommonBigO.EXPONENTIAL + return CommonBigO.NON_COMMON + + def factorial(self, func) -> CommonBigO: + is_factorial = False + + ''' + TODO: function that checks if algorithm has factorial complexity + ''' + + if is_factorial: + return CommonBigO.FACTORIAL + return CommonBigO.NON_COMMON + + def _calculate_complexity(self, func) -> CommonBigO: + checking_funcs = [ + self.constant, + self.linear, + self.logarithmic, + self.linearithmic, + self.quadratic, + self.cubic, + self.exponential, + self.factorial, + ] + + _complexities = [] + for _check in checking_funcs: + if (_complexity := _check(func)) is not CommonBigO.NON_COMMON: + _complexities.append(_complexity) + + if _complexities: + # returns the minimum from the list of possible complexities + return _complexities[0] + + # if all checking funcs returns CommonBigO.NON_COMMON + return CommonBigO.NON_COMMON @AsymptoticNotation.report def complexity(self, func) -> AnalysisFormatter: From 0d0bfa6fa16558e6c1bf9bfa7628d504459b4d3e Mon Sep 17 00:00:00 2001 From: Nikolay Simakov <n.simakoff@gmail.com> Date: Sun, 9 Jul 2023 22:45:17 +0300 Subject: [PATCH 4/4] Edit CommonBigO __repr__ method --- pycomplexity/enums.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pycomplexity/enums.py b/pycomplexity/enums.py index ea2b8c9..d887e3f 100644 --- a/pycomplexity/enums.py +++ b/pycomplexity/enums.py @@ -34,6 +34,5 @@ def __str__(self) -> str: return self.value def __repr__(self) -> str: - _lower = self.name.replace('_', ' ').lower() - _formatted = _lower[0].upper() + _lower[1:] + _formatted = self.name.replace('_', ' ').capitalize() return f'{_formatted} time complexity' \ No newline at end of file