Write a detailed explanation of the principles and implementation of surface codes or Shor codes in the context of quantum computing, including their applications and limitations.
Describe how these codes can be used to protect quantum gates and qubits from errors caused by decoherence, thermal noise, and other sources.
Provide an example of how a specific error correction code would be implemented in practice using a programming language such as Qiskit or Cirq.