code: def simplify(self):
          
          def mul(op1, op2):
              if op1 == "I":
                  return 1.0, op2
              if op2 == "I":
                  return 1.0, op1
              if op1 == op2:
                  return 1.0, "I"
              if op1 == "X":
                  return (-1j, "Z") if op2 == "Y" else (1j, "Y")
              if op1 == "Y":
                  return (-1j, "X") if op2 == "Z" else (1j, "Z")
              if op1 == "Z":
                  return (-1j, "Y") if op2 == "X" else (1j, "X")
  
          before = defaultdict(list)
          for op in self.ops:
              if op.op == "I":
                  continue
              before[op.n].append(op.op)
          new_coeff = self.coeff
          new_ops = []
          for n in sorted(before.keys()):
              ops = before[n]
              assert ops
              k = 1.0
              op = ops[0]
              for _op in ops[1:]:
                  _k, op = mul(op, _op)
                  k *= _k
              new_coeff *= k
              if new_coeff.imag == 0:
                  # cast to float
                  new_coeff = new_coeff.real
              if op != "I":
                  new_ops.append(pauli_from_char(op, n))
          return Term(tuple(new_ops), new_coeff)
docs: Simplify the Term.