docs: def save_data(self, filename = None, data_tag = None, verbose=False):
          """
          saves the script data to a file
          filename: target filename, if not provided, it is created from internal function
          data_tag: string, if provided save only the data that matches the tag, otherwise save all data
          verbose: if true print additional info to std out
          Returns:
  
          """
  
  
          def len(x):
              """
              overwrite the buildin len function to cover cases that don't have a length, like int or float
              and to catch string as objects of length 0
              Args:
                  x: quantity of which we want to find the length
              Returns: length of x
  
              """
              if isinstance(x, (int, float, str)) or x is None:
                  result = 0
              else:
                  result = builtin_len(x)
              return result
  
          if filename is None:
              filename = self.filename('.csv')
  
          filename = os.path.join(os.path.join(os.path.dirname(filename),self.RAW_DATA_DIR), os.path.basename(filename))
  
          # windows can't deal with long filenames so we have to use the prefix '\\\\?\\'
          # if len(filename.split('\\\\?\\')) == 1:
          filename = self.check_filename(filename)
  
          if not os.path.exists(os.path.dirname(filename)):
              os.makedirs(os.path.dirname(filename))
  
          # if deque object, take the last dataset, which is the most recent
          if isinstance(self.data, deque):
              data = self.data[-1]
          elif isinstance(self.data, dict):
              data = self.data
          else:
              raise TypeError("script data variable has an invalid datatype! Must be deque or dict.")
  
  
          if data_tag is None:
              if verbose:
                  print('data_tag is None')
  
              if len(set([len(v) for v in list(data.values())])) == 1 and set(
                      [len(np.shape(list(data.values())[i])) for i in range(len(list(data.values())))]) == set([0, 1]):
                  # if all entries of the dictionary are the same length and single column we can write the data into a single file
  
                  if len(np.shape(list(data.values())[0]))==1:
                      df = pd.DataFrame(data)
                  else:
                      df = pd.DataFrame.from_records([data])
  
                  if len(df) == 0 or df.empty:
                      print('warning! Data seems to be empty. Not saved', df)
                  else:
                      df.to_csv(filename, index=False)
  
              else:
                  # otherwise, we write each entry into a separate file
                  for key, value in data.items():
  
                      if verbose:
                          print('current data', key)
  
                      if len(value) == 0:
                          df = pd.DataFrame([value])
                      else:
                          if isinstance(value, dict) and isinstance(list(value.values())[0], (int, float)):
                              # if dictionary values are single numbers
                              df = pd.DataFrame.from_dict({k: [v] for k, v in value.items()})
                          elif isinstance(value, dict) and isinstance(list(value.values())[0], (list, np.ndarray)):
                              # if dictionary values are lists or arrays
                              df = pd.DataFrame.from_dict(value)
                          else:
                              # if not a dictionary
                              df = pd.DataFrame(value)
  
                      if len(df) == 0 or df.empty:
                          print('warning! Data ({:s}) seems to be empty. Not saved'.format(key), df)
                      else:
                          df.to_csv(filename.replace('.csv', '-{:s}.csv'.format(key)), index=False)
  
          else:
  
              # save only the data for which a key has been provided
              assert data_tag in list(data.keys())
  
              if verbose:
                  print('data_tag', data_tag)
  
              value = data[data_tag]
              if len(value) == 0:
                  df = pd.DataFrame([value])
              else:
                  df = pd.DataFrame(value)
  
              if len(df) == 0 or df.empty:
                  print('warning! Data seems to be empty. Not saved', df)
              else:
                  df.to_csv(filename, index=False)