En el desarrollo de software, los estándares de código elegantes pueden ayudarnos a escribir código que sea a la vez hermoso y práctico.

A continuación se presentan estándares sugeridos para mejorar la calidad del código:

  • Nombres claros: utiliza nombres muy descriptivos para que el código se explique por sí mismo.
  • Simplicidad: busca la simplicidad, evita la redundancia y completa las funciones con el menor número de líneas de código.
  • Consistencia: mantén la uniformidad en los nombres y el estilo de codificación del proyecto para reducir la carga cognitiva.
  • Comentarios: utiliza comentarios para aclarar la intención del código, pero evita los comentarios excesivos.
  • Evitar la complejidad: descompón la lógica compleja en funciones o módulos simples y manejables.
  • Refactorización: refactoriza periódicamente para mejorar la legibilidad y el rendimiento del código.
  • Pruebas: escribe pruebas unitarias para garantizar la estabilidad y fiabilidad del código.
  • Manejo de errores: gestiona los errores adecuadamente para aumentar la robustez del programa.
  • Documentación: escribe documentación clara, incluida la documentación de la API y la del proyecto.
  • Reutilización de código: crea funciones o módulos reutilizables para evitar código duplicado.
  • Optimización del rendimiento: optimiza los cuellos de botella de rendimiento sin sacrificar la legibilidad.
  • Seguridad: escribe código seguro para prevenir vulnerabilidades de seguridad comunes.

A continuación, ampliamos la explicación:

1. Nombres claros

En programación, los nombres son la primera impresión.

Un buen nombre permite ver de un vistazo la función de una variable, función o clase.

Los nombres claros y precisos pueden reducir malentendidos y mejorar la legibilidad del código.

Por ejemplo, customerList deja más claro que list que almacena información de clientes.

Los nombres de variables, funciones y clases deben describir intuitivamente su función y propósito, evitando nombres ambiguos o irrelevantes.

Ejemplo

# Buen ejemplo: nombres claros
def calculate_area(width, height):
    return width * height
​
# Mal ejemplo: nombres poco claros
def calc(w, h):
    return w * h

2. Simplicidad

El código simple significa completar la funcionalidad requerida con el menor número de líneas de código, lo que reduce la dificultad de mantenimiento y la probabilidad de errores.

Por ejemplo, el uso de la comprensión de listas de Python puede crear listas de forma más concisa que los bucles for tradicionales.

Intenta completar las funciones con el mínimo de código y evita la redundancia. El código conciso es más fácil de leer y mantener.

Ejemplo

# Buen ejemplo: usar funciones integradas
numbers = [1, 2, 3, 4, 5]
total = sum(numbers)
​
# Mal ejemplo: bucles redundantes
total = 0
for number in numbers:
    total += number

3. Consistencia

La consistencia es clave en la colaboración en equipo.

Ya sea en las reglas de nomenclatura, la estructura de las funciones o el formato del código, un estilo consistente puede reducir el costo de comunicación entre los miembros del equipo.

Si un equipo decide utilizar la convención camelCase, todos los nombres de variables y funciones deben seguir esta regla.

Se debe mantener un estilo de nomenclatura y codificación consistente en todo el proyecto, incluidas las convenciones de nombres, el formato del código y el estilo de los comentarios.

Ejemplo

# Buen ejemplo: nombres consistentes
def get_user_name(user):
    return user.name
​
def get_user_email(user):
    return user.email
​
# Mal ejemplo: nombres inconsistentes
def getName(user):
    return user.name
​
def getEmail(user):
    return user.email

4. Comentarios

Los comentarios son el manual del código.

Los comentarios razonables pueden explicar la intención del código y ayudar a otras personas (o a tu yo futuro) a comprender la lógica compleja.

El mejor código es autoexplicativo; solo se necesitan comentarios cuando el código en sí no es lo suficientemente claro.

Evita comentar en exceso el código evidente.

Ejemplo

# Buen ejemplo: comentarios necesarios
# Comprueba si el usuario ha iniciado sesión
if user.is_authenticated:
    # El usuario ha iniciado sesión, permitir el acceso
    pass
​
# Mal ejemplo: comentarios excesivos
def add(a, b):
    # a es el primer número
    # b es el segundo número
    # Esta función devuelve la suma de dos números
    return a + b

5. Evitar la complejidad

El código complejo es difícil de entender y mantener.

Intenta descomponer la lógica compleja en partes simples, utilizando funciones o clases para encapsularla.

Evita funciones demasiado largas y anidamientos profundos, ya que aumentan la dificultad de lectura del código.

Descompón la lógica compleja en partes más pequeñas y manejables.

Ejemplo

# Buen ejemplo: lógica simple
def is_even(number):
    return number % 2 == 0
​
# Mal ejemplo: lógica compleja
def check_number(number):
    if number is None:
        return False
    elif number < 0:
        return False
    else:
        return number % 2 == 0

6. Refactorización

La refactorización es el proceso de mejorar el código existente sin cambiar su comportamiento externo.

La refactorización periódica puede mejorar la legibilidad y el rendimiento del código, eliminar código duplicado y optimizar la estructura.

La refactorización debe realizarse con cuidado, asegurando la cobertura de pruebas para evitar introducir nuevos errores.

Ejemplo

# Antes de la refactorización: formato de cadena repetido
def greet(name):
    return "Hello, " + name + "!"
​
def farewell(name):
    return "Goodbye, " + name + "!"
​
# Después de la refactorización: usar formato de cadena
def greet(name):
    return f"Hello, {name}!"
​
def farewell(name):
    return f"Goodbye, {name}!"

7. Pruebas

Las pruebas unitarias son la garantía de que el código funcione como se espera.

Escribe pruebas unitarias para garantizar la estabilidad y fiabilidad del código.

Las pruebas pueden verificar automáticamente la funcionalidad del código, especialmente cuando se modifica o refactoriza el código.

Ejemplo

# Escribir pruebas con el framework unittest
import unittest
​
class TestCalculator(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(1, 2), 3)
​
    def test_subtract(self):
        self.assertEqual(subtract(3, 1), 2)

8. Manejo de errores

El manejo de errores es una parte importante de un programa robusto.

Maneja adecuadamente las situaciones de error que puedan ocurrir, evita que el programa se bloquee ante situaciones excepcionales y, al mismo tiempo, proporciona comentarios útiles.

Utiliza bloques try-except para capturar y manejar posibles excepciones.

Ejemplo

# Buen ejemplo: manejo de errores adecuado
try:
    number = int(input("Enter a number: "))
    if number < 0:
        raise ValueError("Number must be non-negative")
except ValueError as e:
    print(f"Error: {e}")
​
# Mal ejemplo: falta de manejo de errores
number = int(input("Enter a number: "))  # Sin manejo de errores

9. Documentación

La documentación es el mapa del proyecto.

Escribe documentación clara, incluida la documentación de la API y la documentación del proyecto, para ayudar a los nuevos miembros del equipo a comprender rápidamente la estructura del proyecto; la documentación de la API permite a los usuarios saber cómo utilizar tu código.

Ejemplo

"""
Este módulo proporciona algunas funciones de utilidad para manejar datos de usuarios.
"""

def validate_email(email):
    """
Comprueba si una dirección de correo electrónico es válida.
Parámetros:
email (str): la dirección de correo electrónico a validar.
Devuelve:
bool: devuelve True si el correo electrónico es válido; de lo contrario, devuelve False.
    """

    # Implementar la lógica de validación

La documentación explica claramente la función, los parámetros y el valor de retorno, lo que ayuda a otros desarrolladores a utilizar correctamente esta función.

10. Reutilización de código

Evitar la duplicación es un principio básico de la programación.

Evita escribir repetidamente el mismo código, crea funciones o módulos reutilizables, reduce la redundancia del código y mejora la eficiencia del desarrollo. Al mismo tiempo, el código reutilizado es más fácil de mantener y actualizar.

Ejemplo

# Buen ejemplo: reutilizar código
def format_name(first, last):
    return f"{first} {last}"
user1 = format_name("John", "Doe")
user2 = format_name("Jane", "Smith")
# Mal ejemplo: código duplicado
def get_user1_name():
    return "John Doe"
def get_user2_name():
    return "Jane Smith"

11. Optimización del rendimiento

La optimización del rendimiento es el proceso de mejorar la eficiencia de ejecución de un programa.

Optimiza los cuellos de botella de rendimiento sin sacrificar la legibilidad. Esto puede implicar la selección de algoritmos, el uso de estructuras de datos o la optimización del código.

Pero recuerda, la optimización prematura es la raíz de todos los males; asegúrate de optimizar sin sacrificar la legibilidad del código.

Ejemplo

# Buen ejemplo: usar conjuntos para mejorar la eficiencia de búsqueda
def has_duplicates(numbers):
    return len(numbers) != len(set(numbers))
​
# Mal ejemplo: usar listas para búsquedas, menos eficiente
def has_duplicates(numbers):
    for i in range(len(numbers)):
        for j in range(i + 1, len(numbers)):
            if numbers[i] == numbers[j]:
                return True
    return False

12. Seguridad

La seguridad es un aspecto que no se puede ignorar en la programación.

Escribe código seguro para evitar vulnerabilidades de seguridad comunes, como la inyección SQL, los ataques XSS, etc.

Ejemplo

# Buen ejemplo: prevenirSQLla inyección
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))
​
# Mal ejemplo: vulnerable aSQLataques de inyección
cursor.execute("SELECT * FROM users WHERE username = " + username + " AND password = " + password)

Seguir estos estándares puede ayudarte a escribir código más elegante y robusto.