input: Write a function to create an environment object that can execute and analyze Python code. The environment includes a set of predefined global variables and functions, as well as the ability to add additional global variables. The environment can execute Python code and analyze it for variable usage and imports. The environment also includes a stdout object that can be used to capture and display output from executed code.
  
  
  def create_environment(path):
      class Environment:
          extra_globals = {}
          active = weakref.WeakSet()
          predefined_names = set(["parsed"])
  
          def __init__(self, path):
              self.path = path
              self.globals = {
                  "print": jsonify_print,
                  "print_expr": jsonify_print_expr,
                  "jsonify": jsonify,
                  "jsonify_print": jsonify_print,
                  "listdir": stdlib.listdir,
                  "__builtins__": __builtins__,
                  "FILES": stdlib.FilesDict(self.path),
              }
              for name in stdlib.builtin_names:
                  self.globals[name] = getattr(stdlib, name)
              self._cached_analysis = {}
              self.active.add(self)
  
          def init_commands(self):
              for path in os.listdir(self.path):
                  if path.endswith(".json"):
                      continue
                  if not os.path.isfile(os.path.join(self.path, path)):
                      continue
                  try:
                      with open(os.path.join(self.path, path), "r") as fp:
                          content = fp.read()
                      yield FileEdit(filename=path, content=content, external_edit=True)
                  except UnicodeDecodeError:
                      pass
  
          def fixup_globals(self):
              for name, value in self.extra_globals.items():
                  self.globals.setdefault(name, value)
  
          def execute(self, filename, content, subexpressions=False):
              print("Executing", filename, subexpressions)
              self.fixup_globals()
              stdout = Stdout()
              compiled = None
              try:
                  parsed = ast.parse(content, filename, mode='exec')
                  RewriteExprToPrint(subexpressions).walk(parsed)
                  var_inspect = VariableInspector()
                  var_inspect.walk(parsed)
                  print("varsed used:", sorted(var_inspect.used), "set:", sorted(var_inspect.set), "imported:", var_inspect.imports)
                  compiled = compile(parsed, filename, 'exec')
              except:
                  stdout.write(traceback.format_exc())
  
              def displayhook(value):
                  stdout.write_repr(value)
  
              orig_displayhook = sys.displayhook
              sys.displayhook = displayhook
              orig_stdout = sys.stdout
              orig_stderr = sys.stderr
              sys.stdout = stdout
              sys.stderr = stdout
              self.globals["parsed"] = parsed
              self.globals["ast"] = ast
              globals_before = self.globals.copy()
              start = time.time()
              try:
                  try:
                      if compiled:
                          exec(compiled, self.globals)
                  except:
                      traceback.print_exc()
              finally:
                  end = time.time()
                  sys.dipslayhook = orig_displayhook
                  sys.stdout = orig_stdout
                  sys.stderr = orig_stderr
              local_scope = dict(
                  (name, value)
                  for name, value in self.globals.items()
                  if name not in globals_before or globals_before[name] is not value)
              defines = dict(
                  (key, {
                      "json": jsonify(local_scope[key]),
                      "type": str(type(local_scope[key])),
                  })
                  for key in local_scope
                  if not isinstance(local_scope[key], types.ModuleType))
              command = Execution(
                  filename=filename,
                  content=content,
                  emitted=stdout.emitted,
                  defines=defines,
                  start_time=int(start * 1000),
                  end_time=int(end * 1000),
                  exec_time=int((end - start) * 1000),
                  with_subexpressions=subexpressions,
              )
              send(command)
  
          def analyze(self, filename, content):
              print("Analyzing", filename)
              properties = {}
              try:
                  parsed = ast.parse(content, filename, mode='exec')
                  var_inspect = VariableInspector()
                  var_inspect.walk(parsed)
              except:
                  return
                  properties["parse_error"] = jsonify(traceback.format_exc())
              else:
                  properties = var_inspect.json
              if properties != self._cached_analysis.get(filename):
                  self._cached_analysis[filename] = properties
                  send(Analysis(filename=filename, content=content, properties=properties))
  
      return Environment(path)
  
  assert create_environment("/path/to/code").execute("test.py", "print('Hello, World!')") == None
  assert create_environment("/path/to/code").analyze("test.py", "print('Hello, World!')") == None
  
output: 
  def create_environment(path):
      class Environment:
          extra_globals = {}
          active = weakref.WeakSet()
          predefined_names = set(["parsed"])
  
          def __init__(self, path):
              self.path = path
              self.globals = {
                  "print": jsonify_print,
                  "print_expr": jsonify_print_expr,
                  "jsonify": jsonify,
                  "jsonify_print": jsonify_print,
                  "listdir": stdlib.listdir,
                  "__builtins__": __builtins__,
                  "FILES": stdlib.FilesDict(self.path),
              }
              for name in stdlib.builtin_names:
                  self.globals[name] = getattr(stdlib, name)
              self._cached_analysis = {}
              self.active.add(self)
  
          def init_commands(self):
              for path in os.listdir(self.path):
                  if path.endswith(".json"):
                      continue
                  if not os.path.isfile(os.path.join(self.path, path)):
                      continue
                  try:
                      with open(os.path.join(self.path, path), "r") as fp:
                          content = fp.read()
                      yield FileEdit(filename=path, content=content, external_edit=True)
                  except UnicodeDecodeError:
                      pass
  
          def fixup_globals(self):
              for name, value in self.extra_globals.items():
                  self.globals.setdefault(name, value)
  
          def execute(self, filename, content, subexpressions=False):
              self.fixup_globals()
              stdout = Stdout()
              compiled = None
              try:
                  parsed = ast.parse(content, filename, mode='exec')
                  RewriteExprToPrint(subexpressions).walk(parsed)
                  var_inspect = VariableInspector()
                  var_inspect.walk(parsed)
                  compiled = compile(parsed, filename, 'exec')
              except:
                  stdout.write(traceback.format_exc())
  
              def displayhook(value):
                  stdout.write_repr(value)
  
              orig_displayhook = sys.displayhook
              sys.displayhook = displayhook
              orig_stdout = sys.stdout
              orig_stderr = sys.stderr
              sys.stdout = stdout
              sys.stderr = stdout
              self.globals["parsed"] = parsed
              self.globals["ast"] = ast
              globals_before = self.globals.copy()
              start = time.time()
              try:
                  try:
                      if compiled:
                          exec(compiled, self.globals)
                  except:
                      traceback.print_exc()
              finally:
                  end = time.time()
                  sys.displayhook = orig_displayhook
                  sys.stdout = orig_stdout
                  sys.stderr = orig_stderr
              local_scope = dict(
                  (name, value)
                  for name, value in self.globals.items()
                  if name not in globals_before or globals_before[name] is not value)
              defines = dict(
                  (key, {
                      "json": jsonify(local_scope[key]),
                      "type": str(type(local_scope[key])),
                  })
                  for key in local_scope
                  if not isinstance(local_scope[key], types.ModuleType))
              command = Execution(
                  filename=filename,
                  content=content,
                  emitted=stdout.emitted,
                  defines=defines,
                  start_time=int(start * 1000),
                  end_time=int(end * 1000),
                  exec_time=int((end - start) * 1000),
                  with_subexpressions=subexpressions,
              )
              send(command)
  
          def analyze(self, filename, content):
              properties = {}
              try:
                  parsed = ast.parse(content, filename, mode='exec')
                  var_inspect = VariableInspector()
                  var_inspect.walk(parsed)
              except:
                  return
                  properties["parse_error"] = jsonify(traceback.format_exc())
              else:
                  properties = var_inspect.json
              if properties != self._cached_analysis.get(filename):
                  self._cached_analysis[filename] = properties
                  send(Analysis(filename=filename, content=content, properties=properties))
  
      return Environment(path)
  