code: def reconstructRules(
      source: str, feature_names, tree_id: int = 0
  ) -> None:
      """
      Reconstruct rules as python files from randomly created json
          files in parallel runs
      Args:
          source (str): json file name (e.g. outputs/rules/rules.json)
          feature_names (list): feature names
          tree_id (int): tree's id
      Returns:
          None
      """
      logger.debug(f"Reconstructing {source}")
  
      file_name = source.split(".json")[0]
      file_name = file_name + ".py"
  
      # -----------------------------------
  
      constructor = "def findDecision(obj): #"
      idx = 0
      for feature in feature_names:
          constructor = (
              constructor + "obj[" + str(idx) + "]: " + feature
          )
  
          if idx < len(feature_names) - 1:
              constructor = constructor + ", "
          idx = idx + 1
  
      functions.createFile(file_name, constructor + "\n")
  
      # -----------------------------------
  
      with open(source, "r", encoding="UTF-8") as f:
          rules = json.load(f)
  
      logger.debug(rules)
  
      def padleft(rule, level):
          for _ in range(0, level):
              rule = "\t" + rule
          return rule
  
      logger.debug("def findDecision(obj):")
  
      rule_set = []
      # json file might not store rules respectively
      for instance in rules:
          if len(instance) > 0:
              rule = []
              rule.append(instance["current_level"])
              rule.append(instance["leaf_id"])
              rule.append(instance["parents"])
              rule.append(instance["rule"])
              rule.append(instance["feature_name"])
              rule.append(instance["instances"])
              rule.append(instance["metric"])
              rule.append(instance["return_statement"])
              rule_set.append(rule)
              logger.debug(
                  padleft(instance["rule"], instance["current_level"])
              )
  
      np_rules = np.array(rule_set)
  
      def extract_rules(
          np_rules: np.ndarray, parent: str = "root", level: int = 1
      ) -> None:
          """
          Extract rules
          Args:
              np_rules (ndarray): (sub) training data frame
              parent (str): parent leaf's uuid or root for the top one
              level (int): current depth
          Returns:
              None
          """
          level_raw = level * 1
          parent_raw = copy.copy(parent)
  
          else_rule = ""
  
          leaf_idx = 0
          for i in range(0, np_rules.shape[0]):
              current_level = int(np_rules[i][0])
              leaf_id = np_rules[i][1]
              parent_id = np_rules[i][2]
              rule = np_rules[i][3]
              feature_name = np_rules[i][4]
              instances = int(np_rules[i][5])
              metric = float(np_rules[i][6])
              return_statement = int(np_rules[i][7])
  
              if parent_id == parent:
                  if_statement = False
                  if rule[0:2] == "if":
                      if_statement = True
  
                  else_statement = False
                  if rule[0:5] == "else:":
                      else_statement = True
                      else_rule = rule
  
                  # ------------------------
  
                  if else_statement != True:
                      if if_statement == True and leaf_idx > 0:
                          rule = "el" + rule
  
                      logger.debug(
                          f"{padleft(rule, level)} ({leaf_idx})"
                      )
  
                      if leaf_idx == 0 and return_statement == 0:
                          explainer = {}
                          explainer["feature"] = feature_name
                          explainer["instances"] = instances
                          explainer["metric_value"] = round(metric, 4)
                          explainer["depth"] = current_level
                          explainer = "# " + json.dumps(explainer)
                          functions.storeRule(
                              file_name, padleft(explainer, level)
                          )
  
                      functions.storeRule(
                          file_name, padleft(rule, level)
                      )
  
                      level = level + 1
                      parent = copy.copy(leaf_id)
                      extract_rules(np_rules, parent, level)
                      level = level_raw * 1
                      parent = copy.copy(parent_raw)  # restore
  
                      leaf_idx = leaf_idx + 1
  
          # add else statement
  
          if else_rule != "":
              logger.debug(padleft(else_rule, level))
              functions.storeRule(file_name, padleft(else_rule, level))
  
      # end of extract_rules
      # ------------------------------------
  
      extract_rules(np_rules)
  
imports: import math
  import uuid
  import json
  import copy
  import gc
  from contextlib import closing
  from typing import Optional
  import psutil
  import numpy
  import pandas
  from chefboost.training import Preprocess
  from chefboost.commons import functions
  from chefboost.commons.logger import Logger
  from chefboost.commons.module import load_module
  from chefboost.commons.daemon import CustomPool
label_desc: Use image node_id 7 for calling a global function with example usage: reconstructRules(source, feature_names, tree_id) and returns: rule