- Por Emmanuel Valverde
- ·
- Publicado 28-feb-2024 0:00:00
Morning routine
Como soy una persona olvidadiza, necesito un método que me ayude a recordar mi rutina matutina. Por eso he creado un programa que, según la hora del..
Con el propósito de practicar TDD, esta es una de las katas más avanzadas que puedes hacer. A estas alturas ya deberías dominar las habilidades básicas de TDD - las 3 Leyes de TDD, la Regla de Tres para la duplicación, y deberías tener experiencia en cómo estructurar una prueba unitaria (Arrange, Act, Assert).
Este ejercicio te permitirá perfeccionar el proceso para la toma de decisiones sobre cómo añadir tests. Si se hace correctamente, deberías poder hacer evolucionar el algoritmo dando pasos muy pequeños.
Hacerlo de esta manera es una forma segura de codificar: si das un paso equivocado, es más fácil revertirlo en tu software de control de versiones y empezar de nuevo. El "coste" de hacer esto es mínimo y, por lo general, es más fácil retroceder y replantearse las cosas que dedicar tiempo a depurar el código para averiguar en qué ha fallado. Los desarrolladores que dominan TDD generalmente pasan mucho menos tiempo depurando (debugging) código que simplemente deshaciendo sus cambios recientes y probando con otra estrategia.
El rápido feedback que se obtiene de un pequeño cambio significa que se puede reaccionar inmediatamente, en lugar de enfrentarse a un problema que se introdujo en algún momento anterior, donde los cambios subsiguientes anteriores a la detección del problema pueden dificultar su aislamiento. Con progresiones pequeñas, si se rompe algo debería ser muy fácil aislar dónde se ha ido mal.
Lo recomendable es que apoyes tus decisiones de progresar usando una heurística como la Premisa de Prioridad de Transformación (TPP) (ver la sección "Artículos" más abajo). Se trata de un enfoque desarrollado por Robert C. Martin (Uncle Bob) para facilitar el TDD.
Las transformaciones se definen mejor si se comparan con las refactorizaciones. Las refactorizaciones son cambios en el código que NO cambian su comportamiento. Las transformaciones son cambios en el código que SÍ cambian el comportamiento del código, pero en el contexto de TDD son cambios que permiten que el test (actual) que está fallando pase. Es decir, es código que se escribe para que el código pase de Rojo a Verde.
En física, la Segunda Ley de la Termodinámica define una flecha de progresión donde la entropía se mueve de menos a más. En TDD, hay una flecha de dirección donde las pruebas progresan de más específicas a más genéricas. Al definir las reglas de Premisa de Prioridad de Transformación, Uncle Bob ha definido una serie de transformaciones en orden. Las transformaciones que encabezan la lista son las más sencillas. Se vuelven progresivamente más complejas a medida que descendemos en la lista. Al hacer referencia y aplicar estos tipos de transformación, puedes hacer que tu conjunto de pruebas pase de ser específico a ser más genérico de forma lenta e incremental.
Este es un gran ejercicio para practicar el diseño de algoritmos dirigido por pruebas porque puedes empezar a familiarizarte con el uso de transformaciones para avanzar, pero al mismo tiempo la dirección del viaje no es completamente desconocida. Las reglas para los números romanos (ver más abajo) sugerirían una estrategia básica, pero puedes intentar usar TPP para ayudarte a elegir el siguiente paso.
Es relativamente fácil saber cuál es el siguiente paso, pero el objetivo del ejercicio es intentar que el TPP confirme tus pasos al avanzar. Se aconseja hacer esta kata primero eligiendo tus propios movimientos sin ayuda, y luego repitiéndola usando el TPP para guiarte.
Escribe un programa para convertir números arábigos en sus números romanos equivalentes.
Los romanos escribían sus números utilizando combinaciones de las siguientes letras:
Number | Numeral |
---|---|
1 | I |
5 | V |
10 | X |
50 | L |
100 | C |
500 | D |
1000 | M |
Inicialmente, el sistema de números romanos consistía en expresar el número mediante el símbolo más apropiado que pudiera utilizarse.
Para empezar, para los números del 1 al 4, se utilizaba el símbolo "I" en los múltiplos para representar el número:
Number | Numeral |
---|---|
1 | I |
2 | II |
3 | III |
4 | IV |
Cuando los números llegaban a 5, utilizábamos la 'V', ya que este símbolo era la forma más eficaz de representar el número.
Número | Numeral |
---|---|
5 | V |
Para los enteros sencillos superiores a 5, entró en vigor una nueva regla: cuando se añaden símbolos "menores" una o más veces detrás del símbolo "mayor", se considera que se añade al valor que representa el símbolo mayor.
Número | Numeral |
---|---|
6 | VI |
7 | VII |
8 | VIII |
9 | VIIII |
So, the initial sequence of Roman Numerals for the integers 1 - 9 were as follows:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|
I | II | III | IIII | V | VI | VII | VIII | VIIII |
Sin embargo, como habrás notado, los números para el 4 y el 9 no están bien. Pero la formación original de los numerales era ésta (incluso algunas esferas de reloj siguen mostrando IIII para el 4). Pero esto creó problemas, ya que la gente seguía confundiendo el III con el IIII y el VIII con el VIIII, por lo que se desarrolló una regla adicional.
Para números como el 4 y el 9, el símbolo menor (I) se antepone al símbolo mayor (V o 5 para el número 4, y X que representa el 10 para el número 9). Cuando el símbolo menor aparece antes del mayor, se considera restado del mayor.
Así, 'IV' se evalúa como: V - I = 5 - 1 = 4 y 'IX' se evalúa como: X - I = 10 - 1 = 9
Por lo tanto, la lista de números romanos del 1 al 9 se modifica como sigue:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|
I | II | III | IV | V | VI | VII | VIII | IX |
Dado que los números romanos siguen un sistema de notación decimal, se aplican las mismas reglas para el siguiente orden: unidades de 10. En este caso, utiliza los símbolos "X" para 10, "L" para cincuenta y "C" para cien.
10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 |
---|---|---|---|---|---|---|---|---|
X | XX | XXX | XL | L | LX | LXX | LXXX | XC |
Para el siguiente orden decimal, utilice las mismas reglas con "C" para 100, "D" para 500 y "M" para 1000.
100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 |
---|---|---|---|---|---|---|---|---|
C | CC | CCC | CD | D | DC | DCC | DCCC | CM |
(Como no hay símbolos superiores a "M" (1000), el patrón se detiene aquí, y normalmente los números romanos no consideran números superiores a unos pocos miles).
Los numerales siguen ciertas reglas que deben respetarse:
Los símbolos de "base 1" ("I", "X", "C", "M") pueden restarse del siguiente símbolo más alto de "base 5" ("V", "L", "D") o de "base 1", pero sólo se permite una vez. El símbolo no se puede anteponer a un símbolo que esté en el orden decimal inmediatamente superior. Por lo tanto, "IV", "IX" está bien, pero "IL" o "IC" no lo están. XL" y "XC" son válidos, pero XD y XM no ("CD" y "CM" también son válidos).
Los símbolos "I" y "X" pueden repetirse como máximo 3 veces seguidas cuando se añade el símbolo.
Los símbolos "V", "L" y "D" de "base 5" no pueden repetirse nunca.
Más ejemplos:
Número | Numeral |
---|---|
4 | IV |
9 | IX |
29 | XXIX |
80 | LXXX |
294 | CCXCIV |
2019 | MMXIX |
Tu solución debería contener un método similar a:
public string Convert(int amount)
Aquí, amount representa el número arábigo y el valor que devuelve este método es la cadena de números romanos.
Como soy una persona olvidadiza, necesito un método que me ayude a recordar mi rutina matutina. Por eso he creado un programa que, según la hora del..
Historia: Durance ha encontrado un libro de magia en una de sus aventuras y ha decidido aprender a encantar sus armas. Debido a la naturaleza..
Resumen Esta kata es bastante avanzada, por lo que recomendamos que intentes resolverla una vez que hayas practicado TDD con otras katas más fáciles.
Suscríbete a nuestra newsletter para que podamos hacerte llegar recomendaciones de expertos y casos prácticos inspiradores