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