Translate
lunes, 14 de septiembre de 2015
Bazel
Bazel es la herramienta que Google utiliza para construir la mayoría de su software. Esta es de código abierto.
Según Google, Bazel está dirigido a construir "código de forma rápida y fiable" y es "fundamental para la capacidad de Google dado que es una empresa grande y que crece rápidamente"
Antes de la construcción de Bazel, Google construía su software utilizando Makefiles que no le daba mayor confiabilidad. Además, en comparación con los Makefiles, Bazel ofrece conceptos de alto nivel, como "test", "C ++ binario", las nociones de "plataforma de destino" y "host plataforma ", etc.
Bazel soporta varios lenguajes en los que estan c++, java, rust, scala o groovy.
Dejo link:
http://bazel.io/
domingo, 13 de septiembre de 2015
Introducción a ScalaTest
Vamos a hacer algunos test con ScalaTest. Empecemos haciendo una clase:
case class Guest(name: String)
case class Room(number: Int, guest: Option[Guest] = None){ room =>
def isAvailable(): Boolean = ???
def checkin(guest: Guest): Room = ???
def checkout(): Room = ???
}
/*
* We will automatically create 10 rooms
* if these are not specified.
*/
case class Hotel(
rooms: List[Room] = (1 to 10).map(n => Room(number=n)).toList){
def checkin(personName: String): Hotel = ???
}
Hemos hecho una clase Hotel que contiene 10 habitaciones. El ??? significa que el metodo no fue definido, pero me permite compilar. Vamos a trabajar bien TDD.
Antes que nada agregamos el framework al proyecto utilizando sbt:
libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.4" % "test"
Ahora vamos a hacer una clase común para reutilizar métodos comunes:
package org.me.hotel
import org.scalatest.{FlatSpec,Matchers}
abstract class UnitTest(component: String) extends FlatSpec
with Matchers{
behavior of component
}
Como se puede ver hicimos una clase padre o general para todos los tests, esta extiende de FlatSpec e implementa Matchers.
A la vez le pasamos por parámetro el nombre del componente a probar. Si quisieramos utilizar esta clase lo hariamos de la siguiente manera:
class MyClassUnitTest extends UnitTest("MyClass")
A la vez utilizamos Matchers dado que nos provee expresiones más cercanas a los humanos como:
(2+2) should equal (4)
(2+2) shouldEqual 5
(2+2) should === (4)
(2+2) should be (4)
(2+2) shouldBe 5
Bueno ahora definimos nuestro test:
package org.me.hotel
class RoomTest extends UnitTest("Room") {
it should "provide info about its occupation" in {
Room(1).isFree() shouldEqual true
Room(1,None).isFree() shouldEqual true
Room(1,Some(Guest("Bruce"))).isFree() shouldEqual false
}
it should "allow registering a new guest if room is free" in {
val occupiedRoom = Room(1).checkin(Guest("James"))
occupiedRoom.isFree shouldEqual false
occupiedRoom.guest shouldEqual(Option(Guest("James")))
}
it should "deny registering a new guest if room is already occupied" in {
an [IllegalArgumentException] should be thrownBy {
Room(1,Some(Guest("Barbara"))).checkin(Guest("Bruce"))
}
}
it should "deny checking out if room is already free" in {
an [IllegalArgumentException] should be thrownBy {
Room(1).checkout()
}
}
it should "allow checking out if room is occupied by someone" in {
val room = Room(1,Some(Guest("Carmine")))
val freeRoom = room.checkout()
freeRoom.isFree shouldEqual true
}
}
Como se puede ver los test quedan escritos casi en lenguaje natural.
Si corremos los tests nos darán un error:
> test
[info] RoomTest:
[info] Room
[info] - should provide info about its occupation *** FAILED ***
[info] scala.NotImplementedError: an implementation is missing
[info] at scala.Predef$.$qmark$qmark$qmark(Predef.scala:252)
[info] at org.me.hotel.Room.isFree(Room.scala:6)
[info] at org.me.hotel.RoomTest$$anonfun$1.apply$mcV$sp(RoomTest.scala:6)
[info] at org.me.hotel.RoomTest$$anonfun$1.apply(RoomTest.scala:5)
...
[info] Run completed in 699 milliseconds.
[info] Total number of tests run: 15
[info] Suites: completed 6, aborted 0
[info] Tests: succeeded 3, failed 12, canceled 0, ignored 0, pending 0
[info] *** 12 TESTS FAILED ***
[error] Failed tests:
[error] org.me.hotel.RoomTest
[error] org.me.hotel.HotelTest
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 6 s, completed 12-ago-2015 16:08:47
Ahora a hacer que nuestras clases pasen sus tests, Suerte!!!!
package org.me.hotel
import org.scalatest.{FlatSpec,Matchers}
abstract class UnitTest(component: String) extends FlatSpec
with Matchers{
behavior of component
}
Como se puede ver hicimos una clase padre o general para todos los tests, esta extiende de FlatSpec e implementa Matchers.
A la vez le pasamos por parámetro el nombre del componente a probar. Si quisieramos utilizar esta clase lo hariamos de la siguiente manera:
class MyClassUnitTest extends UnitTest("MyClass")
A la vez utilizamos Matchers dado que nos provee expresiones más cercanas a los humanos como:
(2+2) should equal (4)
(2+2) shouldEqual 5
(2+2) should === (4)
(2+2) should be (4)
(2+2) shouldBe 5
Bueno ahora definimos nuestro test:
package org.me.hotel
class RoomTest extends UnitTest("Room") {
it should "provide info about its occupation" in {
Room(1).isFree() shouldEqual true
Room(1,None).isFree() shouldEqual true
Room(1,Some(Guest("Bruce"))).isFree() shouldEqual false
}
it should "allow registering a new guest if room is free" in {
val occupiedRoom = Room(1).checkin(Guest("James"))
occupiedRoom.isFree shouldEqual false
occupiedRoom.guest shouldEqual(Option(Guest("James")))
}
it should "deny registering a new guest if room is already occupied" in {
an [IllegalArgumentException] should be thrownBy {
Room(1,Some(Guest("Barbara"))).checkin(Guest("Bruce"))
}
}
it should "deny checking out if room is already free" in {
an [IllegalArgumentException] should be thrownBy {
Room(1).checkout()
}
}
it should "allow checking out if room is occupied by someone" in {
val room = Room(1,Some(Guest("Carmine")))
val freeRoom = room.checkout()
freeRoom.isFree shouldEqual true
}
}
Como se puede ver los test quedan escritos casi en lenguaje natural.
Si corremos los tests nos darán un error:
> test
[info] RoomTest:
[info] Room
[info] - should provide info about its occupation *** FAILED ***
[info] scala.NotImplementedError: an implementation is missing
[info] at scala.Predef$.$qmark$qmark$qmark(Predef.scala:252)
[info] at org.me.hotel.Room.isFree(Room.scala:6)
[info] at org.me.hotel.RoomTest$$anonfun$1.apply$mcV$sp(RoomTest.scala:6)
[info] at org.me.hotel.RoomTest$$anonfun$1.apply(RoomTest.scala:5)
...
[info] Run completed in 699 milliseconds.
[info] Total number of tests run: 15
[info] Suites: completed 6, aborted 0
[info] Tests: succeeded 3, failed 12, canceled 0, ignored 0, pending 0
[info] *** 12 TESTS FAILED ***
[error] Failed tests:
[error] org.me.hotel.RoomTest
[error] org.me.hotel.HotelTest
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 6 s, completed 12-ago-2015 16:08:47
Ahora a hacer que nuestras clases pasen sus tests, Suerte!!!!
martes, 8 de septiembre de 2015
Este sábado 12 empieza el #HackathonLitoral2015 en Santa Fe. Inscribite!
Curso recomendado de Coursera
Me llego el siguiente mail de Coursera, muy buenos cursos:
My Courses Course Catalog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
domingo, 6 de septiembre de 2015
Haciendo fácil la minería de datos con Rapidminer
Si es raro un post de minería de datos en este blog. Les cuento que estoy haciendo un curso y me llamo la atención gratamente este producto.
Supongamos que necesitas saber reglas para un problema, por ejemplo que persona no debes darles créditos. Entonces que haces:
Si bien estoy simplificando mucho la historia, en la herramienta es así. Luego al ser un trabajo empírico debes hace muchas comparaciones con la realidad.
Esas reglas las podes utilizar con algún motor de reglas como Jboss drools o programarlas.
Rapidminer trae muchas herramientas de diferente índole, para limpiar datos, generar reglas, hacer arboles de decisión, importar datos, etc.
Tiene una versión comercial y otra open source y gratuita.
Dejo link:
https://rapidminer.com/
Supongamos que necesitas saber reglas para un problema, por ejemplo que persona no debes darles créditos. Entonces que haces:
- Te instalas, rapidminer
- Importas datos históricos
- Generas el árbol con algún algoritmo y tenes las reglas. Y listo!
Si bien estoy simplificando mucho la historia, en la herramienta es así. Luego al ser un trabajo empírico debes hace muchas comparaciones con la realidad.
Esas reglas las podes utilizar con algún motor de reglas como Jboss drools o programarlas.
Rapidminer trae muchas herramientas de diferente índole, para limpiar datos, generar reglas, hacer arboles de decisión, importar datos, etc.
Tiene una versión comercial y otra open source y gratuita.
Dejo link:
https://rapidminer.com/
Blog.scalac.io
Quiero compartir con ustedes una excelente pagina que contiene un montón de recursos sobre scala y Akka, tal vez ya la conocen scalac.io
Dejo link: http://blog.scalac.io/
Pequeña introducción a Wolfram
Bueno, si tomamos un lenguaje para navegar en el conocimiento y brindar conocimiento; sin duda; Wolfram es la respuesta.
Ente las características de Wolfram podemos nombrar:
Les dejo un tutorial muy bueno!! Al final de cada ítem pueden validar si entendieron.
Dejo link:
http://www.wolfram.com/language/fast-introduction-for-programmers/
http://reference.wolfram.com/language/
Ente las características de Wolfram podemos nombrar:
- Fue diseñado para ser utilizado de forma interactiva.
- Tiene alrededor de 5000 funciones incorporadas.
- Expresiones simbólicas, por ejemplo podríamos pasar por parámetro un gráfico o guardarlo en una variable.
- Las listas se indican por medio de llaves, tiene listas por comprensión y maneja indices negativos.
Les dejo un tutorial muy bueno!! Al final de cada ítem pueden validar si entendieron.
Dejo link:
http://www.wolfram.com/language/fast-introduction-for-programmers/
http://reference.wolfram.com/language/
jueves, 3 de septiembre de 2015
Aprende Html 5 gracias W3C y EDX
Me llego esta propuesta de curso y esta tan buena que la quiero compartir:
| |||||
Dear all,
We're back! And we need your help in getting the word out.
We are again teaching how to build powerful Web sites and apps with HTML5. If you are tuned into tech news, you've surely been recently exposed to a flurry of articles encouraging developers to ditch other technologies in favor of HTML5.
Register for the new edition of the course! (to start on 5 October 2015)
Thank you.
Best,
Marie-Claire and Michel.
| |||||
|
domingo, 30 de agosto de 2015
Usando Clojure para hacer aplicaciones Android
Se puede desarrollar una aplicación Android con Clojure? Claro!
Leyendo InfoQ, llego a un articulo sobre desarrollo de android con Clojure y esta muy bueno.
Básicamente tenemos 2 caminos para construir aplicaciones:
- lein-droide: un plugin Leiningen que funciona como una herramienta de construcción para proyectos Clojure-Android y se ocupa de los procesos de recursos de embalaje, la creación de un archivo APK, firmarlo, etc.
- Neko: un conjunto de herramientas que envuelve algunas partes de Java API de Android para que sean más idiomática para utilizar en Clojure.
Dejo link:
http://www.infoq.com/news/2015/08/clojure-native-android-apps
ADVENTURES IN WEB ANIMATIONS
Quería compartir un curso de la gente de codeschool, sobre animaciones web. Es gratuito por lo que aprovechen, dejo link:
http://campus.codeschool.com/courses/adventures-in-web-animations
http://campus.codeschool.com/courses/adventures-in-web-animations
martes, 25 de agosto de 2015
Un montón de libros en GitHub
Quiero compartir muchos libros en Github y hay muchos en castellano.
Les dejo link:
https://github.com/vhf/free-programming-books/blob/master/free-programming-books-es.md
También copio el indice:
Index
domingo, 23 de agosto de 2015
Haciendo Juegos con ELM
Anteriormente hable de ELM un lenguaje funcional que tenia la particularidad de compilar a HTML, javascript y CSS.
Este lenguaje no solo nos permite hacer paginas web, sino tambien juegos que como sospecharan corren en HTML con ayuda de javascript.
Les dejo la siguiente pagina que es muy interesante:
http://gelatindesign.co.uk/developing-games-in-elm/functional-programming/
Este lenguaje no solo nos permite hacer paginas web, sino tambien juegos que como sospecharan corren en HTML con ayuda de javascript.
Les dejo la siguiente pagina que es muy interesante:
http://gelatindesign.co.uk/developing-games-in-elm/functional-programming/
miércoles, 19 de agosto de 2015
Pizza as a Service
Quiero compartir con ustedes este genial ejemplo de Pizza como servicio. Me tome la liberta de copiar del post original:
SAP publico un excelente gráfico realizado por un Software Architect de IBM donde se presenta la analogía de los servicios en la nube como si de una Pizza se tratara, me pareció excelente esta explicación, sobre todo cuando estamos con una persona ajena a IT y debemos explicar que es cada cosa y donde quedan sus datos.
Dejo link:
http://menghi.biz/2015/08/14/pizza-as-a-service/
SAP publico un excelente gráfico realizado por un Software Architect de IBM donde se presenta la analogía de los servicios en la nube como si de una Pizza se tratara, me pareció excelente esta explicación, sobre todo cuando estamos con una persona ajena a IT y debemos explicar que es cada cosa y donde quedan sus datos.
Dejo link:
http://menghi.biz/2015/08/14/pizza-as-a-service/
lunes, 17 de agosto de 2015
Postgrest
Algo que me llamo la atención de CouchDB es que exponía sus datos con una API Rest, me pareció fantástico, porque la verdad es que no remplazaría a la capa de aplicación 100% de las veces. Pero para alguna aplicación pequeña. Además si todas las bases usan esta técnica, las aplicaciones no deberían saber si se comunican con una base, con otro sistema, ni es necesario saber que base de datos es. Muchas ventajas!
Postgrest permite hacer esto con postgres, provee una API Rest para comunicarse con la base y de esta forma poder acceder a los datos a través de REST.
Cualquier base de datos Postgres puede utilizar este programa, solo es necesario llamarlo de la siguiente manera:
postgrest --db-host localhost --db-port 5432 \
--db-name my_db --db-user postgres \
--db-pass foobar --db-pool 200 \
--anonymous postgres --port 3000 \
--v1schema public
Podríamos
hablar de muchas ventajas como:
Dejo link:
https://github.com/begriffs/postgrest
Postgrest permite hacer esto con postgres, provee una API Rest para comunicarse con la base y de esta forma poder acceder a los datos a través de REST.
Cualquier base de datos Postgres puede utilizar este programa, solo es necesario llamarlo de la siguiente manera:
postgrest --db-host localhost --db-port 5432 \
--db-name my_db --db-user postgres \
--db-pass foobar --db-pool 200 \
--anonymous postgres --port 3000 \
--v1schema public
Podríamos
hablar de muchas ventajas como:
- Seguro, puede utilizar https y provee autenticación.
- Autodocumentado
- Rapido
Dejo link:
https://github.com/begriffs/postgrest
domingo, 16 de agosto de 2015
Que es la Metaprogramming?
O Metaprogramación, en castellano.
Voy a tomar un post muy bueno sobre metaprogramación en Ruby. Empecemos definiendo la metaprogramación, que es? código que escribe código, y listo.
Como pueden sospechar no es una característica solo de Ruby, en realidad es de muchos lenguajes. Sin embargo es mucho más fácil, hacer metaprogramación en lenguajes dinámicos e interpretados. Si no fuéramos puristas podríamos pensar que por ejemplo un Proxy de spring en Java es metaprogramación, ya que spring genera una clase al vuelo (en tiempo de ejecución) y la implementa. Por lo tanto genera código, por lo tanto es metaprogramación.
Otra virtud necesaria en lenguaje para que la metaprogramación sea útil o sea más útil, es que el lenguaje sea reflexivo o se pueda inspeccionar los objetos, en castellano, los objetos pueden decirte si responden mensajes o que atributos tiene, etc. El etc quiere decir que podemos modificar algunos métodos o hacer macana como romper el encapsulamiento pero recuerda:
“With great power comes great responsibility.”
Pero vuelvo a Ruby y para esto voy a copiar un poco de código. jeje!
Vamos a hacer un método que limpie una cadena, limpie la cadena de caracteres extraños:
def to_alphanumeric(s)
s.gsub(/[^\w\s]/, '')
end
puts to_alphanumeric("A&^ar$o%n&* (is&*&))) t&*(*he B0&*S**^S)")
# => "Aaron is the B0SS"
En Ruby tenemos clases abiertas (como smalltalk) por lo que podemos poner este método en la clase String.
class String
def to_alphanumeric
gsub(/[^\w\s]/, '')
end
end
puts "A&^ar$o%n&* (is&*&))) t&*(*he B0&*S**^S)".to_alphanumeric
# => "Aaron is the B0SS"
Las clases abiertas no son la panacea, podemos hacer desastre. Podemos reescribir métodos de clases propias de ruby. Esto se llama Monkeypatching.
Modelo de Objetos
Antes de seguir debemos ver la jerarquia de clases de Ruby:
Parece complejo, pero no lo es, veamos los detalles:
- Tenemos 3 instancias de la clase MyClass (obj1, obj2, obj3)
- MyClass tiene una clase Class, esto es porque las clases tambien son objetos.
- Los objetos tienen una clase que es MyClass.
Cadena de ancestros
Bueno, recuerden esto porque ahora nos vamos a analizar, la herencia en especial la cadena de ancestros en ingles Ancestors Chain.
Este diagrama es fácil de entender:
Cuando se llama a un método, Ruby va directamente a la clase del receptor (en este caso libro) y luego en cadena a los antepasados, hasta que cualquiera encuentre el método o llegue al final de la cadena.
En este diagrama, un objeto b es creado de una instancia de la clase libro. Libro tiene 2 módulos: imprimir y documentos. Libro hereda de la clase Object, que es la clase que casi todos heredan en Ruby. Objeto incluye un módulo llamado Kernel. Y, por último, el objeto hereda de BasicObject - el padre absoluto de cada objeto en Ruby.
Ya aburrí muchísimo con la introducción, pero en esta parte deberían tener claro el modelo de objetos y la cadena de ancestros. Si no lo tienen en claro bueno, deberían volver a leerlo.
Métodos
En Ruby podemos crear métodos de forma dinámica y a la vez llamar método de forma dinámica, tambien. Vamos por parte, primero ver crear métodos de forma dinámica.
¿Por qué queremos definir dinámicamente métodos? Tal vez para reducir la duplicación de código, o para añadir funcionalidad a otros objetos por ejemplo ActiveRecord (la herramienta ORM por defecto en Rails) lo utiliza en gran medida. Veamos un ejemplo:
class Book < ActiveRecord::Base
end
b = Book.new
b.title
Si estas familiarizado con ActiveRecord esta linea de código no le resultara extraña. Pero nunca definimos el atributo title, pero lo podemos utilizar, como? Bueno ActiveRecord por medio de metaprograming define un atributo de forma dinámica, dado que title es un atributo de la tabla.
Normalmente, llamando title en esta clase debería lanzar error NoMethodError - pero ActiveRecord añade dinámicamente métodos al igual que estamos a punto de hacer. ActiveRecord es un excelente ejemplo de cómo se puede utilizar metaprogramming al máximo.
Crear nuestros propios métodos:
def foo
puts "foo was called"
end
def baz
puts "baz was called"
end
def bar
puts "bar was called"
end
foo
baz
bar
# => foo was called
# => baz was called
# => bar was called
Si, si estamos duplicando codigo. Usemos metaprogramming:
%w(foo baz bar).each do |s|
define_method(s) do
puts "#{s} was called"
end
end
foo
baz
bar
# => foo was called
# => baz was called
# => bar was called
Llamar un método de forma dinámica:
%w(test1 test2 test3 test4 test5).each do |s|
define_method(s) do
puts "#{s} was called"
end
end
# New Code
(1..5).each { |n| send("test#{n}") }
# => test1 was called
# => test2 was called
# => test3 was called
# => test4 was called
# => test5 was called
Como se puede ver con send llamamos un método de forma dinámica. Y send es un método de Object.
class OKCRB
def is_boss?
puts "true"
end
end
okcrb = OKCRB.new
okcrb.send("is_boss?")
# => true
Ojo acá!! send nos permite llamar a métodos privados por lo que podemos romper el encapsulamiento. Si no queremos hacer esto, podemos llamar a public_send que no nos permite llamar métodos privados.
Que pasa si hacemos esto:
class Book
end
b = Book.new
b.read
Por supuesto obtendremos un error, un NoMethodError. Ahora bien podemos hacer lo siguiente:
class Book
def method_missing(method, *args, &block)
puts "You called: #{method}(#{args.join(', ')})"
puts "(You also passed it a block)" if block_given?
end
end
b = Book.new
b.read
b.read('a', 'b') { "foo" }
# => You called: read()
# => You called read(a, b)
# => (You also passed it a block)
BasicObject#method_missing nos permite controlar el error NoMethodError. De esta forma, el error nunca sucede y aquí podemos hacer lo que deseemos.
Este es un pequeño y humilde resumen de metaprograming en Ruby, es decir por hoy estamos!!
Dejo link:
https://thesocietea.org/2015/08/metaprogramming-in-ruby-part-1/
Suscribirse a:
Entradas (Atom)