Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import sys
- import inspect
- import functools
- class BadTypeException(Exception):
- pass
- class BadPredicateException(Exception):
- pass
- class BadSelectorException(Exception):
- pass
- class BadFunctionException(Exception):
- pass
- class BadCastTypeException(Exception):
- pass
- class AdvList(object):
- '''Медленный но удобный лист для работы преимущественно с числовыми последовательностями. Методы, изменяющие состояние внутреннего буфера листа возвращают ссылку на себя,
- что допускает последовательный вызов методов AdvList.
- Например:
- AdvList(int, *[1, 2, 3]).Where(lambda x: x > 1).Select(lambda x: x, lambda y: y ** 2)
- '''
- def __init__(self, containment_type = None, *initargs):
- self._containment_type = containment_type
- self._data_container = []
- for item in initargs:
- if not isinstance(item, self._containment_type): raise BadTypeException('Bad Type:', f'Current list can contain only {self._containment_type}, {type(item)} added')
- self._data_container.extend(initargs)
- def __getitem__(self, position):
- return self._data_container[position]
- def __str__(self):
- return f'{self._containment_type} :: '+'[' + ', '.join(map(str, self._data_container)) + ']'
- def _check_item(self, item):
- try:
- assert isinstance(item, self._containment_type)
- except AssertionError:
- raise BadTypeException('Bad Type:', f'Current list can contain only {self._containment_type}, {type(item)} added')
- else:
- return True
- return False
- def _check_predicate(self, pred):
- try:
- assert callable(pred)
- except AssertionError:
- raise BadPredicateException('Bad predicate', f'{pred} if not callable object')
- else:
- return True
- def _clean(self):
- for index in range(len(self._data_container)-1, -1, -1):
- if self._data_container[index] == 'BAD_ITEM':
- self._data_container.pop(index)
- return self
- def Add(self, item):
- '''Добавляет один элемент в конец последовательности'''
- if self._check_item(item):
- self._data_container.append(item)
- return self
- def AddSeq(self, items:list):
- '''Добавляет последовательность элементов в конец списка. Элементы должны быть переданы в виде list'''
- for item in items:
- self._check_item(item)
- self._data_container.extend(items)
- return self
- def IndexOf(self, elem):
- '''Возвращает индекс указанного элемента'''
- return self._data_container.index(elem)
- def Find(self, felem):
- '''Возвращает первый элемент, удовлетворяющий условию'''
- for item in self._data_container:
- if item == felem:
- return item
- def FindAll(self, predicate):
- '''Возвращает кортеж элементов, удовлетворяющих условию. Условие поиска задаётся предикатом'''
- self._check_predicate(predicate)
- _cont = []
- for item in self._data_container:
- if predicate(item):
- _cont.append(item)
- return tuple(_cont)
- def Remove(self, elem):
- '''Удаляет первый встретившийся элемент, удовлетворяющий условию'''
- for index, item in enumerate(self._data_container):
- if item == elem:
- self._data_container.pop(index)
- return self
- def RemoveAll(self, predicate):
- '''Удаляет все элементы, удовлетворяющие условию. Условие задаётся предикатом'''
- self._check_predicate(predicate)
- for index, item in enumerate(self._data_container):
- if predicate(item):
- self._data_container[index] = 'BAD_ITEM'
- self._clean()
- return self
- def RetRemove(self, elem):
- '''Удаляет первый встретившийся элемент, удовлетворяющий условию и возвращает его'''
- for index, item in enumerate(self._data_container):
- if item == elem:
- return self._data_container.pop(index)
- def RetRemoveAll(self, predicate):
- '''Удаляет все элементы, удовлетворяющие условию и возвращает их. Условие задаётся предикатом '''
- self._check_predicate(predicate)
- _cont = []
- for index, item in enumerate(self._data_container):
- if predicate(item):
- _cont.append(self._data_container[index])
- self._data_container[index] = 'BAD_ITEM'
- self._clean()
- return tuple(_cont)
- def Where(self, predicate):
- '''Возвращает последовательность, содержащую исключительно удовлетворяющие условию предиката элементы'''
- self._check_predicate(predicate)
- if len(inspect.getfullargspec(predicate)[0]) > 1: raise BadPredicateException('Bad predicate:', f'_Where_ predicate can only take 1 argument: element, but {len(inspect.getfullargspec(predicate)[0])} given')
- for index, item in enumerate(self._data_container):
- if not predicate(item):
- self._data_container[index] = 'BAD_ITEM'
- self._clean()
- return self
- def Select(self, selector, func):
- '''Применяет ко всем элементам последовательности, удовлетворяющим условию селектора указанную функцию'''
- if len(inspect.getfullargspec(selector)[0]) > 1: raise BadSelectorException('Bad Selector', f'Selector function must take 1 argument, but {len(inspect.getfullargspec(selector)[0])} given')
- if len(inspect.getfullargspec(func)[0]) > 1: raise BadFunctionException('Bad function:', f'_Select_ function must take only 1 argument - selected item')
- for index, item in enumerate(self._data_container):
- if selector(item):
- self._data_container[index] = func(item)
- return self
- @property
- def Product(self):
- '''Возвращает произведение элементов последовательности'''
- return functools.reduce(lambda x, y: x*y, self._data_container)
- @property
- def Sum(self):
- '''Возвращает сумму элементов последовательности'''
- return sum(self._data_container)
- @property
- def Average(self):
- '''Возвращает среднее арифметическое последовательности'''
- return sum(self._data_container) / len(self._data_container)
- @property
- def Min(self):
- '''Возвращает минимальный элемент последовательности'''
- return min(self._data_container)
- @property
- def Max(self):
- '''Возвращает максимальный элемент последовательности'''
- return max(self._data_container)
- @property
- def Count(self):
- '''Возвращает кол-во элементов последовательности'''
- return len(self._data_container)
- @property
- def ExtractCore(self):
- '''Возвращает внутреннее хранилище класса'''
- return self._data_container
- def Cast(self, newtype):
- '''Приводит все элементы последовательности к новому типу, если это возможно. В ином случае будет выброшено исключение'''
- for index, item in enumerate(self._data_container):
- try:
- self._data_container[index] = newtype(self._data_container[index])
- except:
- raise BadCastTypeException('Bad Type for Cast', f'Can not Cast {type(self._data_container[index])} to {newtype}')
- self._containment_type = newtype
- return self
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement