<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def instantiate(self, substitutions):
 """Keep recursing down from base using dotted name, then call it with self.params and args Args: substitutions (dict):
 Substitutions to make to self.param_dict Returns: The found object called with (*args, map_from_d) E.g. if ob is malcolm.parts, and name is "ca.CADoublePart", then the object will be malcolm.parts.ca.CADoublePart """

        param_dict = self.substitute_params(substitutions)
        pkg, ident = self.name.rsplit(".", 1)
        pkg = "malcolm.modules.%s" % pkg
        try:
            ob = importlib.import_module(pkg)
        except ImportError as e:
            raise_with_traceback(
                ImportError("\n%s:%d:\n%s" % (
                    self.filename, self.lineno, e)))
        try:
            ob = getattr(ob, ident)
        except AttributeError:
            raise_with_traceback(
                ImportError("\n%s:%d:\nPackage %r has no ident %r" % (
                    self.filename, self.lineno, pkg, ident)))
        try:
            model = MethodModel.from_callable(ob, returns=False)
            args = model.validate(param_dict)
            ret = ob(**args)
        except Exception as e:
            sourcefile = inspect.getsourcefile(ob)
            lineno = inspect.getsourcelines(ob)[1]
            raise_with_traceback(
                YamlError("\n%s:%d:\n%s:%d:\n%s" % (
                    self.filename, self.lineno, sourcefile, lineno, e)))
        else:
            return ret