docs: def get_exe_info(dir_, flag_protected=False):
      """
      Returns a list of ExeInfo objects, which represent Python scripts within dir_
  
      Args:
          dir_: string, path to directory
          flag_protected: whether or not to include files starting with a '_'
  
      Returns:
          list of ExeInfo objects
  
      The ExeInfo objects represent the ".py" files in directory dir_,
      """
  
      ret = []
      # gets all scripts in script directory
      ff = glob.glob(os.path.join(dir_, "*.py"))
      # discards scripts whose file name starts with a "_"
      ff = [f for f in ff if flag_protected or not os.path.basename(f).startswith("_")]
      ff.sort()
  
      for f in ff:
          _, filename = os.path.split(f)
          flag_error = False
          flag_gui = None
          descr = "(no doc)"
          try:
              # Checks if it is a graphical application
  
              with open(f, "r") as h:
                  flag_gui = "QApplication" in h.read()
  
              try:
                  script_ = None
                  script_ = import_module(f)  # imp.load_source('script_', f)  # module object
              except SystemExit:
                  descr = "? (called sys.exit())"
              else:
                  if script_.__doc__ is not None:
                      descr = script_.__doc__.strip().split("\n")[0]  # first line of docstring
  
          except Exception as e:
              flag_error = True
              descr = "*{0!s}*: {1!s}".format(e.__class__.__name__, str(e))
  
          if len(descr) == 0:
              descr = "(no doc)"
  
          ret.append(ExeInfo(filename, descr, flag_error, flag_gui))
  
      # Sorts command-line and graphical applications by name separately
      sisi_gra = [si for si in ret if si.flag_gui]
      sisi_cmd = [si for si in ret if not si.flag_gui]
      sisi_gra = sorted(sisi_gra, key=lambda x: x.filename)
      sisi_cmd = sorted(sisi_cmd, key=lambda x: x.filename)
      ret = sisi_cmd+sisi_gra
  
      return ret