Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.65 KB | None | 0 0
  1. import os
  2. import sys
  3. from copy import copy, deepcopy
  4.  
  5. """
  6. Write a class FileIntegerList that gets at init a single parameter, a disk path to a file with an integer on each line, e.g.
  7.  
  8. 4
  9. 3
  10. 1532
  11. 13
  12. 41
  13. Considering the file above, an instance of FileIntegerList should behave in the following way:
  14.  
  15. When we print an instance of the file, only the first three numbers are shown
  16. # os.chdir('/home/cristi/.PyCharm2019.1/config/scratches')
  17. # admin:quajk2Ie@pypi.advance.com
  18.  
  19. >>> file_list = FileIntegerList('/path/to/file')
  20. >>> print(file_list)
  21. # shows only the first three numbers, if any, when the instance is printed
  22. FileIntergerList: 4, 3, 1532, ...
  23. The file is opened and read only when the instance is evaluated
  24.  
  25. # the file is not read when the instance is instantiated
  26. >>> file_list = FileIntergerList('/path/to/file')
  27. # only now the file opened and read
  28. >>> numbers = list(file_list)
  29. >>> print(numbers)
  30. [4, 1532]
  31.  
  32. >>> file_list = FileIntergerList('/path/to/file')
  33. >>> for integer in file_list:
  34. print(integer)
  35. 4
  36. 3
  37. 1532
  38. 13
  39. 41
  40. After the file has be read once, when the instance was evaluated, at a second
  41. evaluation the file is not read anymore
  42.  
  43. >>> file_list = FileIntergerList('/path/to/file')
  44. # the file is opened and read
  45. >>> for number in file_list:
  46. print(number)
  47. # the file is not opened again
  48. >>> for number in file_list:
  49. print(number)
  50.  
  51. The class has a .filter method takes as a single argument a callable that
  52. takes as a single argument an integer from the file and returns True if it
  53. should be kept or False if it should be omitted.
  54. The method .filter returns an instance of FileIntegerList so the filter
  55. operations can be chained like in the example below.
  56. The method .filter does not open the file for reading.
  57. The file will be opened only when the instance is evaluated.
  58.  
  59. >>> file_list = FileIntergerList('/path/to/file')
  60. >>> file_list = file_list.filter(l
  61. ambda x: x % 2 == 0).filter(lambda x: x % 3 == 0)
  62. >>> print(file_list)
  63.  
  64. An instance can be evaluated to True or False in an if statement
  65. # when the file is empty OR when the file does not exist
  66. >>> file_list = FileIntergerList('/path/to/empty/file')
  67. >>> if not file_list:
  68. print('The list is empty')
  69. The list is empty
  70.  
  71. # when the file has items
  72. >>> file_list = FileIntergerList('/path/to/nonempty/file')
  73. >>> if file_list:
  74. print('The list is not empty')
  75. The list is not empty
  76. Two instances can be added together to form a new list
  77.  
  78. >>> file_list_1 = FileIntergerList('/path/to/file1')
  79. >>> file_list_2 = FileIntergerList('/path/to/file2')
  80. # The files /path/to/file1 and /path/to/file2 are not opened when
  81. # this operations is performed
  82. >>> file_list = file_list_1 + file_list_2
  83. # Only now the files /path/to/file1 and /path/to/file2 are opened and read
  84. >>> numbers = list(file_list)
  85. I can use sum function on a FileIntegerList instance
  86.  
  87. >>> file_list = FileIntegerList('/path/to/file1')
  88. >>> print(sum(file_list))
  89. 15321
  90. I can use the keyword in to test the membership of an element
  91.  
  92. >>> file_list = FileIntergerList('/path/to/file')
  93. >>> print(10 in file_list)
  94. True
  95. """
  96.  
  97.  
  98. class FileIntegerList:
  99. def __init__(self, path=None):
  100. if path and not os.path.isfile(path):
  101. print("File path {} does not exist. Exiting...".format(path))
  102.  
  103. if not isinstance(path, dict):
  104. self._paths = {
  105. path: {'filters': []}
  106. }
  107. else:
  108. self._paths = path
  109.  
  110. self._data = []
  111.  
  112. self._index = None
  113. self._current_index = 0
  114. self._all_data_is_loaded = False
  115.  
  116. def __len__(self):
  117. return len(self._data)
  118.  
  119. def load_data(self, end=None, start=0):
  120. if not self._paths:
  121. return
  122.  
  123. for path in self._paths:
  124. with open(path, 'r') as file:
  125. for line_num, line in enumerate(file):
  126. if line_num + start < self._current_index:
  127. continue
  128.  
  129. if end and len(self._data) > end:
  130. break
  131.  
  132. line_is_ok = True
  133. for func in self._paths[path]['filters']:
  134. if not func(int(line)):
  135. line_is_ok = False
  136. if line_is_ok:
  137. self._data.append(int(line))
  138.  
  139. self._current_index += 1
  140.  
  141. start += line_num
  142.  
  143. self._all_data_is_loaded = True
  144.  
  145. def paint_data(self, end=None):
  146. if not end:
  147. self.load_data()
  148. return self._data
  149.  
  150. temp_end = end
  151. self.load_data(end=temp_end)
  152.  
  153. while len(self._data) < end and not self._all_data_is_loaded:
  154. temp_end += 1
  155. self.load_data(end=temp_end)
  156.  
  157. return self._data
  158.  
  159. def __repr__(self):
  160. if not self._all_data_is_loaded:
  161. return str(self)
  162.  
  163. return ', '.join([str(row) for row in self.paint_data()])
  164.  
  165. def __str__(self):
  166. filtered_data = self.paint_data(end=4)
  167. _str = ', '.join([str(row) for row in filtered_data[:3]])
  168.  
  169. if len(filtered_data) >= 3:
  170. _str += ', ...'
  171.  
  172. return _str
  173.  
  174. def __next__(self):
  175. try:
  176. if not self._index:
  177. self._index = 0
  178.  
  179. temp_index = self._index
  180. self.load_data(end=self._index)
  181. self._index += 1
  182. return self._data[temp_index]
  183.  
  184. except IndexError:
  185. self._index = None
  186. raise StopIteration
  187.  
  188. def __iter__(self):
  189. self.load_data()
  190. return self.paint_data().__iter__()
  191.  
  192. def __bool__(self):
  193. for path in self._paths:
  194. if not os.path.isfile(path) or os.path.getsize(path) == 0:
  195. return False
  196.  
  197. return True
  198.  
  199. @classmethod
  200. def _new_instance(cls, paths=None):
  201. self = cls()
  202. self._paths = paths
  203. return self
  204.  
  205. def filter(self, func):
  206. paths = deepcopy(self._paths)
  207. for path in paths:
  208. paths[path]['filters'].append(func)
  209.  
  210. return FileIntegerList._new_instance(
  211. paths=paths,
  212. )
  213.  
  214. def __add__(self, other):
  215. if not isinstance(other, FileIntegerList):
  216. raise ValueError('omfg Value Error')
  217.  
  218. paths = copy(self._paths)
  219. for key, value in other._paths.items():
  220. if key in paths:
  221. paths[key].add(value)
  222. else:
  223. paths[key] = value
  224.  
  225. return FileIntegerList._new_instance(paths=paths)
  226.  
  227.  
  228. a = 'a'
  229. a1 = FileIntegerList('first_file_1.txt')
  230. a2 = a1.filter(lambda x: x % 2 == 0)
  231. a3 = a2.filter(lambda x: x % 5 == 0)
  232.  
  233. b1 = FileIntegerList('first_file_2.txt')
  234. b2 = b1.filter(lambda x: x % 3 == 0)
  235.  
  236. c = (a3+b2)
  237. print(c)
  238. print(list(b2))
  239. print(list(a2))
  240.  
  241. a = 'a'
  242. # for i in c:
  243. # print(i)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement