haikid

Untitled

Jan 23rd, 2025
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.10 KB | None | 0 0
  1. """
  2. Problem statement:
  3. Design Unix File Search API to search file with different arguments as "extension", "name", "size" ...
  4. The design should be maintainable to add new contraints.
  5.  
  6. Which pattern you should use?
  7. Answer: Specification pattern, create for each criteria a specification class
  8.  
  9. Follow up: How would you handle if some contraints should support AND, OR conditionals.
  10. I did not provided it yet. Even though below solution took 30 minutes. Solution: use Specification pattern.
  11.  
  12. I skipped some Getters/Setters to keep code simple, because you can do it yourself.
  13. Solution is simple, it is better do not overengineer. Better for you and interviewer to understand.
  14. """
  15.  
  16. from abc import ABC, abstractmethod
  17. from collections import deque
  18. from typing import List
  19.  
  20. # File
  21. # - no need to implement different files & directories as that will not be used in this system
  22. class File:
  23.     def __init__(self, name, size):
  24.         self.name = name
  25.         self.size = size
  26.         self.children = []
  27.         self.is_directory = False if '.' in name else True
  28.         self.extension = name.split(".")[1] if '.' in name else ""
  29.  
  30.     def __repr__(self):
  31.         return "{"+self.name+"}"
  32.  
  33. # Filters
  34. class Filter(ABC):
  35.     def __init__(self):
  36.         pass
  37.  
  38.     @abstractmethod
  39.     def apply(self, file):
  40.         pass
  41.  
  42.  
  43. class MinSizeFilter(Filter):
  44.     def __init__(self, size):
  45.         self.size = size
  46.  
  47.     def apply(self, file):
  48.         return file.size > self.size
  49.  
  50.  
  51. class ExtensionFilter(Filter):
  52.     def __init__(self, extension):
  53.         self.extension = extension
  54.  
  55.     def apply(self, file):
  56.         return file.extension == self.extension
  57.  
  58.  
  59. # LinuxFindCommand
  60.  
  61. class LinuxFind():
  62.     def __init__(self):
  63.         self.filters: List[Filter] = []
  64.  
  65.     def add_filter(self, given_filter):
  66.         # validate given_filter is a filter
  67.         if isinstance(given_filter, Filter):
  68.             self.filters.append(given_filter)
  69.  
  70.     def apply_OR_filtering(self, root):
  71.         found_files = []
  72.  
  73.         # bfs
  74.         queue = deque()
  75.         queue.append(root)
  76.         while queue:
  77.             # print(queue)
  78.             curr_root = queue.popleft()
  79.             if curr_root.is_directory:
  80.                 for child in curr_root.children:
  81.                     queue.append(child)
  82.             else:
  83.                 for filter in self.filters:
  84.                     if filter.apply(curr_root):
  85.                         found_files.append(curr_root)
  86.                         print(curr_root)
  87.                         break
  88.         return found_files
  89.  
  90.     def apply_AND_filtering(self, root):
  91.         found_files = []
  92.  
  93.         # bfs
  94.         queue = deque()
  95.         queue.append(root)
  96.         while queue:
  97.             curr_root = queue.popleft()
  98.             if curr_root.is_directory:
  99.                 for child in curr_root.children:
  100.                     queue.append(child)
  101.             else:
  102.                 is_valid = True
  103.                 for filter in self.filters:
  104.                     if not filter.apply(curr_root):
  105.                         is_valid = False
  106.                         break
  107.                 if is_valid:
  108.                     found_files.append(curr_root)
  109.                     print(curr_root)
  110.  
  111.         return found_files
  112.  
  113.  
  114. """
  115. TESTING
  116.  
  117. f1 = File("root_300", 300)
  118.  
  119. f2 = File("fiction_100", 100)
  120. f3 = File("action_100", 100)
  121. f4 = File("comedy_100", 100)
  122. f1.children = [f2, f3, f4]
  123.  
  124. f5 = File("StarTrek_4.txt", 4)
  125. f6 = File("StarWars_10.xml", 10)
  126. f7 = File("JusticeLeague_15.txt", 15)
  127. f8 = File("Spock_1.jpg", 1)
  128. f2.children = [f5, f6, f7, f8]
  129.  
  130. f9 = File("IronMan_9.txt", 9)
  131. f10 = File("MissionImpossible_10.rar", 10)
  132. f11 = File("TheLordOfRings_3.zip", 3)
  133. f3.children = [f9, f10, f11]
  134.  
  135. f11 = File("BigBangTheory_4.txt", 4)
  136. f12 = File("AmericanPie_6.mp3", 6)
  137. f4.children = [f11, f12]
  138.  
  139.  
  140. greater5_filter = MinSizeFilter(5)
  141. txt_filter = ExtensionFilter("txt")
  142.  
  143. my_linux_find = LinuxFind()
  144. my_linux_find.add_filter(greater5_filter)
  145. my_linux_find.add_filter(txt_filter)
  146.  
  147. print(my_linux_find.apply_OR_filtering(f1))
  148. print(my_linux_find.apply_AND_filtering(f1))
  149. """
Advertisement
Add Comment
Please, Sign In to add comment