docs: def create_dynamic_script_class(script_information, script_iterators={},verbose=False):
          '''
          creates all the dynamic classes in the script and the class of the script itself
          and updates the script info with these new classes
  
          Args:
              script_information: A dictionary describing the ScriptIterator, or an existing object
              script_iterators: dictionary with the scriptiterators (optional)
  
          Returns:
              script_information:  The updated dictionary describing the newly created ScriptIterator class
              script_iterators: updated dictionary with the scriptiterators
          Poststate: Dynamically created classes inheriting from ScriptIterator are added to pylabcontrol.scripts
  
          '''
  
          def set_up_dynamic_script(script_information, script_iterators, verbose=verbose):
              '''
  
              Args:
                  script_information: information about the script as required by Script.get_script_information()
  
              Returns:
                  script_default_settings: the default settings of the dynamically created script as a list of parameters
                  sub_scripts
  
                  script_iterators: dictionary of the script_iterator classes of the form {'package_name': <script_iterator_classe>}
                  package: name of the package of the script_iterator
  
              '''
  
              if verbose:
                  print(('script_information', script_information))
              sub_scripts = {}  # dictonary of script classes that are to be subscripts of the dynamic class. Should be in the dictionary form {'class_name': <class_object>} (btw. class_object is not the instance)
              script_order = []  # A list of parameters giving the order that the scripts in the ScriptIterator should be executed. Must be in the form {'script_name': int}. Scripts are executed from lowest number to highest
              script_execution_freq = [] # A list of parameters giving the frequency with which each script should be executed
              _, script_class_name, script_settings, _, script_sub_scripts, _, package = Script.get_script_information(script_information)
  
              if package not in script_iterators:
                  script_iterators.update(ScriptIterator.get_script_iterator(package))
  
              assert package in script_iterators
  
              iterator_type = getattr(script_iterators[package], 'get_iterator_type')(script_settings, script_sub_scripts)
              if verbose:
                  print(('iterator_type  JG', iterator_type))
  
              if isinstance(script_information, dict):
  
                  for sub_script_name, sub_script_class in script_sub_scripts.items():
                      if isinstance(sub_script_class, Script):
                          # script already exists
  
                          # To implement: add a function to scripts that outputs a script_information dict corresponding
                          # to the current settings. This can then be fed into Script.get_script_information and things
                          # can proceed as below. We may also need to add an additional tracker to the dialogue window
                          # to differentiate between the case of wanting a new script from scratch when there is an
                          # identically named one already loaded, vs using that loaded script
  
                          raise NotImplementedError
                      elif script_sub_scripts[sub_script_name]['class'] == 'ScriptIterator':
                          # raise NotImplementedError # has to be dynamic maybe???
                          script_information_subclass,  script_iterators = ScriptIterator.create_dynamic_script_class(script_sub_scripts[sub_script_name], script_iterators)
                          subscript_class_name = script_information_subclass['class']
                          #previously in python 2 had used: import pylabcontrol.core.script_iterator
                          #however, this shouldn't have worked, as this was already imported as part of pylabcontrol, so nothing
                          #happens and the old version without the dynamic script is used. Here, we force import the new
                          #version of the module which now contains the script_iterator and everything works as expected
                          script_iterator_module = __import__('pylabcontrol.core.script_iterator')
                          sub_scripts.update({sub_script_name: getattr(script_iterator_module, subscript_class_name)})
                      else:
                          if verbose:
                              print(('script_sub_scripts[sub_script_name]', sub_script_class))
  
                          module = Script.get_script_module(sub_script_class, verbose=verbose)
  
                          if verbose:
                              print(('module', module))
                          new_subscript = getattr(module, script_sub_scripts[sub_script_name]['class'])
                          sub_scripts.update({sub_script_name: new_subscript})
  
                  # for some iterators have default scripts, e.g. point iteration has select points
                  default_sub_scripts, default_script_settings = getattr(script_iterators[package], 'get_iterator_default_script')(iterator_type)
  
  
                  sub_scripts.update(default_sub_scripts)
  
                  for k, v in default_script_settings.items():
                      if k in script_settings:
                          script_settings[k].update(v)
  
  
  
              elif isinstance(script_information, Script):
  
                  print('old code - DOUBLE CHECK')
                  raise NotImplementedError
                  # if the script already exists, just update the script order parameter
                  sub_scripts.update({script_class_name: script_information})
              else:
                  raise TypeError('create_dynamic_script_class: unknown type of script_information')
  
  
  
              script_order, script_execution_freq = getattr(script_iterators[package], 'get_script_order')(script_settings['script_order'])
              script_default_settings = getattr(script_iterators[package], 'get_default_settings')(sub_scripts, script_order, script_execution_freq, iterator_type)
              return script_default_settings, sub_scripts, script_iterators, package
  
          def create_script_iterator_class(sub_scripts, script_settings, script_iterator_base_class, verbose=verbose):
              """
              A 'factory' to create a ScriptIterator class at runtime with the given inputs.
  
              Args:
                  sub_scripts: dictonary of script classes that are to be subscripts of the dynamic class. Should be in the dictionary
                           form {'class_name': <class_object>} (btw. class_object is not the instance)
                  script_default_settings: the default settings of the dynamically created object. Should be a list of Parameter objects.
  
              Returns: A newly created class inheriting from ScriptIterator, with the given subscripts and default settings
  
              """
  
  
              # dynamically import the module, i.e. the namespace for the scriptiterator
              script_iterator_module = __import__(script_iterator_base_class.__module__)
  
              if verbose:
                  print('\n\n======== create_script_iterator_class ========\n')
                  print(('sub_scripts', sub_scripts))
                  print(('script_settings', script_settings))
                  print(('script_iterator_base_class', script_iterator_base_class))
  
                  print((script_iterator_base_class.__module__.split('.')[0]))
  
  
              class_name = script_iterator_base_class.__module__.split('.')[0] + '.dynamic_script_iterator' + str(script_iterator_base_class._number_of_classes)
  
              if verbose:
                  print(('class_name', class_name))
  
              # If three parameters are passed to type(), it returns a new type object.
              # Three parameters to the type() function are:
              #
              #     name - class name which becomes __name__ attribute
              #     bases - a tuple that itemizes the base class, becomes __bases__ attribute
              #     dict - a dictionary which is the namespace containing definitions for class body; becomes __dict__ attribute
              dynamic_class = type(class_name, (script_iterator_base_class,), {'_SCRIPTS': sub_scripts, '_DEFAULT_SETTINGS': script_settings, '_INSTRUMENTS': {}})
  
              if verbose:
                  print(('dynamic_class', dynamic_class))
                  print(('__bases__', dynamic_class.__bases__))
  
                  print(('dynamic_class.__name__', dynamic_class.__name__))
                  print(('dynamic_class.__bases__', dynamic_class.__bases__))
                  print(('dynamic_class.__dict__', dynamic_class.__dict__))
  
              # Now we place the dynamic script into the scope of pylabcontrol.
              setattr(script_iterator_module, class_name, dynamic_class)
  
              if verbose:
                  print(('dynamic_class', dynamic_class))
                  print(('__bases__', dynamic_class.__bases__))
  
                  print(('dynamic_class.__name__', dynamic_class.__name__))
                  print(('dynamic_class.__bases__', dynamic_class.__bases__))
                  print(('dynamic_class.__dict__', dynamic_class.__dict__))
  
              script_iterator_base_class._class_list.append(dynamic_class)
              script_iterator_base_class._number_of_classes += 1
  
  
              return class_name, dynamic_class
  
              # todo: prevent multiple importation of the same script with different names
              # for someclass in cls._class_list:
              #     if (vars(ss)['_SCRIPTS'] == vars(someclass)['_SCRIPTS']):
              #         print('CLASSNAME', vars(someclass)['_CLASS'])
              #         return vars(someclass)['_CLASS']
  
           # get default setting, load subscripts, load the script_iterators and identify the package
          script_default_settings, sub_scripts, script_iterators, package = set_up_dynamic_script(script_information, script_iterators, verbose=verbose)
  
          # now actually create the classs
          class_name, dynamic_class = create_script_iterator_class(sub_scripts, script_default_settings, script_iterators[package], verbose = verbose)
  
          # update the generic name (e.g. ScriptIterator) to a unique name  (e.g. ScriptIterator_01)
          script_information['class'] = class_name
  
          if 'iterator_type' in script_information['settings']:
  
              if verbose:
                  print('WONDER IF WE EVER HAVE THIS CASE: iterator_type in script_information[setting]')
              script_settings = {}
              for elem in script_default_settings:
                  script_settings.update(elem)
              script_information['settings'] = script_settings
  
              if verbose:
                  print('\n\n======== create_dynamic_script_class ========\n')
  
                  print(('dynamic_class', dynamic_class))
                  print(('sub_scripts', sub_scripts))
                  print(('script_settings', script_settings))
  
          if verbose:
              print('\n======== end create_dynamic_script_class ========\n')
  
          return script_information, script_iterators