El Blog de Ana Buigues » Desarrollo http://anabuigues.com Wed, 07 Dec 2011 16:07:47 +0000 es-ES hourly 1 http://wordpress.org/?v=3.4 Apache Barcamp Spain 2011, ¿te lo vas a perder? http://anabuigues.com/2011/09/03/apache-barcamp-spain-2011-%c2%bfte-lo-vas-a-perder/ http://anabuigues.com/2011/09/03/apache-barcamp-spain-2011-%c2%bfte-lo-vas-a-perder/#comments Sat, 03 Sep 2011 18:58:28 +0000 Ana Buigues http://anabuigues.com/?p=3626 Por si alguien no se ha enterado todavía, el 8 de octubre de 2011, se celebrará en Sevilla la Apache Barcamp Spain. Un evento creado por desarrolladores para desarrolladores, en formato Open Space y por si fuese poco, gratuito.

Cualquiera puede proponer su charla y entre todos los asistentes votaran las que crean más interesantes para componer el panel final de sesiones, y no solamente se limita a frameworks, tecnologías y productos de Apache, se espera que haya talleres introductorios y especializados de todo tipo de lenguajes como: Ruby, .NET, Python, Java, Scala, Groovy, Lisp JavaScript o HTML5,  soluciones prácticas y debates teóricos sobre escalabilidad y concurrencia, esto promete!

La idea del evento es compartir con otros, aprender de otros y divertirte con todos! así que no te lo puedes perder.

Además Atlassian patrocinará la fiesta de despedida, invitando a todos los asistentes al acabar con un cargamento de cerveza y tapas gratis después del largo día de sesiones.

Podéis seguir el evento desde  la página web,  la cuenta de twitter, la lista de correo y hasta tiene su  propio lanyrd. También podéis ayudar a su difusión sumandoos a la campaña de ¡Yo también voy!

]]>
http://anabuigues.com/2011/09/03/apache-barcamp-spain-2011-%c2%bfte-lo-vas-a-perder/feed/ 6
Code Kata – FizzBuzz http://anabuigues.com/2011/03/31/code-kata-fizzbuzz/ http://anabuigues.com/2011/03/31/code-kata-fizzbuzz/#comments Thu, 31 Mar 2011 16:41:59 +0000 Ana Buigues http://anabuigues.com/?p=3437 Siguiendo con la iniciativa de 12meses12katas paso a contaros el desafío de este mes, en si el problema es muy muy sencillo, la idea es la siguiente:  para el intervalo de números entre 1 y 100, si uno de ellos resulta múltiplo de 3 o contiene un 3, el resultado debe ser la palabra “Fizz”, si el número es múltiplo de 5 o contiene un 5, el resultado debe ser la palabra “Buzz”, si el número es múltiplo tanto de 3 como de 5, el resultado debe ser “FizzBuzz”. ¿Sencillo verdad?

Bueno, nos ponemos a ello, este mes he decidio realizarla en Javascript, ya que nunca he realizado TDD sobre Javascript y tenía mucha curiosidad. Así que lo primero fué investigar que frameworks hay disponibles y para mi asombro he visto que hay muchos! como por ejemplo QUnit, jqUnit, JsUnit, YUI Test, JSTestDriver, Jspec, Inspect, Jasmine etc… yo me he decantado por Jasmine, ya que es muy sencillito de utilizar, su sintaxis es muy clara y apenas requiere configuración. Además tiene una interfaz para mostrar el resultado de los test, la podeís ver al final del post.

Como siempre recomendaros que os paséis por github del proyecto para ver las distintas soluciones que están aportando a la iniciativa.

A continuación os dejo el código de la kata

function FizzBuzz() {
};
FizzBuzz.prototype.fizz = "Fizz";
FizzBuzz.prototype.buzz = "Buzz";
FizzBuzz.prototype.say = function(number) {
 var result = "";
 if (this.isMultipleOfThree(number) || this.containsTree(number))
 result += this.fizz;
 if (this.isMultipleOfFive(number) || this.containsFive(number))
 result += this.buzz;
 if (result.length == 0)
 result += number;
 return result;
};
FizzBuzz.prototype.isMultipleOfThree = function(number) {
 return number % 3 === 0;
};
FizzBuzz.prototype.isMultipleOfFive = function(number) {
 return number % 5 === 0;
};
FizzBuzz.prototype.containsTree = function(number) {
 return number.toString().indexOf('3') != -1;
};
FizzBuzz.prototype.containsFive = function(number) {
 return number.toString().indexOf('5') != -1;
};

Los tests realizados con Jasmine

describe("FizzBuzz", function() {
 var fizzBuzz;
 beforeEach(function() {
 fizzBuzz = new FizzBuzz();
 });
 it('should return number', function() {
 expect(fizzBuzz.say(2)).toEqual('2');
 expect(fizzBuzz.say(4)).toEqual('4');
 expect(fizzBuzz.say(7)).toEqual('7');
 expect(fizzBuzz.say(19)).toEqual('19');
 });
 it('should return Fizz', function() {
 expect(fizzBuzz.say(3)).toEqual('Fizz');
 expect(fizzBuzz.say(13)).toEqual('Fizz');
 expect(fizzBuzz.say(18)).toEqual('Fizz');
 expect(fizzBuzz.say(96)).toEqual('Fizz');
 });
 it('should return Buzz', function() {
 expect(fizzBuzz.say(5)).toEqual('Buzz');
 expect(fizzBuzz.say(20)).toEqual('Buzz');
 expect(fizzBuzz.say(95)).toEqual('Buzz');
 expect(fizzBuzz.say(100)).toEqual('Buzz');
 });
 it('should return FizzBuzz', function() {
 expect(fizzBuzz.say(15)).toEqual('FizzBuzz');
 expect(fizzBuzz.say(35)).toEqual('FizzBuzz');
 expect(fizzBuzz.say(54)).toEqual('FizzBuzz');
 expect(fizzBuzz.say(75)).toEqual('FizzBuzz');
 expect(fizzBuzz.say(90)).toEqual('FizzBuzz');
 });
});

Aquí os muestro la interfaz que nos ofrece Jasmine para ver el resultado del los test:

]]>
http://anabuigues.com/2011/03/31/code-kata-fizzbuzz/feed/ 7
Code Kata – RomanNumerals http://anabuigues.com/2011/02/15/code-kata-febrero-romannumerals/ http://anabuigues.com/2011/02/15/code-kata-febrero-romannumerals/#comments Tue, 15 Feb 2011 21:49:25 +0000 Ana Buigues http://anabuigues.com/?p=3391 Siguiendo con la iniciativa lanzada por 12meses12katas en la que ya participé el mes pasado realizando mi primera code kata, este mes sigo experimentando en el mundo de las katas. Recomiendo a todo programador, que si tiene un poco de tiempo (las katas se realizan en un tiempo máximo de 2 horas) que prueben la experiencia, ya que estos ejercicios te permiten mejorar la técnica de desarrollo, aplicando TDD, que implica escribir los tests primero, provocar un fallo, implementar la corrección del fallo y refactorizar.

La kata de este mes trata de resolver el problema de las conversiones entre números enteros y romanos.  Para hacer que la kata sea un reto mayor, he decido resolverla en Python que representa un poco más de dificultad que si la realizase en Java, ya que estoy más acostumbrada a programar en Java, En Python soy una principiante,  por lo que seguramente el código escrito para solucionar la kata se podría mejorar, así que sí veís algún fallo no dudeís en comentarlo!

Podeís ver las distintas soluciones que estan aportando a la iniciativa desde el github del proyecto. Os aconsejo que os paseís por ahi para ver la multitud de soluciones que se pueden dar a un mismo problema y la diversidad de lenguajes de programación con la que se resuelven.

A continuación os dejo el código de la kata

class RomanNumerals(object):
    def __init__(self):
        #inicializaciones para la conversión de entero a romano
        self.values =[ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ]
        self.symbols =[ "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" ]
        #inicializaciones para la conversión de romano a entero
        self.value =[ 1000, 500, 100, 50, 10, 5, 1 ]
        self.symbol = "MDCLXVI";
    def intToRoman(self, num):
        '''
            Realiza la conversión de un número entero a romano.
        '''
        output = ""
        index = 0
        #finalizamos cuando el número es 0
        while num > 0:
            while num >= self.values[index]:
                #añadimos el símbolo a la solución
                output = output + self.symbols[index]
                #restamos el valor númerico
                num = num - self.values[index]
            index = index + 1
        return output
    def romanToInt(self, num):
        '''
            Realiza la conversión de un número romano a entero
        '''
        indexSymbol = 0
        output = 0
        index = 0
        valid = True
        lastValue = 0
        while valid and index < len(num):
            #obtenemos el símbolo
            car = num[index]
            #obtenemos el índice del símbolo
            indexSymbol = self.symbol.index(car)
            if(indexSymbol >= 0):
                #sumamos su valor correspondiente
                output = output + self.value[indexSymbol]
                # si el valor es mayor que el último valor, tenemos que restar el último valor sumado
                if self.value[indexSymbol] > lastValue:
                    output = output - 2 * lastValue
                lastValue = self.value[indexSymbol]
            else:
                valid = False
            index = index + 1
        return output

Con su correspondiente test

import unittest
from RomanNumerals import RomanNumerals
class Test(unittest.TestCase):
    def setUp(self):
        self.roman = RomanNumerals()
    def testSimple(self):
        self.checkConversion(1,"I")
        self.checkConversion(4,"IV")
        self.checkConversion(5,"V")
        self.checkConversion(9,"IX")
        self.checkConversion(10,"X")
        self.checkConversion(40,"XL")
        self.checkConversion(50,"L")
        self.checkConversion(90,"XC")
        self.checkConversion(100,"C")
        self.checkConversion(400,"CD")
        self.checkConversion(500,"D")
        self.checkConversion(900,"CM")
        self.checkConversion(1000,"M")
    def testTens(self):
        self.checkConversion(11,"XI")
        self.checkConversion(12,"XII")
        self.checkConversion(13,"XIII")
        self.checkConversion(14,"XIV")
        self.checkConversion(19,"XIX")
        self.checkConversion(20,"XX")
        self.checkConversion(24,"XXIV")
        self.checkConversion(31,"XXXI")
        self.checkConversion(38,"XXXVIII")
        self.checkConversion(45,"XLV")
        self.checkConversion(71,"LXXI")
        self.checkConversion(87,"LXXXVII")
        self.checkConversion(99,"XCIX")
    def testHundreds(self):
        self.checkConversion(109,"CIX")
        self.checkConversion(203,"CCIII")
        self.checkConversion(303,"CCCIII")
        self.checkConversion(304,"CCCIV")
        self.checkConversion(450,"CDL")
        self.checkConversion(546,"DXLVI")
        self.checkConversion(671,"DCLXXI")
        self.checkConversion(788,"DCCLXXXVIII")
        self.checkConversion(888,"DCCCLXXXVIII")
        self.checkConversion(999,"CMXCIX")
    def testThousands(self):
        self.checkConversion(1010,"MX")
        self.checkConversion(1111,"MCXI")
        self.checkConversion(1234,"MCCXXXIV")
        self.checkConversion(2342,"MMCCCXLII")
        self.checkConversion(2999,"MMCMXCIX")
    def checkConversion(self,numeral, roman):
        self.assertEquals(roman, self.roman.intToRoman(numeral))
        self.assertEquals(numeral, self.roman.romanToInt(roman))
if __name__ == "__main__":
    unittest.main()

]]> http://anabuigues.com/2011/02/15/code-kata-febrero-romannumerals/feed/ 5 Mi primera Code Kata http://anabuigues.com/2011/02/01/mi-primera-code-kata/ http://anabuigues.com/2011/02/01/mi-primera-code-kata/#comments Tue, 01 Feb 2011 17:40:00 +0000 Ana Buigues http://anabuigues.com/?p=3344 Ayer hice junto a Héctor Rodes mi primera Code Kata, gracias a la iniciativa de 12meses12katas, donde cada mes se propone una nueva kata. Abierta a todo el mundo y a todos los lenguajes de programación, excelente para poder practicar y aprender.

Y…¿qué es una Code Kata? pues una Code Kata hace referencia a un ejercicio de programación en el cual se resuelve un problema más o menos complejo donde el objetivo es mejorar las cualidades de un programador mediante la práctica y resolución repetitiva de problemas.

Lo que obtenemos de todo esto es obligarnos a encontrar una solución a un problema y además nos permite contrastar nuestra solución con la de otras personas, de esta forma podemos descubrir nuevas formas de resolver el mismo problema, y si la programas en parejas es todavía más divertido.

Para Enero el ejercicio de la Code Kata era el String Calculator, la idea es hacer un programa que sume  los números de una cadena separados por diferentes delimitadores, por ejemplo: “8*5%3″ . Si queréis ver el código de la gente que ha realizado la Code Kata podéis visitar el github del proyecto. El nuestro está en el directorio de animalaes.

Nuestra solución

La hemos realizado en Java, con la ayuda de la clase Scanner de Java para parsear la cadena mediante expresiones regulares. Se admiten sugerencias sobre mejoras o lo que sea.

package com.anabuigues;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
 * Implementación sencilla de la calculadora para la kata de enero.<br />
 * <br />
 * La implementación está realizada usando java 6 estándar apoyándose en la
 * clase Scanner que permite trocear al vuelo un imput a partir de un o n
 * delimitadores. Para ello extrae los delimitadores y construye una expresión
 * reguar válida para el scanner al que se le solicitan los diferentes enteros
 * para ir sumándolos.
 *
 *
 * @author A. Buigues (@animalaes), H. Rodes (@hector_rodes)
 *
 */
public class StringCalculator {
	public int add(String numbers) throws Exception {
		int returnValue;
		if (numbers == null || numbers.isEmpty()) {
			returnValue = 0;
		} else {
			ByteArrayInputStream bais = new ByteArrayInputStream(
					numbers.getBytes());
			Scanner sc = new Scanner(bais);
			String delimiters = null;
			// Delimiters
			if (numbers.startsWith("//")) {
				sc.useDelimiter("//|\n");
				if (sc.hasNext()) {
					delimiters = sc.next();
				}
			}
			delimiters = getScannerFormattedDelimiters(delimiters);
			// Process number lines with numbers to be added
			sc.useDelimiter(delimiters);
			int sum = 0;
			int currentNumber;
			List<Integer> negativeValues = new ArrayList<Integer>();
			while (sc.hasNext()) {
				currentNumber = sc.nextInt();
				if (currentNumber < 0) {
					negativeValues.add(currentNumber);
				} else if (currentNumber <= 1000) {
					sum += currentNumber;
				}
			}
			checkNegativeValues(negativeValues);
			returnValue = sum;
		}
		return returnValue;
	}
	/**
	 * Método auxiliar que comprueba si hay números negativos y forma el mensaje
	 *
	 * @param negativeValues
	 *            Lista de números negativos
	 * @throws Exception
	 *             Si la lista de números negativos contiene algún número
	 */
	private void checkNegativeValues(List<Integer> negativeValues)
			throws Exception {
		if (negativeValues != null && negativeValues.size() > 0) {
			StringBuilder sb = new StringBuilder("negatives not allowed");
			for (int negative : negativeValues) {
				sb.append(" ").append(negative);
			}
			throw new Exception(sb.toString());
		}
	}
	/**
	 * Genera la cadena de delimitadores necesaria para ser usada en el scanner
	 * y así poder procesar los números.<br />
	 * Siempre introduce el \n como un delimitador válido.<br />
	 * En caso de que los delimiters sean vacÌos o nulos usa la , y el \n como
	 * delimitadores por defecto
	 *
	 * @param delimiters
	 *            Los delimitadores introducidos
	 * @return Cadena con los delimitadores en el formato que espera el Scanner
	 */
	private String getScannerFormattedDelimiters(String delimiters) {
		String delimitersExpression;
		if (delimiters == null || delimiters.isEmpty()) {
			delimitersExpression = ",|\n";
		} else {
			String currentDelimiter;
			StringBuilder sb = new StringBuilder();
			Scanner scDelimiters = new Scanner(delimiters).useDelimiter(Pattern
					.quote("]") + "|" + Pattern.quote("["));
			while (scDelimiters.hasNext()) {
				currentDelimiter = scDelimiters.next();
				if (!currentDelimiter.isEmpty()) {
					sb.append(Pattern.quote(currentDelimiter)).append("|");
				}
			}
			sb.append("\n");
			delimitersExpression = sb.toString();
		}
		return delimitersExpression;
	}
}

Y su test

package com.anabuigues;
import junit.framework.Assert;
import org.junit.Test;
/**
 *
 * @author A. Buigues (@animalaes), H. Rodes (@hector_rodes)
 *
 */
public class CalculatorTest {
	private StringCalculator calculator = new StringCalculator();
	@Test
	public void basicCalculator() throws Exception {
		Assert.assertEquals(0, calculator.add(""));
		Assert.assertEquals(1, calculator.add("1"));
		Assert.assertEquals(10, calculator.add("7,3"));
		Assert.assertEquals(10, calculator.add("7\n2,1"));
		Assert.assertEquals(27, calculator.add("5\n5\n8,2,4\n2,1"));
	}
	@Test
	public void simpleDelimiterCalculator() throws Exception {
		Assert.assertEquals(16, calculator.add("//[*]\n5*5*6"));
		Assert.assertEquals(20, calculator.add("//[*]\n5*5*6\n4"));
		Assert.assertEquals(20, calculator.add("//[*][;][,]\n5,5;6\n4"));
		Assert.assertEquals(20,
				calculator.add("//[*][;][pollofrito]\n5pollofrito5;6\n4"));
	}
	@Test
	public void bigNumbersCalculator() throws Exception {
		Assert.assertEquals(1005, calculator.add("//[*]\n5*1000*1001"));
	}
	@Test
	public void negativeNumbersCalculator() throws Exception {
		try {
			Assert.assertEquals(1005, calculator.add("//[*]\n5*-23*45*-34"));
		} catch (Exception e) {
			Assert.assertTrue("-23 must be in error message ", e.getMessage()
					.indexOf("-23") != -1);
			Assert.assertTrue("-34 must be in error message ", e.getMessage()
					.indexOf("-34") != -1);
		}
	}
	@Test
	public void notDefinedDelimiterCalculator() throws Exception {
		try {
			Assert.assertEquals(8, calculator.add("//[*]\n5;3"));
			Assert.fail("Delimiter ; is not allowed but it has been used");
		} catch (Exception e) {
		}
	}
}

Ahora toca ponerse con la de febrero!!

]]> http://anabuigues.com/2011/02/01/mi-primera-code-kata/feed/ 4