¿Qué hacer si el código no funciona?

Este artículo discutirá las diferentes rutas que uno podría tomar si su código no funciona en varios escenarios.

Si uno, aparentemente al menos, ha codificado todo a la perfección, ha probado soluciones en los casos de prueba incluidos en las declaraciones, pero después de enviar el código al sistema falla en la prueba y no hay códigos de error explícitos para ayudar a identificar y resolver el problema. . Este problema puede deberse a una gran cantidad de razones, pero generalmente es una de las siguientes:

Aunque el enfoque puede diferir según el motivo, generalmente se pueden seguir los pasos a continuación:

  • Compruebe los casos extremos : por ejemplo, si N = 1 o n es el número máximo posible que satisface las restricciones. Compruebe si el programa se comporta correctamente dada la entrada que golpea las restricciones en todos los sentidos posibles.
  • Genere algunos casos de prueba generales: para los que sepa la respuesta correcta. No mire la respuesta del código para estas pruebas antes de averiguar cuál debería ser la respuesta con lápiz y papel. De lo contrario, es fácil convencerse de que es correcto y dejar de ver algún error tonto.
  • El límite de tiempo excedió el error , midiendo cuánto tiempo funciona el programa para las entradas más grandes. Las siguientes funciones ayudan a medir el tiempo de CPU desde el inicio del programa:
    • C++ (doble) reloj() / RELOJES POR SEGUNDO con tiempo incluido.
    • python time.clock() devuelve un valor de coma flotante en segundos.
    • Java System.nanoTime() devuelve valores largos en nanosegundos.

Mida el tiempo para pruebas pequeñas, pruebas medianas y pruebas grandes. Se puede encontrar uno de los siguientes resultados posibles:

  • El programa funciona para pruebas pequeñas y medianas en el tiempo, pero es más de 10 veces más lento de lo necesario (o se cuelga para las pruebas grandes). En ese caso, el programa probablemente tenga problemas de complejidad y podríamos intentar resolver el problema usando las siguientes opciones:
    • Mida el tiempo que toman las partes del programa por separado. Por ejemplo, cuánto tiempo lleva leer la entrada/imprimir la salida).
    • Calcule el número real de operaciones que hacen su algoritmo y sus partes y vea si es lo esperado.
    • Compruebe si se han pasado referencias a funciones que solo se aplican a C++ , en Java y en Python . Siempre está referenciado).
  • El programa depende de una prueba pequeña o mediana. Compruebe si hay un bucle infinito/recursión. Agregue afirmaciones (afirmar en c ++, python y java) en condiciones previas y posteriores de bucles y funciones y vea si fallan. Use la salida de depuración/depurador para ver qué ruta de código conduce al bloqueo.
  • Si se trata de un error de tiempo de ejecución , el mensaje podría ser una señal desconocida, entonces podría ser una buena señal. Es una de las razones más informativas que significa que el programa podría bloquearse debido a uno de los siguientes factores:
    • Se accede a una ubicación en la memoria que no pertenece al programa. En C++, puede tomar dos formas: intentar acceder a un elemento inexistente de una array, intentar evaluar un puntero nulo o un puntero que apunta a una ubicación que no pertenece al programa.
    • Cometer un error aritmético : división por cero , desbordamiento de un número de coma flotante , etc.
    • (Específico de C++) Se excedió el tamaño de la pila, lo que puede deberse a una recurrencia infinita o a la creación de un objeto grande (como una array) dentro de una función.

Genere diferentes pruebas y ejecute su programa contra ellas hasta que falle:

  • La razón de la ‘respuesta incorrecta’ es probablemente la más desafiante; muchas cosas pueden conducir a ello. Para encontrar una prueba fallida, se puede hacer una de las siguientes cosas:
    • Encuentre una solución alternativa que puede no ser correcta en términos de eficiencia (y algunos casos ni siquiera funcionan para algunos tipos de pruebas), pero que podría usarse para verificar si la respuesta de la solución principal es correcta.
    • Haga que el programa se bloquee si algo es inconsistente. Eso significa agregar aserciones para condiciones posteriores y previas de sus funciones y bucles.

Cómo generar pruebas: La forma más sencilla de generar una prueba es escribir un programa que imprima una prueba en un archivo de texto. A continuación se muestra un ejemplo para ilustrar lo mismo:

Programa 1: Generando una prueba para el par máximo distinto:

Python3

import sys
n = int(sys.argv[1])
print(n)
print(' '.join([str(i∗2)for i in range(n)])

Lo más críptico aquí es probablemente sys.argv[1]. Este es un getter para el primer argumento de la línea de comandos. Ahora, ¿cómo usar esto para ejecutar el programa? Copie el archivo ejecutable o una secuencia de comandos de python en el mismo directorio que la secuencia de comandos de generación y ejecute los siguientes comandos:

python script.py 17 > input.txt
./your_program_name < input.txt

Se recomienda el uso de Python3 sobre Python. Podría ayudar a resolver los problemas en algunos casos. Por lo tanto, algunas pruebas pueden generarse automáticamente y el programa puede ejecutarse contra ellas, pero las siguientes preguntas quedan sin respuesta:

  • ¿Cómo aleatorizar las pruebas?
  • ¿Cómo generar muchos de ellos?
  • ¿Cómo comprobar las respuestas?

Generar pruebas aleatorias y ejecutar su programa sobre ellas: Se puede utilizar la siguiente técnica que consta de 3 partes:

  • Generador de pruebas que acepta una semilla como parámetro de línea de comandos, como se explicó en el Programa 2.
  • Una solución alternativa.
  • Un script que genera repetidamente una prueba con el generador de (1) ejecuta tanto la solución principal como la solución modelo en la prueba generada y verifica si las respuestas coinciden en el programa 2 o no.

Programa 2: Generador que acepta una semilla desde la línea de comando:

Python3

import random
import sys
  
# Input the number N
n = int(sys.argv[1])
myseed = int(sys.argv[2])
random.seed(myseed)
  
print(n)
  
# 1000 could also be moved to
# parameters instead of making it
# a hard constant in the code
print(' '.join([str(random.randint(1, 1000)) for i in range(n)])

Programa 3: El guión real:

Python3

import random
import sys
import os
  
# Accept the number of tests as a
# command line parameter
  
tests = int(sys.argv[1])
  
# Accept the parameter for the
# tests as a command line parameter
  
n = int(sys.argv[2])
for i in range(tests):
    print("Test #" + str(i))
  
    # Run the generator gen.py with
    # parameter n and the seed i
os.system("python3 gen.py " + str(n) + " " + str(i) + " > input.txt")
  
# Run the model solution model.py
# Notice that it is not necessary
# that solution is implemented in
# python, you can as well run
# ./model < input.txt > model.txt
# for a C++ solution.
  
os.system("python3 model.py < input.txt > model.txt")
  
# Run the main solution
  
os.system("python3 main.py < input.txt > main.txt")
  
# Read the output of the
# model solution
  
with open('model.txt') as f:
    model = f.read()
print("Model: ", model)
  
# Read the output of the
# main solution :
  
with open('main.txt') as f:
    main = f.read()
print("Main: ", main)
if model != main:
    break

Cómo agregar afirmaciones: en Java, Python y C++ afirmar expresión, afirmar expresión y afirmar (expresión); respectivamente, producirá un error de tiempo de ejecución si la expresión booleana es falsa. Un posible uso de las aserciones es verificar que la respuesta al programa sea consistente. Otro caso de uso común es verificar que los pasos intermedios del programa sean consistentes.

Publicación traducida automáticamente

Artículo escrito por mittalashwin y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *