Translate

lunes, 5 de febrero de 2018

Empezando con Elixir 11

Sigils

Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde ~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils  cuando necesitamos extender el lenguaje.

Los Sigils disponibles son:

~ C Genera una lista de caracteres sin escape ni interpolación
~ c Genera una lista de caracteres con escape e interpolación
~ R Genera una expresión regular sin escape ni interpolación
~ r Genera una expresión regular con escape e interpolación
~ S Genera una cadena sin escape ni interpolación
~ s Genera una cadena con escape e interpolación
~ W Genera una lista de palabras sin escape ni interpolación
~ w Genera una lista de palabras con escape e interpolación
~ N genera una estructura NaiveDateTime

Una lista de delimitadores incluye:

<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples

Lista de caracteres

~c y ~C generan una lista de caracteres:

iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'

iex> ~C/2 + 7 = #{2 + 7}/

'2 + 7 = \#{2 + 7}'

Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.

Expresiones regulares

~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:

iex> re = ~r/elixir/
~r/elixir/

iex> "Elixir" =~ re
false

iex> "elixir" =~ re
true

Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.

iex> re = ~r/elixir/i
~r/elixir/i

iex> "Elixir" =~ re
true

iex> "elixir" =~ re
true

Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:

iex> string = "100_000_000"
"100_000_000"

iex> Regex.split(~r/_/, string)
["100", "000", "000"]

String

~s y ~S se utilizan para generar cadenas. Por ejemplo:

iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"

iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"

¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:

iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"

iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"

Word List

La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:

iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]

iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]

Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:

iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]

iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]

NaiveDateTime

Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.

En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:

iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}

Crear un Sigils

Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.

iex> defmodule MySigils do
...>   def sigil_u(string, []), do: String.upcase(string)
...> end

iex> import MySigils
nil

iex> ~u/elixir school/
ELIXIR SCHOOL

Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.


viernes, 2 de febrero de 2018

Un resumen de Scala for the Impatient, parte 36


Operadores de asignación.

Los operadores de asignación tienen la forma operador= y se utilizan de la siguiente forma:

a operator= b

que es igual a decir :

a = a operator b

Por ejemplo a+= b es equivalente a escribir a = a + b

Hay unos detalles técnicos :
<=, >= y != no son operadores de asignación
Un operador que comienza con = nunca es un operador de asignación (==, ===, =/=, etc)
Si a tiene un operador llamado operator= entonces este sera llamado directamente.

Precedencia.

Cuando tenemos más de un operador, sin paréntesis debemos definir las precedencias de los operadores. Dado que esto define el orden de resolución, por ejemplo :

1 + 2 * 3

El operador * se evalúa primero y luego la suma, esto fue definido por conversión. Lenguajes como C++ y Java tienen un numero fijo de operadores por lo tanto es más sencillo definir la precedencias (se pueden enumerar). En cambio en Scala tenemos un numero arbitrario de operadores por lo que se debe definir esto de forma general.

  • La precedencia más alta esta dada por un caracter operador que no sea los antesesores. 
  • * / %
  • + -
  • :
  • < >
  • ! =
  • &
  • ^
  • |
  • Un carácter que no es un operador
  • La menor precedencia es el operador de asignación

Los caracteres que estan en similar fila tiene similar precedencia. Por ejemplo + y -

Los operadores infijos tienen menor precedencia, por lo tanto :

a infixOp b postfixOp es similar a (a infixOp b)postfixOp
 
Asociatividad

Luego de definir la precedencia, es importante la asociatividad dado que exiten operadores que son asociativos. Por ejemplo 17 – 2 – 9 es similar a (17 – 2) – 9. El operador – es asociativo por la izquierda.

En scala todos los operadores son asociativos por la izquierda excepto :

  • Los operadores que finalizan en : 
  • Los operadores de asignación. 

Por ejemplo el operador :: construye listas con asosciatividad a la derecha por ejemplo :

1 :: 2 :: Nil esto es similar a 1 :: (2 :: Nil)

Esto generara una lista con elemento 1 y 2 es ese orden. Es decir el operador :: es un metodo de la lista que ingresa un elemento por la izquierda, convirtiendolo en el primer elemento.

Es decir 2 :: Nil es igual a Nil.::(2)

 

jueves, 1 de febrero de 2018

Aprende Go con un video

Go es un lenguaje de google, que rápidamente tomo importancia. Es un lenguaje interesante no solo por las características que tiene sino por las que no tiene. Es decir, se tomaron decisiones que son controversiales para el mundo del software.

Este video de casi una hora trata de darnos una primera pasada por el lenguaje, es un tur completo por el lenguaje. Esta muy bueno y todo muy bien explicado.


miércoles, 31 de enero de 2018

Google lanzo Puppeteer 1.0

Puppeteer es una herramienta de automatización de pruebas esta basado en Chrome. Aprovechando Node.js y el protocolo Chrome DevTools, Puppeteer proporciona una alternativa a Selenium WebDriver.

Más allá del típico caso de uso de pruebas automáticas del navegador, Puppeteer se puede utilizar para una variedad de técnicas de automatización del navegador, incluida la realización de tareas repetitivas, el contenido de raspado y la generación de capturas de pantalla.

El proyecto proporciona un Try Puppeteer con el cual podemos comenzar rápidamente con Puppeteer.

Desde su lanzamiento inicial, Puppeteer ha sido ampliamente adoptado como una forma más sencilla de introducir la automatización en el flujo de trabajo del desarrollador. Muchos desarrolladores han escrito extensos tutoriales y brindado sus comentarios sobre el trabajo con Puppeteer.

Por lo que vamos a tener que probarlo.

Dejo link: https://github.com/GoogleChrome/puppeteer/

sábado, 20 de enero de 2018

Consultar APIs REST con restQL

RestQL es un lenguaje de consultas de microservicio que facilita la obtención de información de múltiples servicios de la manera más eficiente. Parecido a GraphQL

Veamos un ejemplo:

from hero
    with
        name = "Restman"

from sidekick
    with
        hero = hero.id
    only
        skills

RestQL se integra a la perfección con su arquitectura de microservicio actual.

Solo se debe configurar los end points del servicio, corremos el servidor de restQL y luego comencemos a consultar.

Una arquitectura basada en microservicios no es una bala de plata. A pesar de sus beneficios inmediatos para los equipos de servicio, plantea por su propia naturaleza un desafío en términos de complejidad y rendimiento para los consumidores. restQL tiene como objetivo resolver esta brecha, reduciendo los viajes redondos y simplificando la orquestación de microservicios.

Dejo link:
http://restql.b2w.io/

miércoles, 17 de enero de 2018

Instalar mint desde un usb


Me toco instalar Linux Mint desde un usb y me llamo la atención lo fácil que es.

Los pasos a seguir son los siguientes:

  • Bajamos la imagen de linux mint. 
  • Luego iniciamos una aplicación llamada mintStick
  • Elegimos la imagen ISO, elegimos la unidad USB y presionamos empezar (ojo que esto nos va a borrar el contenido del usb)
  • Luego este proceso demorara unos minutos. 
  • Y listo, ahora a bootear con el USB y comenzar el proceso de instalación como lo hacemos normalmente. 


Así de simple, luego a disfrutar de nuestro mint!




domingo, 14 de enero de 2018

Empezando con Python de nuevo!


Hace mucho mucho tiempo que no hago nada en python y por x motivo debo volver a programar en este lenguaje. Por suerte me tope con la pagina: http://www.python.org.ar/ . En la cual se puede encontrar muchos recursos para empezar y de muy buena calidad.

¡Felicitaciones! No todos los días se toma el coraje de adentrarse en un mundo desconocido para muchos y tan divertido para otros. Me pone muy contento que te haya surgido la inquietud de ver "¿de qué se trata esto de Python?" y hayas llegado a este sitio web.
Aquí podrás encontrar unos pequeños lineamientos que te pueden ser de gran ayuda a la hora de aprender a programar en Python. Incluso, si no tienes conocimiento alguno de programación.
Antes que nada, algunos consejos para que no te desanimes en el camino del aprendizaje y te resulte más sencillo:
  • Programar es muy divertido, pero como cualquier otra disciplina: lleva tiempo.
  • A diferencia de otros lenguajes de programación, Python tiene una curva de aprendizaje mucho más rápida, lo cual te permitirá obtener resultados casi de inmediato.
  • Al fin y al cabo, era mucho más fácil aprender a programar (y mantenerse actualizado) si se dominaba, al menos, un nivel básico de Inglés.
  • Cualquiera puede aprender a programar. ¡Sí, cualquiera! No hay que ser un genio ni un maestro en nada. Yo pude, ;)
  • En el camino, aprenderás a investigar y a resolver problemas por tu propia cuenta. Simplemente, con una conexión a Internet y leyendo varios foros/listas de correo o preguntando en diferentes canales de chat.
  • ¡Sí, eso! Suscríbete a la lista de correo de tu región para así poder hacerle preguntas a otras personas que tienen más experiencia en el tema y siempre tienen ganas de ayudar.
¡Ahora sí, vamos a lo importante y centrémonos en aprender!
La teoría es cuando creés saber algo pero no anda. La práctica es cuando algo funciona pero no sabés porqué. El programador combina ambas: nada anda y no sabe porqué.
Einstein + Anónimo
Antes de empezar a leer fuertemente los libros o tutoriales que te recomendamos aquí, me parece muy bueno pegarle una primera ojeada a algunos de ellos (los que más te llamen la atención) y en base a eso, determinar cuál puede ser más divertido y entusiasmante empezar a leer. Incluso, ¡hay algunos que son interactivos y están buenísimos!

¿Por dónde empezar?

No sé nada de Python, ni de programación, y quiero empezar desde lo más básico:

¿Por dónde seguir?

Tengo algún conocimiento en programación, o incluso en Python, y quiero leer algo un poquito más avanzado:

Me manejo con el Inglés

Tengo un dominio básico de lectura en inglés.

Soy científico y quiero analizar mis datos

Pertenezco al mundo de las ciencias de alguna manera: biología, química, genética, matemática, física, <coloque aquí su ciencia preferida> y quiero aprender a utilizar Python, por ejemplo, para analizar un enorme conjunto de datos de una forma automatizada.

Muchísimo más material!

¡Me re copé con Python, leí un montón de cosas y ahora quiero rockearla!
Aquí listamos todo el material excedente que consideramos muy útil para seguir con el estudio de Python y la programación, pero que quizás desorienta un poco al principio. En esta sección podés encontrar otras guías similares a esta, más herramientas y módulos, documentación que se encuentra en progreso y diferentes tutoriales orientados a públicos distintos.

sábado, 13 de enero de 2018

Empezando con Elixir 10

Mix

Antes de que podamos sumergirnos en las aguas más profundas de Elixir, primero tenemos que aprender Mix. Si está familiarizado con Ruby, Mix es Bundler, RubyGems y Rake combinados. Es una parte crucial de cualquier proyecto de Elixir y en esta lección vamos a explorar solo algunas de sus excelentes características.


Hasta ahora hemos estado trabajando exclusivamente dentro de iex, que tiene limitaciones. Para construir algo sustancial necesitamos dividir nuestro código en muchos archivos para administrarlo efectivamente; Mix nos permite hacer eso con proyectos.

Proyectos

Para hacer un nuevo proyecto debemos hacer :

$ mix new example

De la salida podemos ver que Mix ha creado nuestro directorio y una serie de archivos:

* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/example.ex
* creating test
* creating test/test_helper.exs
* creating test/example_test.exs

Vamos a centrarnos mix.exs. Aquí configuramos nuestra aplicación, dependencias, entorno y versión. Vamos abrir este archivo :

defmodule Example.Mixfile do
  use Mix.Project

  def project do
    [app: :example,
     version: "0.0.1",
     elixir: "~> 1.1-dev",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    []
  end
end

La primera sección es project. Aquí definimos el nombre de nuestra aplicación (app), especificamos nuestra versión (version), versión de Elixir (elixir) y finalmente nuestras dependencias (deps).

En application configuramos settings que se usa durante la generación de nuestro archivo de aplicación.

Interactivo

Puede ser necesario usar iex dentro del contexto de nuestra aplicación. Afortunadamente para nosotros, Mix lo hace fácil. Podemos comenzar una nueva sesión iex:

$ iex -S mix

Iniciar iex de esta manera cargará la aplicación y dependencias en el tiempo de ejecución.

Compilacion

Mix es inteligente y compilará los cambios cuando sea necesario. Para compilar de forma manual un proyecto Mix solo necesitamos ejecutar la compilación de Mix en nuestro directorio base:

$ mix compile

si se compilo con exito retornará :

Compiled lib/example.ex
Generated example app

Cuando compilamos un proyecto Mix crea un directorio _build para nuestros artefactos. Si miramos dentro de _build veremos nuestra aplicación compilada: example.app.

Administrar dependencias

Nuestro proyecto no tiene dependencias, pero lo hará en breve, así que seguiremos adelante y cubriremos las dependencias definitorias y las buscaremos.

Para agregar una nueva dependencia, primero debemos agregarla a nuestra mix.exs en la sección deps. Nuestra lista de dependencias se compone de tuplas con dos valores obligatorios y uno opcional: el nombre del paquete como un átomo, la cadena de versión y opciones.

Para este ejemplo, veamos un proyecto con dependencias, con phoenix_slim:

def deps do
  [
    {:phoenix, "~> 1.1 or ~> 1.2"},
    {:phoenix_html, "~> 2.3"},
    {:cowboy, "~> 1.0", only: [:dev, :test]},
    {:slime, "~> 0.14"}
  ]
end

La dependencia cowboy solo es necesaria durante el desarrollo y la prueba.

Una vez que hemos definido nuestras dependencias, hay un último paso: obtenerlas. Esto es análogo a la instalación del paquete:

$ mix deps.get

Hemos definido y buscado nuestras dependencias de proyectos. 

Entornos

Mix, al igual que Bundler, admite diferentes entornos. Mix funciona con tres entornos:
  • :dev - El entorno predeterminado.
  • :test - Usado por la prueba de mezcla. Cubierto más en nuestra próxima lección.
  • :prod - se usa cuando enviamos nuestra aplicación a producción.

Se puede acceder al entorno actual utilizando Mix.env. Como se esperaba, el entorno se puede cambiar a través de la variable de entorno MIX_ENV:

$ MIX_ENV=prod mix compile



Comparando F# con C# parte 3

Vamos ha hacer un programa que baje una pagina en F# y en C# para comparar.

Veamos la implementación en F# :

// open es similar al using
open System.Net
open System
open System.IO

// Obtener los contenidos de una página web
let fetchUrl callback url =     
    let req = WebRequest.Create(Uri(url))
    use resp = req.GetResponse()
    use stream = resp.GetResponseStream()
    use reader = new IO.StreamReader(stream)
    callback reader url

Repasemos este código:

  • El "open" en la parte superior nos permite escribir "WebRequest" en lugar de "System.Net.WebRequest". Es similar a un encabezado "using System.Net" en C#.
  • A continuación, definimos la función fetchUrl, que toma dos argumentos, un callback para procesar la pagina y la URL a buscar.
  • Luego, creamos una Uri con la URL. F# tiene una estricta comprobación de tipos, por lo tanto, si en  hubiéramos escrito: let req = WebRequest.Create(url), el compilador se habría quejado de que no sabía qué versión de WebRequest.Create usar.
  • Al declarar los valores de respuesta, transmisión y lectura, se usa la palabra clave "use" en lugar de "let". Esto solo se puede usar junto con las clases que implementan IDisposable. Le dice al compilador que elimine automáticamente el recurso cuando se sale del alcance. Esto es equivalente a la palabra clave "using" C#.
  • La última línea llama a la función callback con StreamReader y la url como parámetros. Note que nunca especificamos el timpo del callback. 


Ahora veamos la implementación equivalente de C#:

class WebPageDownloader
{
    public TResult FetchUrl<TResult>(
        string url,
        Func<string, StreamReader, TResult> callback)
    {
        var req = WebRequest.Create(url);
        using (var resp = req.GetResponse())
        {
            using (var stream = resp.GetResponseStream())
            {
                using (var reader = new StreamReader(stream))
                {
                    return callback(url, reader);
                }
            }
        }
    }
}

Como de costumbre, la versión C # tiene más 'ruido'.

  • Hay diez líneas solo para llaves, y existe la complejidad visual de 5 niveles de anidación *
  • Todos los tipos de parámetros deben declararse explícitamente, y el tipo TResult genérico debe repetirse tres veces.
Podemos probar el codigo de la siguiente manera : 


let myCallback (reader:IO.StreamReader) url = 
    let html = reader.ReadToEnd()
    let html1000 = html.Substring(0,1000)
    printfn "Downloaded %s. First 1000 is %s" url html1000
    html      // return all the html

//test
let google = fetchUrl myCallback "http://google.com"

Finalmente, tenemos que recurrir a una declaración de tipo para el parámetro del lector (reader:IO.StreamReader). Esto es necesario porque el compilador F# no puede determinar el tipo del parámetro "reader" automáticamente.

Una característica muy útil de F# es que puede "pasar" parámetros en una función para que no tengan que pasarse en todo momento. Esta es la razón por la que el parámetro url se colocó en último lugar en lugar de primero, como en la versión de C#. La devolución de llamada se puede configurar una vez, mientras que la URL varía de llamada a llamada.

// build a function with the callback "baked in"
let fetchUrl2 = fetchUrl myCallback 

// test
let google = fetchUrl2 "http://www.google.com"
let bbc    = fetchUrl2 "http://news.bbc.co.uk"

// test with a list of sites
let sites = ["http://www.bing.com";
             "http://www.google.com";
             "http://www.yahoo.com"]

// process each site in the list
sites |> List.map fetchUrl2 

La última línea (usando List.map) muestra cómo la nueva función se puede usar fácilmente junto con las funciones de procesamiento de listas para descargar una lista completa a la vez.

Aquí está el código de prueba C# equivalente:

[Test]
public void TestFetchUrlWithCallback()
{
    Func<string, StreamReader, string> myCallback = (url, reader) =>
    {
        var html = reader.ReadToEnd();
        var html1000 = html.Substring(0, 1000);
        Console.WriteLine(
            "Downloaded {0}. First 1000 is {1}", url,
            html1000);
        return html;
    };

    var downloader = new WebPageDownloader();
    var google = downloader.FetchUrl("http://www.google.com",
                                      myCallback);
            
    // test with a list of sites     var sites = new List<string> {
        "http://www.bing.com",
        "http://www.google.com",
        "http://www.yahoo.com"};

    // process each site in the list   
   sites.ForEach(site => downloader.FetchUrl(site, myCallback));
}

De nuevo, el código tiene más ruido que el código F#, con muchas referencias explícitas de tipo. Lo que es más importante, el código C# no le permite pasar fácilmente algunos de los parámetros en una función, por lo que la devolución de llamada se debe referenciar explícitamente cada vez.



jueves, 11 de enero de 2018

Encuesta de ecosistemas de Desarrolladores


El año pasado, en JetBrains realizamos una Encuesta de Ecosistemas de Desarrolladores para comprender mejor a los desarrolladores y sus necesidades en todo el mundo. 9,000 encuestados en todo el mundo nos dieron sus comentarios, y compartieron los datos más interesantes (así como datos brutos anonimizados) con la comunidad.

Este año estan haciendo otra encuesta, Developer Ecosystem Survey 2018, y necesitan tu ayuda nuevamente.

Y completando esta encuesta de 20 minutos tendremos la oportunidad de ganar un valioso premio: $ 1,000 para su educación, un certificado de Amazon de $ 100 o un paquete de regalo de sorpresa de JetBrains.

Como siempre, los ganadores serán elegidos al azar. Es bueno proporcionar respuestas significativas a las preguntas de la encuesta.

Dejo link: https://surveys.jetbrains.com/s3/c4-DevEcosystem18?gclid=EAIaIQobChMIy8HhiOXO2AIVVFMMCh3WCAQCEAEYASAAEgKnwvD_BwE

miércoles, 10 de enero de 2018

Lenguajes de programación para aprender en 2018

Quiero compartir un excelente articulo sobre lenguajes de programación en 2018 (es decir este año)

Si bien el articulo no presenta mayor sorpresa, lista los lenguajes más populares de 2017 y que seguirán fuerte en 2018. Ojo aparece Scala (esto me llamo mucho la atención)

Yo empece el año con Crystal y se lo recomiendo porque esta muy bueno el lenguaje.

Dejo link: https://platzi.com/blog/lenguajes-de-programacion-2018/?utm_source=facebook&utm_medium=paidsocial&utm_campaign=pubetapa0

martes, 9 de enero de 2018

Juego de Serie en Crystal


Cuando quiero aprender un nuevo lenguaje desarrollo un juego de series, es decir aparece una serie con un valor faltante y el jugador debe completarlo.

Uno de los requerimientos no funcionales es que se pueda agregar una serie nueva fácilmente, para cumplirlo vamos a utilizar las ventajas de herencia y polimorfismo.

Vamos a desarrollar este juego en Crystal :

Comencemos haciendo un nuevo proyecto:

crystal init app secuenciaCrystal
cd secuenciaCrystal

y luego probamos compilar :

shards build

Y todo debería funcionar. 

Ahora utilizaremos visual code con un plugin para crystal, para importar el proyecto, vamos a abrir carpeta y seleccionamos la carpeta donde estamos trabajando : 


Ahora vamos a hacer un archivo secuencia.cr que va a tener las clases de secuencias:


abstract class Secuencia

  @secuencia : Array(Int32)

  getter secuencia

  def initialize()
    @secuencia = generarSecuencia()
  end

  abstract def generarSecuencia() : Array(Int32)

end

class SecuenciaPar < Secuencia

  def generarSecuencia() : Array(Int32)
     Array(Int32).new(4) { |i|
       i * 2 * rand(100) + rand(10) * 2
     }

  end

end

class SecuenciaInPar < Secuencia

  def generarSecuencia() : Array(Int32)
    Array(Int32).new(4) { |i|
       i * 2 * rand(100) + rand(10) * 2 + 1
    }
  end

end

Luego hacemos otro archivo para juego:

require "./secuencia.cr"

class Juego

  getter puntos

  @secuencia : Secuencia

  def initialize()
    @puntos = 0
    @secuencia = generarSecuencia()
  end

  def generarSecuencia() : Secuencia
    i = rand(2)

    case i
        when 0
          SecuenciaPar.new
        else
          SecuenciaInPar.new
    end
  end

  def valor1()
    @secuencia.secuencia[0]   
  end

  def valor2()
    @secuencia.secuencia[1]   
  end

  def valor4()
    @secuencia.secuencia[3]   
  end

  def esta_bien?(num : Int32?) : Bool
    if @secuencia.secuencia[2] == num
       @puntos = @puntos + 1
       @secuencia = generarSecuencia()
       true
    else
       @puntos = @puntos - 1
       @secuencia = generarSecuencia()
       false
    end
  end

end

Y por ultimo tenemos el programa propiamente dicho:

require "./secuenciaCrystal/*"
require "./juego.cr"


module SecuenciaCrystal
  puts "Bienvenido a Secuancia Crystal"
  juego = Juego.new
  while true
    puts juego.valor1.to_s + " " + juego.valor2.to_s + " ______ " + juego.valor4.to_s + " \n"
    puts "Ingere el valor \n"
   
    valorStr = gets.to_s
   
    valor = (valorStr).to_i32

    if juego.esta_bien?(valor)
      puts " Ganaste !! Tus puntos : " + juego.puntos.to_s
    else
      puts " Perdiste !! Tus puntos : " + juego.puntos.to_s
    end
    puts "Ingere 0 para salir y otro valor para continuar"
    if gets()  == "0"
      break
    end

  end
  puts "Bye!"
end


Como se puede apreciar el diseño del juego permite generar una interfaz de consola o gráfica o en otra tecnología esta es la mayor ventaja de separar nuestros objetos de la capa de presentación.

Funcionando es muy divertido:



Dejo el repo: https://github.com/emanuelpeg/secuenciaCrystal



domingo, 7 de enero de 2018

Primeros pasos con Crystal parte 2


Instalado el compilador y probado. Podemos empezar a hacer nuestro primer proyecto.

Para poder continuar el post con un ide un poco más comoda que nano, voy a usar el visual code con un pluging para Crystal. Es muy fácil instalar esto, van a complementos y buscan Crystal :



Si conocen otra IDE mejor, por favor comenten. Gracias.

Ahora voy a la consola y voy hacer mi proyecto:

crystal init app MiPrimerApp

Esto creo todo un proyecto ya listo para usar con git y con dependencias, versión y todo lo necesario :

Por ahora y solo por ahora, vamos a hacer un "Hola mundo" . Editamos MiPrimerApp.cr y escribimos:

require "./MiPrimerApp/*"

module MiPrimerApp
  puts "Hola Mundo"
end

Luego en la consola entramos en la carpeta MiPrimerApp

cd MiPrimerApp

Ahora a ejecutar:

crystal deps

Para resolver las dependencias

crystal docs

Para generar la documentación. 

shards build

Para compilar todo. (luego hablaremos de shards)

Si todo fue bien, podemos entrar a la carpeta bin y ejecutar nuestra aplicación: 

 cd bin/
./MiPrimerApp 

Y listo!!



sábado, 6 de enero de 2018

Primeros pasos con Crystal

Ya instalado Crystal, vamos a comenzar haciendo un "Hola mundo"

Para hacer un ejemplo rápido vamos a utilizar la consola.

Primero con nano, vamos a hacer nuestro archivo que debe tener extensión .cr :

nano holaMundo.cr

Luego vamos a programar el hola mundo : 

puts "Hola Mundo"

Luego salimos y guardamos.

Ahora vamos a compilar y ejecutar: 

crystal holaMundo.cr

Si solo queremos ejecutar podemos hacer : 

crystal run holaMundo.cr 

Para generar un ejecutable debemos hacer : 

crystal build holaMundo.cr

Luego podemos ejecutar nuestro programa con : 

./holaMundo

Por defecto, los archivos ejecutables generados no están completamente optimizados. Para activar optimizaciones, se debe usar --release

crystal build holaMundo.cr --release

Si queremos no solo trabajar con un solo archivo sino hacer proyectos debemos utilizar el comando init pero eso sera en otro post. 

Instalar Crystal en Linux


Para instalar Crystal en Linux es muy fácil.

Vamos por pasos:

Primero, debe agregar el repositorio a su configuración APT. Podemos hacerlo con este comando:

curl https://dist.crystal-lang.org/apt/setup.sh | sudo bash

Eso agregará la clave de firma y la configuración del repositorio. Si queremos hacerlo manualmente, ejecutamos los siguientes comandos como root:

apt-key adv --keyserver keys.gnupg.net --recv-keys 09617FD37CC06B54
echo "deb https://dist.crystal-lang.org/apt crystal main" > /etc/apt/sources.list.d/crystal.list
apt-get update

Una vez que el repositorio está configurado, estamos listo para instalar Crystal:

sudo apt-get install crystal

Algunas veces necesitará instalar el paquete build-essential para ejecutar o construir programas Crystal. Puedes instalarlo con el comando:

sudo apt-get install build-essential

Y Listo!!

Dejo link: https://crystal-lang.org/docs/installation/on_debian_and_ubuntu.html