diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..600d2d33 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/AndreyOzerets/Task1.py b/AndreyOzerets/Task1.py new file mode 100644 index 00000000..ac0849dd --- /dev/null +++ b/AndreyOzerets/Task1.py @@ -0,0 +1,39 @@ +# Task 7.1 +import sys +import traceback + + +class MyOpen: + """Context manager for opening and working with file""" + + def __init__(self, file, mode='r') -> None: + self._file = file + self._mode = mode + self._file_obj = None + + def __enter__(self): + self._file_obj = open(self._file, self._mode) + return self._file_obj + + def __exit__(self, exc_type, exc_val, exc_tb): + self._file_obj.close() + + +def _print_ex(): + """Print traceback""" + *_, exc_traceback = sys.exc_info() + traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) + + +if __name__ == '__main__': + try: + with MyOpen('d.txt', 'r') as mo: + mo.write('OK') + except FileNotFoundError as e: + _print_ex() + print(f'\n*** Is the filename correct?: {e}', end='\n\n') + raise SystemExit + except ValueError as e: + _print_ex() + print(f'\n*** Is the mode correct?: {e}', end='\n\n') + raise SystemExit diff --git a/AndreyOzerets/Task10.py b/AndreyOzerets/Task10.py new file mode 100644 index 00000000..a9ae7c3c --- /dev/null +++ b/AndreyOzerets/Task10.py @@ -0,0 +1,23 @@ +# Task 7.10 + +from time import sleep + + +def endless_generator(): + """Endless generator.""" + number = 1 + while True: + yield number + number += 2 + + +def main(): + """Main function.""" + gen = endless_generator() + while True: + print(next(gen)) + sleep(.3) + + +if __name__ == '__main__': + main() diff --git a/AndreyOzerets/Task11.py b/AndreyOzerets/Task11.py new file mode 100644 index 00000000..586def99 --- /dev/null +++ b/AndreyOzerets/Task11.py @@ -0,0 +1,29 @@ +# Task 7.11 + + +from typing import Generator +from time import sleep + + +def endless_fib_generator() -> Generator[int, None, None]: + """Infinite fibonacci numbers. + + :yield: Fibonacci number at each iteration. + :rtype: Generator[int, None, None] + """ + + first, second = 0, 1 + while True: + yield second + first, second = second, first + second + + +def main(): + gen = endless_fib_generator() + while True: + print(next(gen)) + sleep(.3) + + +if __name__ == '__main__': + main() diff --git a/AndreyOzerets/Task2.py b/AndreyOzerets/Task2.py new file mode 100644 index 00000000..d0d9888c --- /dev/null +++ b/AndreyOzerets/Task2.py @@ -0,0 +1,36 @@ +# Task 7.2 +from contextlib import contextmanager +import sys +import traceback + + +@contextmanager +def my_open(file, mode='r'): + """Context manager for opening and working with file""" + + f = open(file, mode) + try: + yield f + finally: + f.close() + + +def _print_ex(): + """Print traceback""" + *_, exc_traceback = sys.exc_info() + traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) + + +if __name__ == '__main__': + + try: + with my_open('a.txt', 'w') as mo: + mo.write('OK') + except FileNotFoundError as e: + _print_ex() + print(f'\n*** Is the filename correct?: {e}', end='\n\n') + raise SystemExit + except ValueError as e: + _print_ex() + print(f'\n*** Is the mode correct?: {e}', end='\n\n') + raise SystemExit diff --git a/AndreyOzerets/Task3.py b/AndreyOzerets/Task3.py new file mode 100644 index 00000000..e18cc7c6 --- /dev/null +++ b/AndreyOzerets/Task3.py @@ -0,0 +1,37 @@ +# Task 7.3 +from contextlib import ContextDecorator +from time import sleep, time + + +class ExecutionTimeToLogFile(ContextDecorator): + """Decorator with context manager + + Support for writing execution time to log-file. + """ + + def __init__(self, file) -> None: + super().__init__() + self._file = file + + def __enter__(self): + print('Starting') + self._start = time() + return self + + def __exit__(self, *exc): + _stop = str(time() - self._start) + with open(self._file, 'w') as f: + f.write(f'Execution time is {_stop}') + print('Finishing') + + +@ExecutionTimeToLogFile('log-file.txt') +def fun(): + """Something very important""" + + for _ in range(50): + sleep(0.01) + + +if __name__ == '__main__': + fun() diff --git a/AndreyOzerets/Task4.py b/AndreyOzerets/Task4.py new file mode 100644 index 00000000..5f666be4 --- /dev/null +++ b/AndreyOzerets/Task4.py @@ -0,0 +1,45 @@ +# Task 7.4 + +from contextlib import ContextDecorator +from time import sleep, time + + +class SupressDecorator(ContextDecorator): + """Decorator for supressing exceptions""" + + def __init__(self, file) -> None: + super().__init__() + self._file = file + + def __enter__(self): + print('Starting') + self._start = time() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + _stop = str(time() - self._start) + message = f'Execution time is {_stop}' + if exc_type: + with open(self._file, 'w') as f: + f.write(message) + else: + print(message) + + print('Finishing') + return True + + +@SupressDecorator('log-file.txt') +def fun(): + """Something very important""" + + for _ in range(50): + sleep(0.01) + + +if __name__ == '__main__': + + with SupressDecorator('log-file.txt'): + for _ in range(50): + sleep(0.01) + raise Exception('---') diff --git a/AndreyOzerets/Task5.py b/AndreyOzerets/Task5.py new file mode 100644 index 00000000..6b18cd28 --- /dev/null +++ b/AndreyOzerets/Task5.py @@ -0,0 +1,54 @@ +# Task 7.5 + + +class MyBaseError(Exception): + """Base class for native error""" + + def __init__(self, number, message): + super().__init__(number, message) + self._number = number + self._message = message + + def __str__(self): + return f'{self._number} - {self._message}' + + +class WrongTypeError(MyBaseError): + """Class for type errors""" + + def __init__(self, number, message='is not a number') -> None: + super().__init__(number, message) + + +class NegativeError(MyBaseError): + """Class of positive errors""" + + def __init__(self, number, message='must be positive'): + super().__init__(number, message) + + +def check_parity(number: int) -> bool: + + if not isinstance(number, int): + raise WrongTypeError(number) + + if number is False: + raise MyBaseError(number, 'cannot be False') + + if number < 0: + raise NegativeError(number) + + return number % 2 == 0 + + +if __name__ == '__main__': + try: + print(check_parity(-9)) + except WrongTypeError as e: + print(e) + except MyBaseError as e: + print(e) + except NegativeError as e: + print(e) + else: + print('OK') diff --git a/AndreyOzerets/Task7.py b/AndreyOzerets/Task7.py new file mode 100644 index 00000000..66885076 --- /dev/null +++ b/AndreyOzerets/Task7.py @@ -0,0 +1,108 @@ +# Task 7.7 + +from collections.abc import Iterable +from typing import List + + +def typed_prop(name, expectrd_type): + """Type checking""" + + storage_name = '_' + name + + @property + def prop(self): + return getattr(self, storage_name) + + @prop.setter + def prop(self, value): + if isinstance(value, expectrd_type) and \ + self._validate(value, f'{self.__class__.__name__} supports only numbers!'): + setattr(self, storage_name, value) + else: + raise TypeError( + f'{self.__class__.__name__} supports only numbers!') + + return prop + + +class MyNumberCollection: + start = typed_prop('start', (int, Iterable)) + stop = typed_prop('stop', (int, type(None))) + step = typed_prop('step', (int, type(None))) + + def __init__(self, start, stop=None, step=None) -> None: + self.start = start + self.stop = stop + self.step = step + self._collection: List[int] = [] + self._init_collection() + + def append(self, value): + """Add item to the collection.""" + if self._validate(value, f"'string' - object is not a number!"): + self._add_el(value) + + def _init_collection(self) -> None: + """Complete the original list.""" + if isinstance(self.start, Iterable): + self._add_el(self.start) + else: + self._collection = [i for i in range(self.start, self.stop, + self.step) + ] + [self.stop] + + def _add_el(self, value) -> None: + """Add items to the list.""" + + if isinstance(value, Iterable): + for i in value: + if isinstance(i, Iterable): + self._add_el(i) + else: + self._collection.append(i) + else: + self._collection.append(value) + + def _validate(self, value, message) -> bool: + """Check if the passed value is not a string.""" + if isinstance(value, Iterable): + for i in value: + if isinstance(i, Iterable) and not isinstance(i, str): + self._validate(i, message) + if isinstance(i, (str)): + raise TypeError(message) + return True + + def __str__(self) -> str: + return f'{self._collection}' + + def __getitem__(self, item): + return self._collection[item] ** 2 + + def __add__(self, other): + return self._collection + other._collection + + def __iter__(self): + for i in self._collection: + yield i + + +if __name__ == '__main__': + # col3 = MyNumberCollection((1, (7, 9, (0, 's')), 3, 4)) + col1 = MyNumberCollection(0, 5, 2) + col2 = MyNumberCollection((1, 2, 3, 4, 5)) + # col3 = MyNumberCollection((1,2,3,"4",5)) + + print(f'collection 1 = {col1}') + print(f'collection 2 = {col2}') + # print(f'collection 3 = {col3}') + col1.append(7) + print(f'collection 1 = {col1}') + # col2.append("string") + print(col1 + col2) + print(f'collection 1 = {col1}') + print(f'collection 2 = {col2}') + print(col2[4]) + + for item in col1: + print(item) diff --git a/AndreyOzerets/Task8.py b/AndreyOzerets/Task8.py new file mode 100644 index 00000000..c07fd019 --- /dev/null +++ b/AndreyOzerets/Task8.py @@ -0,0 +1,31 @@ +# Task 7.8 + +from copy import deepcopy + + +class MySquareIterator: + def __init__(self, el): + self._el = deepcopy(el) + self._len = len(el) + self._i = -1 + + def __iter__(self): + return self + + def __next__(self): + self._i += 1 + if self._i >= self._len: + raise StopIteration + return self._el[self._i]**2 + + +def main(): + """Main function.""" + lst = [1, 2, 3, 4, 5] + itr = MySquareIterator(lst) + for item in itr: + print(item) + + +if __name__ == '__main__': + main() diff --git a/AndreyOzerets/Task9.py b/AndreyOzerets/Task9.py new file mode 100644 index 00000000..c4c6e729 --- /dev/null +++ b/AndreyOzerets/Task9.py @@ -0,0 +1,82 @@ +# Task 7.9 + +def typed_prop(name, expectrd_type): + """Type checking""" + + storage_name = '_' + name + + @property + def prop(self): + return getattr(self, storage_name) + + @prop.setter + def prop(self, value): + if not isinstance(value, expectrd_type): + raise TypeError(f'{name} must be a {expectrd_type}') + setattr(self, storage_name, value) + + return prop + + +class EvenRange: + start = typed_prop('start', int) + stop = typed_prop('stop', int) + + def __init__(self, start: int, stop: int) -> None: + """Initializer. + + :param start: Countdown start. + :type start: int + :param stop: End of countdown. + :type stop: int + """ + self.start = start + self.stop = stop + self.number = start + self._text = "Out of numbers!" + self._end_of_iteration = False + self._for_loop = False + + def __iter__(self): + self._for_loop = True + return self + + def __next__(self): + + while self.start < self.stop: + if self.start % 2 == 0: + self.number = self.start + self.start += 1 + return self.number + else: + self.start += 1 + else: + if not self._end_of_iteration: + self._end_of_iteration = True + return self._text + + if not self._for_loop: + return self._text + + raise StopIteration + + +def main(): + """Main function.""" + er2 = EvenRange(3, 14) + for number in er2: + print(number) + + er1 = EvenRange(7, 14) + print(next(er1)) + print(next(er1)) + print(next(er1)) + print(next(er1)) + print(next(er1)) + print(next(er1)) + print(next(er1)) + print(next(er1)) + + +if __name__ == '__main__': + main()