Showing posts with label OCaml. Show all posts
Showing posts with label OCaml. Show all posts

Tuesday, September 29, 2015

SAP HANA en la joraba de OCaml

Este post fué posteado originalmente en SAP HANA on the OCaml hump.


OCaml es un lenguaje de programación de fuerza industrial que soporta estilos funcional, imperativo y orientado a objetos.



Suena bonito, no? OCaml es el siguiente paso del Lenguaje de programación Caml.

Habiendo aprendido otros lenguajes de programación funcional como Haskell y Erlang, OCaml fué para mi la próxima opción obvia…así que decidí comenzar a aprenderlo…no fué una tarea fácil debo decirlo…pero realmente divertida y iluminadora.

Así que…ninguna demostración estaría completa si la enlazaramos con SAP HANA, so? Así que…vamos a hacerlo -;)

Primero, debemos crear un objeto Join y asociar la tabla por MANDT y CARRID. De ahí, seleccionar los siguientes campos como output MANDT, CARRID, CARRNAME, PRICE y CURRENCY.

Luego crear un objeto Aggregation seleccionándo los campos CARRNAME, PRICE (Como columnas agregadas) y CURRENCY. Debemos filtrar el campo CURRENCY por ‘USD’.

Luego, debemos crear un objeto Projection y seleccionar solo PRICE y CARRNAME.

En el objeto Semantics asegúrense de marcar  “CROSS CLIENT” como cliente por defecto.


Ahora, cambiemos a la vista SAP HANA Development y creemos un nuevo repositorio. Lo llamaremos“Flights”.

Creamos un proyecto “XS Engine” y también lo llamamos “Flights”. Lo enlazamos con el repositorio “Flights”.

Creamos un archivo vacio llamado “.xsapp”.

Creamos un archivo llamado “.xsaccess” con el siguente código.

.xsaccess
{
          "exposed" : true,
          "authentication" : [ { "method" : "Basic" } ]
}

Finalmente creamos un archivo llamado “flights.xsodata” con el siguiente código

flights.xsodata
service {
          "Blag/FLIGHTS_BY_CARRIER.calculationview" as "FLIGHTS" keys 
                                                        generate local "Id";
}

Activamos el proyecto y lanzamos nuestro browser...deberíamos ver algo como esto…


La parte de SAP HANA está lista…así que podemos pasar a la parte de OCaml…

Para los principiantes, OPAM (El manejador de paquetes de OCaml puede ser complicado y a veces frustrante), así que vamos a hacerles la vida más sencilla siguiendo estos simples pasos…en el terminal escriban esto…

• opam init
• eval `opam config env`
• opam switch 4.01.0
• eval `opam config env`
• opam install core utop core_extended async uri yojson cohttp lwt ezjsonm

Se va a demorar un poco, pero instalándo todos los paquetes requeridos en un solo comando previene que los errores ocurran.

Para programar en OCaml utilizo unos de los editores más asombrosos que he encontrado…Geany. viene pre-configurado para manejar una gran cantidad de lenguajes de programación, pero solo para estar seguros, aquí está como lo configuré para trabajar con OCaml.

Primero, creamos un archivo y lo grabamos como OCaml_HANA.ml

Luego, hacemos click en el botón “Choose more build actions”


La pequeña media flecha que está al lado del botón que parece un ladrillo marrón. Esto abrirá la siguiente pantalla


En "Compile" escriban lo siguiente

corebuild -pkg yojson,cohttp.async,cohttp.lwt,lwt,ezjsonm "%e.native"

Y en "Execute" pongan

“./%e.native”

Con esto, estaremos más que listos para comenzar a programar -:) Copien y peguen el siguiente código…

OCaml_HANA.ml
open Core.Std
open Yojson.Basic.Util
open Ezjsonm

let get_definition_from_json json =
 let json = Ezjsonm.from_string(json) in
 let json = Ezjsonm.(find json ["d";"results"]) in
 let json = Ezjsonm.to_string(json) in
 let json = Yojson.Basic.from_string(json) in
 let json = Yojson.Basic.Util.to_list json in
 let carrname = Yojson.Basic.Util.filter_member "CARRNAME" json in
 let carrname = Yojson.Basic.Util.filter_string carrname in
 let price = Yojson.Basic.Util.filter_member "PRICE" json in
 let price = Yojson.Basic.Util.filter_string price in
 printf "Reading SAP HANA from OCaml\n\n";
 for i = 0 to List.length(carrname) - 1 do
  printf "%s: %s\n" (List.nth_exn carrname i) (List.nth_exn price i)
done

let fetch uri =
 let cred = Cohttp.Auth.string_of_credential(`Basic("SYSTEM", "YourPassword")) in
 let headers = Cohttp.Header.init() in 
 let headers = Cohttp.Header.add headers "Authorization" cred in
 let open Lwt in
 Cohttp_lwt_unix.Client.get ~headers:headers uri 
 >>= fun (_,body) ->
 Cohttp_lwt_body.to_string_list body
 >>= fun strings ->
 return(get_definition_from_json (String.concat strings))  

let () =
  let hana_uri = Uri.of_string "http://YourServer:8000/Flights/flights.xsodata
                                /FLIGHTS?$format=json"
  in Lwt_main.run (fetch hana_uri)

Guarden su archivo, presionen el botón “Compile the current file”. El primer botón de la imagen anterior que muestra un triángulo con una flecha y una esfera (todo en un bonito 3D) y luego presionen el botón “Run or view the current file". El último botón de la imagen que muestra dos engranajes.


Notarán que se ejecuta bastante rápidamente…

Ahora…algo gracioso acerca de mi código…y debe ser por alguna de estas dos simples razones…

• Aún estoy aprendiendo OCaml
• La documentación para paquetes externos no es un muy extensa o simplemente no existe (En realidad, tuve que navegar por el código fuente en GitHub para poder realizar la mayoría del código)

Así que…la cosa graciosa es que estoy utilizándo dos librerías JSON diferentes para poder leer la información ODATA generada por SAP HANA…utilizándo solamente uno no podría manejar la información que necesitaba…así que utilizándo los dos y extrayendo las piezas de aquí y allá finalmente obtuve lo que quería…no es muy divertido cuando lo estás haciendo por primera vez…pero al final hay una gran recompenza cuando finalmente puedes compilar y obtener el outpur que quieres -;)

Saludos,

Blag.
Development Culture.

Thursday, March 19, 2015

Real World OCaml - Review del Libro

Finalmente terminé de leer el libro Real World OCaml...y realmente lo disfruté mucho -:)


Este libro como todos lo de la serie "Real World" te dá una introducción profunda al lenguaje y te permite comenzar a programar de una forma bastanta rápida...por supuesto...si ya has utilizado un lenguage de programación Funcional antes...eso realmente ayuda y OCaml tiene algunos aspectos que no son tan fáciles de aprender...


A medida que vayas leyendo este libro, más te va a gustar OCaml...es un lenguaje realmente muy bueno -:)

Este libro lo básico como Listas y Patrones, Registros, Variantes y Manejo de Errores.  Pero claro también más allá con Functors, Objectos y Parseo de Linea de Comandos...no dejándo de lado conceptos importantes como manejo de JSON y Programación Concurrente. Así que...es una muy completa referencia para poder empezar.

Por cierto...el libro tiene 509 páginas...así que es bastante extenso...pero lleno de ejemplos y demostraciones...

Aquí hay un pequeño código que escribí para "aplanar" listas -;)

Flat_List.ml
open Core.Std

let rec flat list =
 match list with
  | [] -> ""
  | head :: tail -> head ^ (flat tail)

let () = 
 printf "%s" (flat ["1";"2";"3"])

Aquí esta el resultado...


Como pueden ver...OCaml es divertido...así que no pierdan tiempo...lean el libro y expandan sus conocimientos -;)

Saludos,

Blag.
Development Culture.

Monday, March 02, 2015

LED es mi nuevo Hello World - Tiempo de OCaml

Aprender OCaml no es sencillo...debo admitirlo...pero estoy avanzando -;) Así que, aquí está mi versión de Numeros LED...

LED_Numbers.ml
open Core.Std

let get_leds number =
let leds = [0, [" _  ";"| | ";"|_| "];
            1, ["  ";"| ";"| "];
            2, [" _  ";" _| ";"|_  "];
            3, ["_  ";"_| ";"_| "];
            4, ["    ";"|_| ";"  | "];
            5, [" _  ";"|_  ";" _| "];
            6, [" _  ";"|_  ";"|_| "];
            7, ["_   ";" |  ";" |  "];
            8, [" _  ";"|_| ";"|_| "];
            9, [" _  ";"|_| ";" _| "]] in
 for i = 0 to 2 do
  for j = 0 to String.length(number) - 1 do
   let line = List.Assoc.find_exn leds 
        (int_of_string(Char.to_string(number.[j]))) in
   printf "%s" (List.nth_exn line i)
  done;
  print_string "\n"
 done
 
let () =
 print_string "Enter a number: "
 let num = read_line() in
 get_leds num

Lo gracioso es que al inicio intenté traducir my códigos pasados deJulia y Go...pero después de acordé de que aunque OCaml se puede utilizar hasta cierto punto como un lenguaje imperativo...su nucleo es en realidad Funcional...así que me dije...Ok...necesito reutilizar mi código en Haskell...pero de alguna forma empecé a pensar en una forma completamente nueva de hacer las cosas...y pienso que terminé con una forma mucho mejor y más clara...lo cual es algo que solo aprender un nuevo lenguaje de programación puede darte...una nueva forma de pensar acerca de viejos problemas -;)

Aquí están las imagenes como siempre -:)



Saludos,

Blag.
Development Culture.


Saturday, February 21, 2015

Mi primer post en OCaml

Luego de probar un poco de Programación Funcional con Erlang y Haskell sabía que era tiempo de seguir avanzándo hacia adelante -;) Esta vez...decidí aprender OCaml -:D

OCaml es un lenguaje de programación multi-paradigma, imperativo, funcional, orientado a objectos.

Por supuesto...Estoy leyendo un libro para aprenderlo -:) Así que van a ver mi review apenas termine de leerlo...


Mis primeras impresiones sobre OCaml es que se ve como Haskell...pero con algunas diferencias...lo cual hace que sienta extraño puesto que tiendo a programar en Haskell pero luego me doy cuenta de que hay algunas cosas muy diferentes...OCaml parece ser un lenguaje muy interesánte y bueno y por supuesto...no es tan puro como Haskell...

Como la mejor manera de aprender es programando...construí un generado de numeros Fibonacci...basado por supuesto en un código que ya había hecho en Haskell -;)

Fibonacci.ml
open Core.Std

let rec fib num a b = 
 match num with 
 | num when a > 0 && num > 1 -> string_of_int (a + b) ^ " " ^ fib (num - 1) (a+b) a
 | num when a = 0 -> string_of_int a ^ " " ^ string_of_int b ^ " " ^ 
                     string_of_int (a + b) ^ " " ^ fib (num - 1) (a+b) b
 | num -> ""
 
let () =
 print_string "Enter a number: "
 let num = read_int() in
 printf "%s" (fib num 0 1)

Cuando le ejecutemos...vamos a ver esto -;)



Saludos,

Blag.
Development Culture.