¿Cómo documento mi código para una revisión de tiempo mínimo? [cerrado]

22

Quiero documentar mi código de tal manera que haya una mínima necesidad de leer y explorar el código nuevamente meses después.

Sé que hay diferentes tipos de documentación (en código fuente y fuera, diagramas de secuencia, etc.).

Solo quiero saber cuál es una manera eficiente de documentar mi código para que, unos meses después, quiera ver mi código, dedique menos tiempo a leer el código y comprender el flujo del código.

Hamed_gibago
fuente
42
El mejor método para pasar menos tiempo leyendo código más adelante es escribir código más claro y más comprensible .
Mael
La documentación depende del objetivo. Si se dirige a desarrolladores, los comentarios en el código serán bastante útiles. Si se dirige a analistas, los diagramas de la descripción general también son útiles. Si se dirige a un público experto en tecnología, haga una guía del usuario.
Laiv
@Laiv Bueno, en vista de un desarrollador de mi propio código y tal vez el código de otros desarrolladores.
Hamed_gibago
Lo más importante es mantener el código pequeño. Si el código necesario para implementar un elemento en su sistema de seguimiento de problemas es grande, entonces su equipo puede necesitar aprender a dividirlo un poco más para que la cantidad de código revisado no sea abrumadora.
Berin Loritsch

Respuestas:

16

Debo admitir que no estoy de acuerdo con algunas de las cosas que recomiendan las otras respuestas, así que voy a tirar mis dos centavos;

Comentarios

La documentación es extremadamente útil para los extraños que leen su código. Por lo general, muchas cosas no serán lo suficientemente detalladas como para ser leídas y entendidas de inmediato, y luego debe explicar lo que está haciendo.

Editar : la discusión en la sección de comentarios ha señalado algo correcto: los comentarios excesivos generalmente se realizan al escribir código incorrecto .

Comentar tu trabajo debe ser preciso y mínimo, pero, en mi opinión, definitivamente debe estar presente. Al menos un comentario por cada 15 líneas de código. Por ejemplo, encima de los bloques en el código, agregue una línea sobre lo que está haciendo:

def login(username: str, password: str, create_session: bool = True):

    # Filter the user we need from the database
    hash = md5(password)
    users = db.table("users", db_entities.USER)
    results = [x for x in users.query(lambda c: c.get("username") == username and c.get("password_hash") == hash)]


    if len(results) == 0:
        return None, None
    else:
        # Create a login session record in the database.
        if create_session:
            sessions = db.table("sessions", db_entities.SESSION)
            ses = sessions.new()
            ses.set("username", username) \
                .set("expiery", 31536000 + time.time())
            sessions.update(ses)
            return results[0], ses
        else:
            return results[0], None

Los comentarios mínimos que explican por qué y qué está haciendo son muy útiles en todo el código. No estoy de acuerdo con la respuesta que dice

Si me encuentro con un código que contiene comentarios, me preparo para lo peor: es probable que el código sea malo y, para ser sincero, es probable que los comentarios también sean malos.

Muchas veces, con gracia, se documenta un buen código. Es cierto que los programadores malos ven su documentación como "Muy bien, mi código es malo, agreguemos algunas oraciones para aclararlo".

Sí, y aunque esto ocurre bastante, también es cierto que los buenos programadores que escriben código limpio también quieren asegurarse de que regresen a su código y entiendan por qué quieren que su función se comporte así, o por qué lo necesitaban. línea que parece un poco redundante, etc.

Sí, los comentarios que explican cosas obvias, los comentarios que no están claros, los comentarios que se reunieron para asegurarse de que "este código está documentado, sí, lo que sea", son olores de código. Hacen que leer el código sea más difícil e irritante. (Añadiendo un ejemplo a continuación)

# Logging into Gmail when the module is imported
_client = login()
def get_client():
    global _client
    return _client

Ejemplo de aclaración: "No hay mierda, Sherlock. ¿Se _client = login()conecta al servicio de correo?

Más aclaraciones: el login()método no tiene relación con el login()método del ejemplo anterior.

Pero los comentarios que coinciden con las normas, explican las de por qué y no el cómo, y responder a las preguntas correctas , son muy, muy ( muy ) votos.

Comentarios en línea

Una cosa que NO debe hacer (y si pudiera escribir más grande, lo haría) es escribir sus comentarios en la misma línea del código. Hace comentarios muy específicos de línea, lo que pierde por completo el propósito de comentar su código.

Por ejemplo, malos comentarios en línea:

outer = MIMEText(details["message"]) # Constructing a new MIMEText object
outer["To"] = details["to"] # Setting message recipient
outer["From"] = "xAI No-Reply" # Setting message sender
outer["Subject"] = details["subject"] # Setting message subject
outer.preamble = "You will not see this in a MIME-aware mail reader.\n" # I don't know what I'm doing here, I copied this from SO.
msg = outer.as_string() # Getting the string of the message
_client = details["client"] # Assigning the client
_client.sendmail(SENDER, details["to"], msg) # Sending the mail

Sería mucho más fácil leer y comprender este código sin los comentarios, que lo hacen desordenado e ilegible.

En cambio, los comentarios dentro de su código deben colocarse sobre los bloques en el código, y deben responder las preguntas importantes que pueden surgir al leer el bloque de código.

# Constructing the email object with the values 
# we received from the parameter of send_mail(details)
outer = MIMEText(details["message"])
outer["To"] = details["to"]
outer["From"] = "xAI No-Reply"
outer["Subject"] = details["subject"]
outer.preamble = "You will not see this in a MIME-aware mail reader.\n"
msg = outer.as_string()

# Sending the mail using the global client (obtained using login())
_client = details["client"]
_client.sendmail(SENDER, details["to"], msg)

Mucho más claro, ¿verdad? Ahora también sabe que debe usar la login()función y proporcionar los parámetros send_mail()con todo lo que usó. Ayuda un poco, pero aún falta una cosa.

Documentación de la función

Ha sido ampliamente discutido. Siempre debe informar a sus lectores de qué se trata su función, por qué y para qué sirve. Cómo lo hace, esto no pertenece a la documentación, sino quizás a las notas al pie de la función.

Debe describir claramente lo que espera que sean sus parámetros, y si desea que se obtengan / creen en un método específico. Debe declarar qué debe devolver su función, cuál es su uso, etc.

Nuevamente, esa es mi opinión y metodología al escribir mi código. No solo esos, sino que son solo algunas de las cosas sobre las que no podría estar de acuerdo con las otras respuestas. Ah, y por supuesto, no solo los comentarios leen su código, sino su propio código. Escriba código limpio, comprensible y mantenible . Piensa en tu futuro mientras codificas ;-)

Salmón Yotam
fuente
55
No está de acuerdo con un ejemplo dado: en lugar de escribir muchos comentarios en una gran función, debe componerlo de muchas funciones más pequeñas con nombres descriptivos, que actuarán como comentarios. Sin riesgo de estar fuera de sincronización con lo que el código realmente está haciendo.
user11153
66
Finalmente algo de cordura. Extraer cada pieza de código que podría usar un comentario en su propia función es cómo terminas con miles de funciones repartidas en cientos de archivos.
user369450
2
Ese segundo ejemplo es encantador.
Lightness compite con Monica el
77
Los comentarios en el segundo ejemplo son demasiado detallados. Algunos de ellos (por ejemplo, "¿Encontramos algo?") Simplemente repiten lo que dice el código y sería mejor eliminarlos. Por otro lado, podría obtener más legibilidad refactorizando, como hacer (stream.is_empty ()) la condición del bucle, o mover la verificación de accept_literals afuera.
Frax
3
@cpburnz, "He tenido que buscar demasiados proyectos heredados y bibliotecas de terceros sin ningún comentario de código para apreciar los comentarios que explican lo que está sucediendo y por qué". exactamente mi punto todo el tiempo: los comentarios están ahí para explicar el código basura. Dado que la pregunta es "¿cómo escribo un código que sea fácil de leer", entonces claramente esta respuesta es incorrecta, ya que se centra en escribir comentarios para explicar el código incorrecto, en lugar de escribir un buen código en primer lugar.
David Arno
55

En mi opinión, la mejor documentación es la documentación que realmente no necesita. También odio escribir documentación y comentarios.

Con eso dicho:

  • Elija nombres legibles y parlantes. No use n, sino en su lugar, numberOfItemsFoundpor ejemplo.
  • No evite almacenar partes de un cálculo en una variable constante en lugar de empujar todo en una línea.
  • Mueva las tareas parciales de las ramas a sus propias funciones (en línea), si las está reutilizando o si la función principal se vuelve larga y tediosa de seguir.
  • Sea más elaborado y solo optimice el código sobre la legibilidad donde realmente se requiera.
Mario
fuente
19
Aquí hay una buena métrica para la documentación (enlace obligatorio).
Neil
44
Esto también debería estar en la lista: explique en código por qué está haciendo las cosas que está haciendo.
t3chb0t
2
+1 para el último elemento de viñeta, ya que la optimización prematura es (en el 97% de las veces) la raíz de todo mal
gmauch
44
numberOfItemsFoundaunque es bastante detallado; demasiado detallado también es un problema.
Matthieu M.
66
@MatthieuM., Rara vez es "demasiado detallado" un problema con los nombres en el código. Sin embargo, demasiado breve o críptico es un problema muy común.
David Arno
25

Trate su código como documentación

Su código es su documentación principal. Describe con precisión lo que realmente hace la aplicación resultante, la biblioteca o lo que sea. Como tal, cualquier intento de acelerar la comprensión de ese código tiene que comenzar con el código mismo.

Hay muchos escritos sobre cómo escribir código legible, pero algunos de los puntos clave son:

  • no confíe en los comentarios para explicar el código incorrecto, mejore el código y deshágase de los comentarios,
  • escribir funciones enfocadas cortas, métodos, clases, etc.
  • usar nombres apropiados para el contexto (por ejemplo, nes bueno para un bucle, se necesitan nombres descriptivos más largos para elementos con mayor alcance),
  • tratar los nombres de funciones como si fueran comentarios, por ejemplo, no usar UpdtTblcon un comentario que explique que actualiza la tabla con las reglas proporcionadas cuando UpdateTableContentsWithSuppliedRulesse puede usar como nombre,
  • Evitar la mutabilidad. Cada vez que cambia el contenido de una variable, aumenta la complejidad del código. Asigne ese nuevo valor a una nueva variable (con un buen nombre) cuando sea factible.
  • Por último, y lo más importante, evite el código "inteligente". El único código inteligente real es el código que es fácil de leer. Si escribes un código complejo y te encuentras pensando "wow, ¿no soy inteligente aquí?", La respuesta es casi segura: "no, no lo eres".

Mejora en la lectura del código

Leer el código, independientemente de lo simple que sea, es una habilidad aprendida. Nadie es naturalmente bueno leyendo el código. Se necesita práctica; mucha práctica Entonces, por ejemplo, vaya a Github o lo que sea y lea el código de las bibliotecas que usa, en lugar de solo usar esas bibliotecas. Encuentra el código para leerlo y leerlo.

Los comentarios son un olor a código

Solo entonces llegamos a otros tipos de documentación. En primer lugar, como se indicó anteriormente, evite los comentarios. Si me encuentro con un código que contiene comentarios, me preparo para lo peor: es probable que el código sea malo y, para ser sincero, es probable que los comentarios también sean malos. Es improbable que alguien que no puede comunicarse bien a través del código pueda comunicarse mejor a través del lenguaje natural.

Cuidado con la documentación de API autogenerada

Además, tenga cuidado con la documentación de API autogenerada. Si tengo que recurrir a la lectura de dichos documentos, será porque su código es muy difícil de leer. Nuevamente, simplifique el código y puedo leerlo directamente.

Las pruebas también son documentos

Las pruebas también son documentación. Así que no trate sus pruebas unitarias como una tarea. Trátelos como una forma de comunicarse con otros (su autoestima de seis meses más tarde incluido aquí) en cuanto a cómo funciona el código y cómo se debe usar.

Haz dibujos si te ayuda

Si te gusta UML, entonces encuentra una buena herramienta y genera diagramas UML a partir de tu código. Simplemente nunca jamás intente usarlo para generar código. No es bueno como herramienta de diseño y, como resultado, terminarás con un código horrible.

Tener un documento de vista de "1000 pies"

Finalmente, escriba un documento de resumen. ¿Qué hace la aplicación? Como lo hace ¿A qué otros sistemas se conecta? Ese tipo de cosas. Sin embargo, no intente describir la estructura del código aquí. Deja que el código haga eso. Deje que este documento le recuerde por qué escribió el código en primer lugar.

David Arno
fuente
14
Estoy de acuerdo con todos sus puntos, excepto que los comentarios tienen su lugar. Si bien estoy de acuerdo en que no tiene sentido comentarios como add 1 to i, los comentarios deberían explicar por qué el código hace lo que hace. Por ejemplo, el código if (!something.Exists()) {...}se puede utilizar un comentario como: // something exists only when (explanation of the broader scenario).
Jonathan
16
Todos hemos visto una buena cantidad de // increment x x++;comentarios que no sirven de nada, pero está mal tirar al bebé con el agua del baño y declarar que los comentarios siempre son malos. Por ejemplo, comentarios del formulario // this case should never happen because xyz throw exception "unreachable".
angrydust
77
Muy buena lista. Pero como @ Jonathan. No estoy de acuerdo con los comentarios. Sin embargo, algunas veces debe tener en cuenta los errores en los marcos de un tercero. Si bien esto se puede refactorizar en su propia función, todavía es bueno dejar un poco de descripción de por qué se requiere la solución (número de error o nombre de error / descripción del error).
magu_
16
@DavidArno Pero no puede hacer eso por un comentario que explica por qué no se hizo algo . Al igual //XXX: Not using straight-forward method Foo here because .... Tales comentarios pueden ser inmensamente valiosos, pero son imposibles de transmitir con código por razones obvias.
cmaster
77
Me gusta aún más dramático: cada comentario es una falla para expresarse bien en código . Por ejemplo, tengo un comentario de 4 líneas en un método, explicando la solución para un error de terceros. No pude expresarlo bien en el código, así que está en un comentario . Yo diría que ha mejorado la legibilidad difícil, porque dudo que alguien pueda disfrutar de desplazamiento horizontal para leer un muy largo y muy nombre del método descriptivo. "Los comentarios son un código de olor" - sí, pero tenemos que recordar que no todo lo que huele es mierda.
R. Schmitz
5

Proporcione una carta de presentación

A menos que esté en un dominio muy técnico, la mayoría de las preguntas sobre el código no serán sobre el "cómo" sino sobre el "por qué" o el "qué".

Como tal, la forma de evitar que las personas tengan que mirar su código es escribir una breve descripción del mismo. La ventaja de esto es que puede compilar una descripción general de las descripciones con bastante facilidad, y que esto es mucho más accesible. (Incluso para las personas que no quieren / no pueden ver el código).

Incluso si las personas son técnicas, la carta de presentación debe ofrecer orientación sobre dónde deberían estar buscando algo.

Puntos simples extremadamente minimalistas:

  1. Introducción, por qué existe este código (base)
  2. ¿Qué función cumple el subconjunto de códigos?
  3. ¿Dónde está el código (nombre del script por ejemplo)

Ejemplo

  1. Este conjunto de scripts raspa StackOverflow y vota las respuestas de Dennis Jaheruddin
  2. a. Este script es responsable de analizar el html y analizar si es el usuario correcto
  3. a. El script se encuentra en: ScrapeAndVote / RecognizeDennis.scr
Dennis Jaheruddin
fuente
1

La mayor ganancia de velocidad que obtengo generalmente al construir confirmaciones separadas, cada una representa un paso intermedio que compila y funciona.

Entonces, si tengo que introducir un nuevo parámetro en una función para implementar una característica específica, entonces hay una confirmación que no hace nada más que agregar el parámetro en la declaración, en la definición y en todos los sitios de llamadas. Luego, la próxima confirmación introduce funcionalidad, y la tercera actualiza los sitios de llamadas que hacen uso de la nueva función.

Esto es fácil de revisar, porque los cambios puramente mecánicos se pueden ver rápidamente y luego apartarse del camino.

Del mismo modo, si reformatea el código, eso siempre debería ser una confirmación por separado.

Simon Richter
fuente
1

Aunque hay uno o dos puntos aparentes de desacuerdo entre las respuestas existentes, aunque solo sea en énfasis, trataré de resumir los consejos habituales de una manera que aclare de dónde vienen todos:

  1. En primer lugar, escriba código limpio; cualquier otra "documentación" se encargará de sí misma después de eso. El código limpio es un conjunto completo de principios para aprender en primer lugar: clases de responsabilidad única, métodos cortos que hacen una cosa, buenos nombres de variables y métodos, mejores nombres de clase / tipo que estos al enfocarse en metáforas (por ejemplo, llame a un MultiButtSupporter a soda), pruebas unitarias para indicar requisitos, SECO, SÓLIDO, un paradigma coherente, etc.
  2. El código revela cómo funciona el código; Los comentarios revelan por qué el código funciona. Por ejemplo, explique un +1 con "evita un error de apagado por 1", o alguna fórmula complicada con "derivado de este libro de texto o página web".
  3. Independientemente de lo que haya estado haciendo con los comentarios, el punto 1 anterior puede lograrlo en código limpio. Vea los comentarios como fallas / males necesarios, o incluso mentiras si con el tiempo no se sincronizan con el código a medida que ambos se editan. Los comentarios no deberían compensar el código mal escrito, porque ¿por qué los comentarios se escribirían con más talento o cuidado que el código?

Por otro lado, si hay algo, probablemente me equivoco demasiado al revés, casi nunca uso comentarios. Sus revisores de código le informarán si tiene el saldo en el lugar equivocado para ellos, pero si hace un esfuerzo consciente para seguir el plan de 3 puntos anterior, probablemente estará cerca de su óptimo de todos modos.

JG
fuente
2
¿En qué se diferencia un comentario de "evita un error de apagado por 1" de un comentario que dice "el +1 no es un error tipográfico" o "No estoy al tanto de los errores de uno en mi programa"? (Los comentarios útiles generalmente se relacionan con algo más grande que +1 en el código fuente, o con algo fuera del código fuente). De modo que todavía queda "derivado en este libro de texto o página web" como un ejemplo válido y realmente excelente en su punto # 2. Luego, su punto # 3 parece sugerir que podría expresar "derivado de este libro de texto o página web" utilizando un código lo suficientemente limpio sin ningún comentario; wow, me gustaría ver eso en acción.
Jirka Hanika
@JirkaHanika Quizás fuera de uno fue un mal ejemplo. En cuanto a 3, lo que quise decir fue "cada uno puede" en lugar de "quizás cada uno"; así que no, no creo que el código solo pueda aclarar tales cosas. (Bueno, podrías probar gaussianFromThisTextbookNamesApproximation como un nombre de variable, ¡pero es una mala idea!)
JG