<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_grid_facets(facets):
 """ Return two lists of facetting variables, for the rows & columns """

    valid_seqs = ["('var1', '.')", "('var1', 'var2')",
                  "('.', 'var1')", "((var1, var2), (var3, var4))"]
    error_msg_s = ("Valid sequences for specifying 'facets' look like"
                   " {}".format(valid_seqs))

    valid_forms = ['var1 ~ .', 'var1 ~ var2', '. ~ var1',
                   'var1 + var2 ~ var3 + var4',
                   '. ~ func(var1) + func(var2)',
                   '. ~ func(var1+var3) + func(var2)'
                   ] + valid_seqs
    error_msg_f = ("Valid formula for 'facet_grid' look like"
                   " {}".format(valid_forms))

    if isinstance(facets, (tuple, list)):
        if len(facets) != 2:
            raise PlotnineError(error_msg_s)

        rows, cols = facets

        if isinstance(rows, str):
            rows = [] if rows == '.' else [rows]
        if isinstance(cols, str):
            cols = [] if cols == '.' else [cols]

        return rows, cols

    if not isinstance(facets, str):
        raise PlotnineError(error_msg_f)

    # Example of allowed formulae
    # 'c ~ a + b'
    # '. ~ func(a) + func(b)'
    # 'func(c) ~ func(a+1) + func(b+2)'
    try:
        lhs, rhs = facets.split('~')
    except ValueError:
        raise PlotnineError(error_msg_s)
    else:
        lhs = lhs.strip()
        rhs = rhs.strip()

    lhs = ensure_var_or_dot(lhs)
    rhs = ensure_var_or_dot(rhs)

    lsplitter = ' + ' if ' + ' in lhs else '+'
    rsplitter = ' + ' if ' + ' in rhs else '+'

    if lhs == '.':
        rows = []
    else:
        rows = [var.strip() for var in lhs.split(lsplitter)]

    if rhs == '.':
        cols = []
    else:
        cols = [var.strip() for var in rhs.split(rsplitter)]

    return rows, cols