Convertidor y comparador de horas
Escriba dos programas, uno que convierte y otro que compara horas. El código común entre ellos debe reutilizarlo en una biblioteca de código que podría ser utilizada por terceros.
Programa convertidor
El programa convertidor recibe en la primera línea la convención de reloj a la que se quiere convertir (convención destino), que puede ser la palabra 24h
o 12h
. Cualquier otra palabra hará que el programa finalice con el mensaje de error invalid convention
.
Después de una línea en blanco vendrán varias horas, una por línea en la convención complementaria a la indicada en la primera línea. Por ejemplo, si en la primera línea se indicó 12h
, todas las horas en la entrada deberán estar en convención de reloj de 24 horas. Si una hora no respeta esta restricción, el programa no deberá convertir la hora sino reportar el texto invalid hour
y continuar procesando más líneas. También se debe reportar este mensaje para horas incorrectas o que no sean horas del todo. Líneas vacías deben ser ignoradas sin efecto en la salida del programa.
24h
11:59am
11:59:59pm
3:5pm
0:0:0am
00:00PM
12:00AM
12:00PM
59:59AM
18:90PM
Output example:
11:59:00
23:59:59
15:05:00
invalid hour
invalid hour
00:00:00
12:00:00
invalid hour
invalid hour
Programa comparador
El programa comparador recibe varias líneas, cada una con dos horas separadas entre sí por un espacio en blanco. Cada una de las horas puede estar en cualquiera de las dos convenciones de reloj permitidas (reloj de 12 horas y reloj de 24 horas). El programa comparará ambas horas de la línea y las imprimirá en una línea de la salida estándar, separadas por uno de los siguientes caracteres:
|
Ambas horas son iguales |
|
La primera hora ocurre antes que la segunda hora |
|
La primera hora ocurre después que la segunda hora |
Si una hora no respeta las convenciones de reloj permitidas, el programa reportará invalid hour
y continuará procesando más líneas. Líneas vacías deben ser ignoradas sin efecto en la salida del programa.
11:59pm 23:59:00
15:05:01 3:5pm
0:0:0 12:00AM
24:00 12:00PM
1:15 13:15:00
00:00am 00:00
Output example:
11:59:00pm = 23:59:00
15:05:01 > 03:05:00pm
00:00:00 = 12:00:0am
invalid hour
01:15:00 < 13:15:00
invalid hour
Biblioteca de horas
La biblioteca de horas dispondrá del código común entre el programa convertidor y el comparador que puede ser reutilizado por programas de otras personas. Aproveche este reto para potenciar sus habilidades para crear código de muy alta calidad, como lo haría si fuese una biblioteca que va a vender a potenciales clientes. La biblioteca tendrá subrutinas para realizar tareas como la siguiente lista no exhaustiva:
-
Representar una hora en un registro de memoria e inicializarla.
-
Cargar o leer una hora a partir de una cadena de caracteres, o indicar si el texto no contiene una hora válida. Si no se proveen segundos, suponga
00
, pero las horas y minutos son obligatorios. Sugerencia: indague sobresscanf()
. -
Escribir una hora en una cadena de caracteres en formato
HH:MM:SS
. Si la hora está en reloj de 12 horas, agregue el textoam
opm
inmediatamente después de los segundos. Sugerencia: indague sobresprintf()
. -
Indicar si un registro de hora es válido o no.
-
Convertir de un registro hora en formato 12-horas a 24-horas y viceversa, sólo si es válido.
-
Comparar dos registros de hora para saber si son iguales, o cuál ocurre antes o después que la otra, sólo si los registros son válidos.
Su biblioteca debe estar bien documentada. Piense que esta documentación será lo que dispongan sus clientes para poder aprender y usarla efectivamente. Además de documentar la interfaz de cada subrutina, provea ejemplos de invocación de ellas, ejemplos de uso de la biblioteca, y una página principal.
Su biblioteca debe estar bien probada. Si el código de sus clientes falla por una pulga en su biblioteca, tendrá consecuencias muy graves en el prestigio y confianza. Pruebe cada subrutina escogiendo casos bien estratégicos e implementándolos en un programa de pruebas en C++ con ayuda del framework de Google Test.
Cuando se compile su biblioteca, debe producir una versión estática (archivo .a
) de la misma y una versión dinámica (archivo .so
), de tal forma que sus clientes puedan decidir cuál de las dos utilizan. Haga que una de sus aplicaciones (el convertidor o el comparador de horas) use la biblioteca estática y la otra aplicación la biblioteca dinámica. Provea alguna forma automatizada de construir la biblioteca como las aplicaciones (ej.: make files).
Argumentos de línea de comandos [opcional]
Tanto el programa convertidor como el comparador leen horas de la entrada estándar e imprimen resultados en la salida estándar si se invocan sin argumentos de línea de comandos. Permita a los usuarios de sus programas proveer horas como argumentos. En el siguiente ejemplo se pide al programa convertir las tres horas dadas en argumentos a la convención de 12-horas:
$ bin/hour_convert 12h 20:45 0:5:8 una-p.m
08:45:00pm
12:05:08am
error: could not open una-p.m
Si un argumento no tiene formato de hora, el programa trata de abrirlo como un archivo de texto con horas, y procesarlo como si los datos se hubieran provisto en la entrada estándar. Si se proveen varios archivos, el programa los procesa todos en el mismo orden en que fueron provistos.
Los programas reportan todas sus conversiones o comparaciones a la salida estándar, a menos de que el usuario provea la opción -o
seguida por el nombre de un archivo. En tal caso, el programa escribe las conversiones y comparaciones a un archivo de texto con el nombre provisto. Si ya existe un archivo con ese nombre, será sobrescrito. Por ejemplo:
$ bin/hour_compare h1.txt 12:12 12:12am h2.txt -o h3.txt
En la invocación anterior, el programa comparará todas las parejas de horas que se encuentren en el archivo h1.txt
, luego compara las dos horas provistas en los siguientes dos argumentos (12:12:00 = 12:12:00am
), finalmente compara todas las horas que se encuentren en el archivo h2.txt
. El resultado no es reportado en la salida estándar, sino en el archivo h3.txt
.
Evaluación
Esta se una evaluación individual. Presente su solución en su repositorio privado de control de versiones, que incluye:
General:
-
[5%] Buen uso de control de versiones (commits, ignores). Una estructura ordenada del proyecto en directorios y archivos.
Makefile
general que corre reglas en los demás. -
[5%] Documento de análisis en un archivo
readme
(con notación AsciiDoc o Markdown) general con el problema a resolver, índice de los módulos que componen la solución (enlaces a los otrosreadme
), manual de cómo construir la solución, y autor. -
[10%] Apego a una convención de estilos (linting) de todo el código fuente en C/C++.
Biblioteca de horas:
-
[10%] Diseño en pseudocódigo de la biblioteca.
-
[10%] Casos de prueba de cada subrutina de la biblioteca y programa de pruebas con Google Test.
-
[10%] Documentación de interfaces (Doxygen): propósito, parámetros, supuestos (contratos). Página principal de la biblioteca. Archivo de extracción de documentación (
Doxyfile
). Documentación de implementaciones: comentarios en los cuerpos de subrutinas de lo que no es trivial. -
[10%] Implementación correcta de cada subrutina de la biblioteca.
-
[5%] Compila de forma automática (
Makefile
) la biblioteca de forma estática (.a
) y dinámica (.so
).
Programa convertidor y programa comparador de horas:
-
[10%] En un documento de análisis (
readme
) explica el problema que resuelve el programa, y provee un manual de uso con ejemplos. -
[10%] Crea nuevos casos de prueba de caja negra para cada aplicación. Recuerde crear pocos casos, pero que sean estratégicos y representativos. Puede reutilizar casos de prueba de la biblioteca.
-
[10%] Implementa la lógica de cada programa y reutiliza la biblioteca de horas para lograr su propósito.
-
[5%] Compila de forma automática (
Makefile
) cada programa. En uno incluye la biblioteca de forma estática y en otro de forma dinámica. Permite probar la aplicación contra los casos de prueba de caja negra. -
[+10% opcional] Procesa horas provistas en argumento de línea de comandos o archivos con horas. Escribe la salida en un archivo con la opción
-o
.
Fecha límite de entrega: lunes 13 mayo a las 23:59, en el repositorio personal de control de versiones.