<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def dirac_notation(state: Sequence, decimals: int=2) -> str: """Returns the wavefunction as a string in Dirac notation. For example: state = np.array([1/np.sqrt(2), 1/np.sqrt(2)], dtype=np.complex64) print(dirac_notation(state)) -> 0.71|0⟩ + 0.71|1⟩ Args: state: A sequence representing a wave function in which the ordering mapping to qubits follows the standard Kronecker convention of numpy.kron. decimals: How many decimals to include in the pretty print. Returns: A pretty string consisting of a sum of computational basis kets and non-zero floats of the specified accuracy. """

    perm_list = ["".join(seq) for seq in itertools.product(
        "01", repeat=int(len(state)).bit_length() - 1)]
    components = []
    ket = "|{}⟩"
    for x in range(len(perm_list)):
        format_str = "({:." + str(decimals) + "g})"
        # Python 2 rounds imaginary numbers to 0, so need to round separately.
        val = (round(state[x].real, decimals)
               + 1j * round(state[x].imag, decimals))
        if round(val.real, decimals) == 0 and round(val.imag, decimals) != 0:
            val = val.imag
            format_str = "{:." + str(decimals) + "g}j"
        elif round(val.imag, decimals) == 0 and round(val.real, decimals) != 0:
            val = val.real
            format_str = "{:." + str(decimals) + "g}"
        if val != 0:
            if round(state[x], decimals) == 1:
                components.append(ket.format(perm_list[x]))
            else:
                components.append((format_str + ket).format(val, perm_list[x]))
    if not components:
        return '0'

    return ' + '.join(components).replace(' + -', ' - ')