<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def parse_blocks(self, text):
 """Extract the code and non-code blocks from given markdown text. Returns a list of block dictionaries. Each dictionary has at least the keys 'type' and 'content', containing the type of the block ('markdown', 'code') and the contents of the block. Additional keys may be parsed as well. We should switch to an external markdown library if this gets much more complicated! """

        code_matches = [m for m in self.code_pattern.finditer(text)]

        # determine where the limits of the non code bits are
        # based on the code block edges
        text_starts = [0] + [m.end() for m in code_matches]
        text_stops = [m.start() for m in code_matches] + [len(text)]
        text_limits = list(zip(text_starts, text_stops))

        # list of the groups from the code blocks
        code_blocks = [self.new_code_block(**m.groupdict())
                       for m in code_matches]

        text_blocks = [self.new_text_block(content=text[i:j])
                       for i, j in text_limits]

        # remove indents
        list(map(self.pre_process_code_block, code_blocks))
        # remove blank line at start and end of markdown
        list(map(self.pre_process_text_block, text_blocks))

        # create a list of the right length
        all_blocks = list(range(len(text_blocks) + len(code_blocks)))

        # NOTE: the behaviour here is a bit fragile in that we
        # assume that cells must alternate between code and
        # markdown. This isn't the case, as we could have
        # consecutive code cells, and we get around this by
        # stripping out empty cells. i.e. two consecutive code cells
        # have an empty markdown cell between them which is stripped
        # out because it is empty.

        # cells must alternate in order
        all_blocks[::2] = text_blocks
        all_blocks[1::2] = code_blocks

        # remove possible empty text cells
        all_blocks = [cell for cell in all_blocks if cell['content']]

        return all_blocks