Advertisement
Unchpokable

Python AdvList v0.0.2

Feb 3rd, 2020
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.87 KB | None | 0 0
  1. import os
  2. import sys
  3. import inspect
  4. import functools
  5.  
  6. class BadTypeException(Exception):
  7.     pass
  8.  
  9. class BadPredicateException(Exception):
  10.     pass
  11.  
  12.  
  13. class BadSelectorException(Exception):
  14.     pass
  15.  
  16. class BadFunctionException(Exception):
  17.     pass
  18.  
  19. class BadCastTypeException(Exception):
  20.     pass
  21.  
  22.  
  23. class AdvList(object):
  24.     '''Медленный но удобный лист для работы преимущественно с числовыми последовательностями. Методы, изменяющие состояние внутреннего буфера листа возвращают ссылку на себя,
  25.     что допускает последовательный вызов методов AdvList.
  26.     Например:
  27.     AdvList(int, *[1, 2, 3]).Where(lambda x: x > 1).Select(lambda x: x, lambda y: y ** 2)
  28.     '''
  29.  
  30.     def __init__(self, containment_type = None, *initargs):
  31.  
  32.         self._containment_type = containment_type
  33.         self._data_container = []
  34.  
  35.         for item in initargs:
  36.             if not isinstance(item, self._containment_type): raise BadTypeException('Bad Type:', f'Current list can contain only {self._containment_type}, {type(item)} added')
  37.  
  38.         self._data_container.extend(initargs)
  39.  
  40.     def __getitem__(self, position):
  41.         return self._data_container[position]
  42.  
  43.     def __str__(self):
  44.         return f'{self._containment_type}  ::  '+'[' + ', '.join(map(str, self._data_container)) + ']'
  45.  
  46.     def _check_item(self, item):
  47.  
  48.         try:
  49.             assert isinstance(item, self._containment_type)
  50.         except AssertionError:
  51.             raise BadTypeException('Bad Type:', f'Current list can contain only {self._containment_type}, {type(item)} added')
  52.  
  53.         else:
  54.             return True
  55.  
  56.         return False
  57.  
  58.     def _check_predicate(self, pred):
  59.         try:
  60.             assert callable(pred)
  61.         except AssertionError:
  62.             raise BadPredicateException('Bad predicate', f'{pred} if not callable object')
  63.         else:
  64.             return True
  65.  
  66.     def _clean(self):
  67.         for index in range(len(self._data_container)-1, -1, -1):
  68.             if self._data_container[index] == 'BAD_ITEM':
  69.                 self._data_container.pop(index)
  70.  
  71.         return self
  72.  
  73.  
  74.  
  75.     def Add(self, item):
  76.         '''Добавляет один элемент в конец последовательности'''
  77.  
  78.         if self._check_item(item):
  79.             self._data_container.append(item)
  80.  
  81.         return self
  82.  
  83.     def AddSeq(self, items:list):
  84.         '''Добавляет последовательность элементов в конец списка. Элементы должны быть переданы в виде list'''
  85.         for item in items:
  86.             self._check_item(item)
  87.  
  88.         self._data_container.extend(items)
  89.         return self
  90.  
  91.     def IndexOf(self, elem):
  92.         '''Возвращает индекс указанного элемента'''
  93.         return self._data_container.index(elem)
  94.  
  95.  
  96.     def Find(self, felem):
  97.         '''Возвращает первый элемент, удовлетворяющий условию'''
  98.         for item in self._data_container:
  99.             if item == felem:
  100.                 return item
  101.  
  102.  
  103.     def FindAll(self, predicate):
  104.         '''Возвращает кортеж элементов, удовлетворяющих условию. Условие поиска задаётся предикатом'''
  105.         self._check_predicate(predicate)
  106.         _cont = []
  107.  
  108.         for item in self._data_container:
  109.             if predicate(item):
  110.                 _cont.append(item)
  111.  
  112.         return tuple(_cont)
  113.  
  114.     def Remove(self, elem):
  115.         '''Удаляет первый встретившийся элемент, удовлетворяющий условию'''
  116.         for index, item in enumerate(self._data_container):
  117.             if item == elem:
  118.                 self._data_container.pop(index)
  119.  
  120.         return self
  121.  
  122.     def RemoveAll(self, predicate):
  123.         '''Удаляет все элементы, удовлетворяющие условию. Условие задаётся предикатом'''
  124.         self._check_predicate(predicate)
  125.         for index, item in enumerate(self._data_container):
  126.             if predicate(item):
  127.                 self._data_container[index] = 'BAD_ITEM'
  128.         self._clean()
  129.  
  130.         return self
  131.  
  132.  
  133.     def RetRemove(self, elem):
  134.         '''Удаляет первый встретившийся элемент, удовлетворяющий условию и возвращает его'''
  135.         for index, item in enumerate(self._data_container):
  136.             if item == elem:
  137.                 return self._data_container.pop(index)
  138.  
  139.        
  140.     def RetRemoveAll(self, predicate):
  141.         '''Удаляет все элементы, удовлетворяющие условию и возвращает их. Условие задаётся предикатом '''
  142.         self._check_predicate(predicate)
  143.         _cont = []
  144.  
  145.         for index, item in enumerate(self._data_container):
  146.             if predicate(item):
  147.                 _cont.append(self._data_container[index])
  148.                 self._data_container[index] = 'BAD_ITEM'
  149.         self._clean()
  150.  
  151.         return tuple(_cont)
  152.  
  153.  
  154.     def Where(self, predicate):
  155.         '''Возвращает последовательность, содержащую исключительно удовлетворяющие условию предиката элементы'''
  156.         self._check_predicate(predicate)
  157.         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')
  158.  
  159.         for index, item in enumerate(self._data_container):
  160.             if not predicate(item):
  161.                 self._data_container[index] = 'BAD_ITEM'
  162.  
  163.         self._clean()
  164.  
  165.         return self
  166.  
  167.     def Select(self, selector, func):
  168.         '''Применяет ко всем элементам последовательности, удовлетворяющим условию селектора указанную функцию'''
  169.  
  170.         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')
  171.         if len(inspect.getfullargspec(func)[0]) > 1: raise BadFunctionException('Bad function:', f'_Select_ function must take only 1 argument - selected item')
  172.  
  173.         for index, item in enumerate(self._data_container):
  174.             if selector(item):
  175.                 self._data_container[index] = func(item)
  176.  
  177.         return self
  178.  
  179.     @property
  180.     def Product(self):
  181.         '''Возвращает произведение элементов последовательности'''
  182.         return functools.reduce(lambda x, y: x*y, self._data_container)
  183.  
  184.     @property
  185.     def Sum(self):
  186.         '''Возвращает сумму элементов последовательности'''
  187.         return sum(self._data_container)
  188.  
  189.     @property
  190.     def Average(self):
  191.         '''Возвращает среднее арифметическое последовательности'''
  192.         return sum(self._data_container) / len(self._data_container)
  193.  
  194.     @property
  195.     def Min(self):
  196.         '''Возвращает минимальный элемент последовательности'''
  197.         return min(self._data_container)
  198.  
  199.     @property
  200.     def Max(self):
  201.         '''Возвращает максимальный элемент последовательности'''
  202.         return max(self._data_container)
  203.  
  204.     @property
  205.     def Count(self):
  206.         '''Возвращает кол-во элементов последовательности'''
  207.         return len(self._data_container)
  208.  
  209.     @property
  210.     def ExtractCore(self):
  211.         '''Возвращает внутреннее хранилище класса'''
  212.         return self._data_container
  213.  
  214.        
  215.     def Cast(self, newtype):
  216.         '''Приводит все элементы последовательности к новому типу, если это возможно. В ином случае будет выброшено исключение'''
  217.         for index, item in enumerate(self._data_container):
  218.             try:
  219.                 self._data_container[index] = newtype(self._data_container[index])
  220.             except:
  221.                 raise BadCastTypeException('Bad Type for Cast', f'Can not Cast {type(self._data_container[index])} to {newtype}')
  222.  
  223.         self._containment_type = newtype
  224.  
  225.         return self
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement