<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def create_introns(self, exon_featuretype='exon', grandparent_featuretype='gene', parent_featuretype=None, new_featuretype='intron', merge_attributes=True):
 """ Create introns from existing annotations. Parameters exon_featuretype : string Feature type to use in order to infer introns. Typically `"exon"`. grandparent_featuretype : string If `grandparent_featuretype` is not None, then group exons by children of this featuretype. If `granparent_featuretype` is "gene" (default), then introns will be created for all first-level children of genes. This may include mRNA, rRNA, ncRNA, etc. If you only want to infer introns from one of these featuretypes (e.g., mRNA), then use the `parent_featuretype` kwarg which is mutually exclusive with `grandparent_featuretype`. parent_featuretype : string If `parent_featuretype` is not None, then only use this featuretype to infer introns. Use this if you only want a subset of featuretypes to have introns (e.g., "mRNA" only, and not ncRNA or rRNA). Mutually exclusive with `grandparent_featuretype`. new_featuretype : string Feature type to use for the inferred introns; default is `"intron"`. merge_attributes : bool Whether or not to merge attributes from all exons. If False then no attributes will be created for the introns. Returns ------- A generator object that yields :class:`Feature` objects representing new introns Notes ----- The returned generator can be passed directly to the :meth:`FeatureDB.update` method to permanently add them to the database, e.g., :: db.update(db.create_introns()) """

        if (grandparent_featuretype and parent_featuretype) or (
            grandparent_featuretype is None and parent_featuretype is None
        ):
            raise ValueError("exactly one of `grandparent_featuretype` or "
                             "`parent_featuretype` should be provided")

        if grandparent_featuretype:
            def child_gen():
                for gene in self.features_of_type(grandparent_featuretype):
                    for child in self.children(gene, level=1):
                        yield child
        elif parent_featuretype:
            def child_gen():
                for child in self.features_of_type(parent_featuretype):
                    yield child

        for child in child_gen():
            exons = self.children(child, level=1, featuretype=exon_featuretype,
                                  order_by='start')
            for intron in self.interfeatures(
                exons, new_featuretype=new_featuretype,
                merge_attributes=merge_attributes, dialect=self.dialect
            ):
                yield intron