SHARE
TWEET

Untitled

a guest Aug 12th, 2017 52 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import json
  2.  
  3.  
  4.     # linked list class representing hiearchy and selectors
  5. debug = True
  6. def print_debug(input):
  7.     if debug:
  8.         print(input)
  9.  
  10. class Selector:
  11.     def __init__(self, tag, id, classes):
  12.         # we do empty string checks in constructor for convenience of constructing selectors
  13.         self.classes = None
  14.         self.tag = None
  15.         self.id = None
  16.         if not tag and not id and not classes:
  17.             print("nothing to select")
  18.         if tag:
  19.             self.tag = tag
  20.         if id:
  21.             self.id = id
  22.         if classes:
  23.             self.classes = classes
  24.     def match(self, other):
  25.         if not other:
  26.             return false
  27.         match = True
  28.         if self.tag:
  29.             match &= self.tag == other.tag
  30.         if self.id:
  31.             match &= self.id == other.id
  32.         if self.classes:
  33.             if not other.classes:
  34.                 return False
  35.             match &= set(self.classes) <= set(other.classes) # python is literally pseudocode. check subset or equality
  36.         return match
  37.     def __repr__(self):
  38.         return "Selector:[tag: {}, id: {}, classes {}]".format(self.tag, self.id, self.classes)
  39.        
  40.    
  41.  
  42. class DOM(Selector):
  43.     def __init__(self, tag):
  44.         if not tag:
  45.             print("Tag can't be null for DOM object")
  46.         self.tag = tag
  47.         self.children = None
  48.  
  49.  
  50.  
  51. def parse_selector(string_rep):
  52.     selector_hierarchy = string_rep.split(" ") # hierarchy is based on split lines
  53.     selector_chain = []
  54.     for elem in selector_hierarchy:
  55.         tag, hashbrown, after_brown = elem.partition("#")
  56.         id, dot, all_the_classes = after_brown.partition(".")
  57.         classes = []
  58.         while all_the_classes:
  59.             class_to_add, dotty, rest = all_the_classes.partition(".")
  60.             if class_to_add:
  61.                 classes.append(class_to_add)
  62.             all_the_classes = rest
  63.         selector_chain.append(Selector(tag, id, classes))
  64.     return selector_chain
  65.  
  66. def parse_dom(input_node):
  67.     tag = input_node["tag"]
  68.     classes = input_node["classes"] if "classes" in input_node else None
  69.     id = input_node["id"] if "id" in input_node else None
  70.     children = None
  71.     if "children" in input_node:
  72.         children = [parse_dom(elem) for elem in input_node["children"]]
  73.     dom_to_return = DOM(tag)
  74.     dom_to_return.classes = classes
  75.     dom_to_return.id = id
  76.     dom_to_return.children = children
  77.     return dom_to_return
  78.        
  79. def iterative_DFS_matcher(dom_tree, selector):
  80.     counter = 0
  81.     stack = [dom_tree]
  82.     curr_selector_depth = 0
  83.     tombstone = "tombstone" # when we pop this, it means that we gotta go up the selector hierarchy by 1"
  84.     while stack:
  85.         elem_to_visit = stack.pop()
  86.         print_debug("visiting: {}".format(elem_to_visit))
  87.         if elem_to_visit == tombstone:
  88.             curr_selector_depth -= 1
  89.             print_debug("got tombstone, decrementing current selector_depth to : {}".format(curr_selector_depth))
  90.         else:
  91.             if selector[curr_selector_depth].match(elem_to_visit):
  92.                 if curr_selector_depth == len(selector) - 1:
  93.                     print_debug("got full hit on selector: {} full selector: {}".format(selector[curr_selector_depth], selector))
  94.                     counter += 1
  95.                 else:
  96.                     print_debug("got partial hit on selector: {} full selector: {}".format(selector[curr_selector_depth], selector))
  97.                     curr_selector_depth +=1
  98.                     # add tombstone indicating that if you pop this you gotta go back up the selector chain
  99.                     stack.append(tombstone)
  100.                
  101.             stack = stack + elem_to_visit.children if elem_to_visit.children else stack
  102.     return counter
  103.        
  104.    
  105.    
  106.        
  107.            
  108.        
  109.        
  110.        
  111.  
  112. # get the input
  113. read_input = ""
  114. # while(True):
  115. #     try:
  116. #         new_line = input()
  117. #         read_input = read_input + new_line + "\n"
  118. #     except EOFError:
  119. #         break
  120.  
  121. with open('input004.txt', 'r') as myfile:
  122.     read_input=myfile.read().replace('\n', '')
  123.  
  124. json_map = json.loads(read_input)
  125.  
  126. # build the selectors list
  127. selectors_list = [parse_selector(element) for element in json_map["tests"]]
  128. dom_tree = parse_dom(json_map["hierarchy"])
  129. print_debug("selectors list: {}".format(selectors_list))
  130. print_debug("dom_tree: {}".format(dom_tree))
  131.  
  132. # for some fucky reason this test case is not formatting the strings correctly sigh
  133. output = [iterative_DFS_matcher(dom_tree, elem) for elem in selectors_list]
  134. print("[" + ",".join(str(elem) for elem in output) + "]")
  135. # print_debug("let's go select some stuff: {}".format(iterative_DFS_matcher(dom_tree, selectors_list[0])))
RAW Paste Data
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top