Pruebas:
#!/usr/bin/env python import unittest from strcalc import calc def expected(exception): def argcatcher(f): def wrapper(self, *args): self.assertRaises(exception, lambda: f(self, *args)) return wrapper return argcatcher class StringCalcTest(unittest.TestCase): def testEmptyString(self): self.assertEquals(0, add("")) def testOneNumberString(self): self.assertEquals(2, add("2")) def testTwoNumberString(self): self.assertEquals(7, add("2,5")) def testThreeNumberString(self): self.assertEquals(15, add("2,5,8")) def testThreeNumberStringNewLine(self): self.assertEquals(15, add("2,5\n8")) def testEmptyStringWithUserSeparator(self): self.assertEquals(0, add("//;\n")) def testOneNumberStringWithUserSeparator(self): self.assertEquals(2, add("//;\n2")) def testTwoNumberStringWithUserSeparator(self): self.assertEquals(7, add("///\n2/5")) def testThreeNumberStringWithUserSeparator(self): self.assertEquals(15, add("//#\n2#5#8")) def testThreeNumberStringNewLineAndUserSeparator(self): self.assertEquals(15, add("//!\n2!5\n8")) @expected(ValueError) def testNegativesNotAllowed(self): add("2,-1") @expected(ValueError) def testNegativesNotAllowedWithUserSeparator(self): add("//&\n2&-1") def testIgnoreGreaterThan1000(self): self.assertEquals(1, add("1\n1001")) def testIgnoreGreaterThan1000WithUserSeparator(self): self.assertEquals(8, add("//$\n1\n1002$3$4$1005")) if __name__ == '__main__': unittest.main()
Código:
#!/usr/bin/env python def parse(s): return int(s) if s else 0 def tonums(lines, sep=','): return [parse(part) for line in lines for part in line.split(sep)] def config(s): lines = s.split() if lines and lines[0].startswith('//'): return lines[1:], lines[0][2:] return lines, ',' def add(s): lines, sep = config(s) nums = tonums(lines, sep) negatives = [n for n in nums if n < 0] if negatives: raise ValueError('No se permiten negativos: %r' % negatives) return sum(n for n in nums if n <= 1000)
Al igual que en el caso de +Alcides Flores Pineda y +rodrigo salado anaya , el presente código no implementa el requerimiento de separadores de longitud arbitraria.
El código resultante es más largo que la versión en scheme/kawa, en algunos casos por la verbosidad propia de las comprensiones y generadores de Python, y en otras por las diferencias propias de la implementación, más que por cuestiones sintácticas.
A mi en lo particular me resulta muy ilustrativo ver las diferentes respuestas que se han generado para la misma kata en diversos lenguajes o incluso de personas distintas usando el mismo lenguaje.
La siguiente parte del ejercicio es: ejecutarlo en 15 o menos minutos todos los días por una semana y al cabo de ese tiempo, reflexionar:
- ¿Mi solución a la kata está evolucionando cada vez que la ejecuto o por el contrario, repito los mismos pasos "como periquito"?
- ¿Puedo encontrar alguna forma más elegante/clara/eficiente de resolver el problema o alguna parte de el mismo?
- ¿Si la primera vez resolví el problema de forma, digamos, procedural, puedo intentar una solución orientada a objetos?, ¿funcional?
- ¿Qué ventajas/desventajas tendrían dichas soluciones?
Saludos