Mostrando las entradas con la etiqueta erlang. Mostrar todas las entradas
Mostrando las entradas con la etiqueta erlang. Mostrar todas las entradas

sábado, agosto 13, 2011

me gane una mochila un libro y un titulo de ingeniero en sistemas

dia de regalos, se anunciaron los ganadores del spawnfest y gane en la categoria "" por qrly

el premio es una mochila de erlang solutions y un libro de Erlang OTP in action (IRL!)

la UTN por haber aguantado 6 anios asistiendo a sus aulas le entrego a mi viejo por cuestiones geograficas (el E5 no llega hasta Inglaterra todavia) un titulo de ingeniero en sistemas de informacion.

demasiados premios para un dia

lunes, julio 11, 2011

Qrly - selectores a lo jquery para XML y HTML en erlang

este fin de semana fue el spawnfest, un evento en el que tenes dos días para hacer una aplicación en erlang que sera juzgada por grosos del lenguaje y de yapa con interesantes premios.

estaba inscripto hace como 5 meses pero coincidio con un viaje a praga.

si bien era viaje de trabajo y ya estuve en praga dos veces antes, da un poco de cosita pasarse el finde encerrado en lugar de salir a pasear.

así que hice un equilibrio y le dedique el tiempo que consideraba que de todas formas estaba al pedo/cansado (aka a la maniana y a la tardecita) y salio qrly.

el proyecto esta en github aca:

https://github.com/marianoguerra/qrly

si bien no lo termine completamente quedo bastante util, los filtros que faltan son mas avanzados y ya tendre tiempo de agregarlos.

en resumen y siendo esta mi tercera aplicación útil en erlang (efene, fnt y qrly) continuo pensando que es un lenguaje muy copado y potente, me sorprende lo mucho que se logra con pocas lineas de codigo.

en lo malo, si bien la sintaxis ya no me molesta y hasta podria decir que me gusta, lo que me sigue molestando es los 3 tipos de puntuación para delimitar sentencias, el problema no es usarlos sino tener que cambiarlas cuando uno mueve o agrega codigo. Por ultimo, TDD se hace un poco molesto si uno agrega el paso de compilar (python me maleduco en esto ;)

sobre el final, me quedaban unos minutos asi que hice un ejemplo muy simple de como usarlo llamado oliver, que es un parser de atom.



por ultimo, no podia irme sin presentarles a la mascota del projecto "Qrly the bird"


como siempre, ayuda mas que bienvenida, la licencia es BSD.

esto fue qrly para sega genesis, espero que les haya gustado

ACTION!

martes, mayo 18, 2010

pynerl

tras unas horas de codear, tengo la primera version de pynerl, un modulo en erlang que permite ejecutar python y obtener los resultados en erlang.

mas facil si lo explica xzibit.



el proyecto esta hosteado en github aca:

http://github.com/marianoguerra/pynerl

un ejemplo:

1> pynerl:eval("t = 1", "t").
1
2> pynerl:eval("t = 1 * 2", "t").
2
3> pynerl:eval("import time;t = time.time()", "t").
1274236802.877999
4> pynerl:eval("import random;t = random.random()", "t").
0.45102117275294684
5> pynerl:eval("t = print('hello erlang or python')", "t").
hello erlang or python
none
6> pynerl:call("time", "time", []).
1274236859.510859
7> pynerl:call("random", "random", []).
0.9623136682858975
8> pynerl:eval("t = True", "t").
true
9> pynerl:eval("t = 2.3", "t").
2.3


como ves las dos funciones principales son eval y call, que hacen lo que esperarias, eval evalua una expresion y devuelve el valor de la variable que pases como segundo parametro. call llama a la funcion dentro del modulo pasandole los parametros del tercer argumento y devuelve el resultado.

El estado actual es alpha, el mapeo de tipos funciona solo para los tipos basicos y el paso de parametros en call todavia no esta implementado (simplemente porque lo empece hace 2 horas :P).

Como es la primera vez que programo python y erlang internamente seguro que estoy leakeando por todos lados, se va a resolver cuando lea un poco mas.

evaluando python desde erlang

y el secreto se develo, como tener algo como eval de python pero corriendolo desde erlang.

el codigo no es lo mas bonito de la tierra pero ya va a ir mejorando.

primero que todo bajate erlang R13B04 para tener la ultima version de la API de NIF.

crea un archivo pynerl.c

/* pynerl.c */
#include <stdio.h>
#include "erl_nif.h"
#include <Python.h>

#define STR_SIZE 1024
char code[STR_SIZE];

static ERL_NIF_TERM pyeval(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
Py_Initialize();

if (enif_get_string(env, argv[0], code, STR_SIZE, ERL_NIF_LATIN1) < 0) {
return enif_make_string(env, "code too long", ERL_NIF_LATIN1);
}
else {
PyRun_SimpleString(code);
}

Py_Finalize();

return argv[0];
}
static ErlNifFunc nif_funcs[] =
{
{"pyeval", 1, pyeval}
};

ERL_NIF_INIT(pynerl,nif_funcs,NULL,NULL,NULL,NULL)


y uno llamado pynerl.erl

-module(pynerl).
-export([init/0, pyeval/1]).

-on_load(init/0).

init() ->
erlang:load_nif("./pynerl", 0).

pyeval(_Str) ->
"NIF library not loaded".


despues compila ambos:


gcc -fPIC -shared -o pynerl.so pynerl.c -I $ERL_INCLUDE -I/usr/include/python3.1/ -D_THREAD_SAFE -lpthread -ldl -lutil -lpython3.1 -lm
$ERLC pynerl.erl


en mi caso


$ echo $ERL_INCLUDE
/home/mariano/Software/otp_src_R13B04/erts/emulator/beam
$ echo $ERLC
/home/mariano/Software/otp_src_R13B04/bin/erlc


despues de eso lo probamos


$ $ERL
Erlang R13B04 (erts-5.7.5) [source] [rq:1] [async-threads:0] [kernel-poll:false]

Eshell V5.7.5 (abort with ^G)
1> pynerl:pyeval("print('hello python 3.1 from erlang!')").
hello python 3.1 from erlang!
"print('hello python 3.1 from erlang!')"


observaciones:

uso $ERL porque tengo dos versiones de erlang instalando, esa variable apunta al erlang mas nuevo que tengo compilado.

la primera linea de salida es la ejecucion de la linea, la segunda es el string que le pase como parametro, que es lo que devuelve por ahora pyeval, algun dia va a devolver el objeto que devolvio la evaluacion (mientras sea algo que pueda ser convertido a un tipo de erlang).

implementar una function en C y llamarla en erlang

Si leiste el post anterior y este podes empezar a formarte una idea de lo que quiero hacer.

para poder llamar codigo de C en erlang hay que hacer un NIF (native implemented functions), estoy siguiente el ejemplo del manual de erlang pero como tiene un error pongo el codigo aca.

creamos un archivo niftest.c y ponemos el siguiente codigo

/* niftest.c */
#include "erl_nif.h"
static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_string(env, "Hello world!");
}
static ErlNifFunc nif_funcs[] =
{
{"hello", 0, hello}
};
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)



creamos niftest.erl (tranquilamente se podria hacer en efene :D)

-module(niftest).
-export([init/0, hello/0]).
init() ->
erlang:load_nif("./niftest", 0).
hello() ->
"NIF library not loaded".


compilamos


gcc -fPIC -shared -o niftest.so niftest.c -I/usr/lib/erlang/erts-5.7.4/include/


y lo probamos


$ erl
cErlang R13B03 (erts-5.7.4) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4 (abort with ^G)
1> c(niftest)
1> .
{ok,niftest}
2> niftest:hello().
"NIF library not loaded"
3> niftest:init().
ok
4> niftest:hello().
"Hello world!"
5>


vamos avanzando

domingo, julio 19, 2009

Resolviendo ejercicios de MPI(y tambien en erlang)

Como tarea en un grupo de la facultad del que formo parte tenemos que resolver ejercicios de MPI, como yo algo de idea de MPI tengo decidí también resolverlos en erlang para seguir aprendiendo mas de este lenguaje, acá van los enunciados del primer ejercicio y las resoluciones de ambos.

Write a program that uses MPI and has each MPI process print
Hello world from process i of n
using the rank in MPI_COMM_WORLD for i and the size of MPI_COMM_WORLD for n. You can assume that all processes support output for this example.

el ejercicio en C lo pueden ver en el post anterior así que acá pego el de erlang nomas

-module(ej1).
-export([run/1]).

run(Total, Total) -> ok;
run(Count, Total) ->
spawn(fun() -> salute(Total) end),
run(Count + 1, Total).

run(Total) -> run(0, Total).

salute(Total) ->
io:format("Hello world from ~p of ~p~n", [self(), Total]).


como en erlang no hay una forma de saber cuantos procesos totales hay dando vueltas (o al menos no es tan estatico como MPI) decidi pasarle el total y imprimir el PID.

para correrlo y ver la salida la forma facil es:

$ erl ej1.erl
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.6.5 (abort with ^G)
1> c(ej1).
{ok,ej1}
2> ej1:run(4).
Hello world from <0.42.0> of 4
Hello world from <0.43.0> of 4
Hello world from <0.44.0> of 4
Hello world from <0.45.0> of 4
ok
3>

todo en orden, vamos a por el segundo

como nota al margen, donde hice el pattern matching de

run(Total, Total) -> ok;

podria haber hecho

run(0, _Total) -> ok;

y contar al reves en

run(Count + 1, Total).

por

run(Count - 1, Total).

pero me parecio mas simpatico contar para adelante :P

viernes, mayo 08, 2009

Project Euler problema 6

Lo lei, hice un oneliner en python y no lo corri porque pense que iba a demorar mucho, trate de recordar alguna propiedad pero no me acorde nada, buscando en internet todas eran resoluciones de project euler asi que decidi correrlo por fuerza bruta, termino siendo rapido asi que no me esforce mas:

problema:

The sum of the squares of the first ten natural numbers is,

1^(2) + 2^(2) + ... + 10^(2) = 385

The square of the sum of the first ten natural numbers is,

(1 + 2 + ... + 10)^(2) = 55^(2) = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.



python:

>>> sum(xrange(1, 101)) ** 2 - sum(map(lambda x: x**2, xrange(1, 101)))
25164150

lisp:

[44]> (- (expt (apply #'+ (loop for x from 1 to 100 collect x)) 2) (apply #'+ (loop for x from 1 to 100 collect (expt x 2))))
25164150

erlang:

-module(ej_006).
-export([show/0]).

do_to_range(Stop, Stop, Accum, Fun) -> Accum + Fun(Stop);
do_to_range(Start, Stop, Accum, Fun) ->
do_to_range(Start + 1, Stop, Accum + Fun(Start), Fun).

show() ->
SumOfSquares = do_to_range(1, 100, 0, fun(X) -> X * X end),
SquareOfSums = math:pow(do_to_range(1, 100, 0, fun(X) -> X end), 2),
SquareOfSums - SumOfSquares.



observaciones:
  • encontre esta referencia de lisp: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node81.html
  • la exponenciacion en lisp se hace con expt
  • no encontre algo como xrange asi que use el macro de for
  • no me gusta la cantidad de funciones que hay en lisp (y en un solo namespace! :P)
  • en erlang lo hice un poco mas prolijito porque lo tuve que hacer recursivo
  • si no fuera por que python no tiene notacion prefija, la resolucion seria casi igual (si hiciese una funcion range con los for)

viernes, febrero 20, 2009

project euler - problema 5

Hasta ahora a todos los problemas los venia resolviendo por fueza bruta aplicando algunas optimizaciones (para que no sea tan bruto vio?), pero decidi ejercitar un poco mis conocimientos matematicos para intentar resolverlo puramente con matematicas o al menos eliminar muchas cosas innecesarias.

el problema 5 es este:

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?

agarre un lapiz y un papel (posta!) y me puse a pensar un poco.

Lo primero que probe (fuerza bruta matematica) es el producto de los numeros del 1 al 20 es divisible por todos ellos, el problema es que no es el mas chico.. entonces pense un poco mas. Porque no es el mas chico? bueno, porque ahi hay muchas multiplicaciones innecesarias, si es multiplo de 20 es tambien multiplo de 10, 5, 4 2 etc.

despues de eso llegue a la conclusion de que el numero era el producto de los numeros del 11 al 20, pero resulto no ser asi, pense un rato mas y no se me ocurrio nada asi que decidi darle mi problema acotado a python, lo que hice a grandes rasgos fue.

incrementar de a 380 el contador (producto de 20 y 19), y ya que incremento en multiplos de 20 y 19 no me hace falta controlar que sean multiplos de ellos, por lo tanto hice una lista de numeros del 18 al 11 ya que los numeros mas chicos se comprueban comprobando esos. Puse los numeros al reves ya que si el numero divisor es mas grande tiene menos numeros multiplos, por lo tanto al cortar al encontrar un numero no divisor en los numeros mas grandes me ahorro algunos calculos innecesarios.

cuando entre a las soluciones vi que la solucion del problema tenia que ver con multiplicar numeros, pero no los numeros en si, sino las potencias mas altas de los primos de la factorizacion del 1 al 20. (aca esta la explicacion http://mathforum.org/library/drmath/view/62527.html)

y bue, tan bueno en la matematica no soy :D

codigo en python

NUMS = [float(x) for x in range(11, 19)]
NUMS.reverse()

def first_multiple_from_1_to_20():
num = 380

while True:
for x in NUMS:
if num % x != 0:
break
else:
return num

num += 380

num = first_multiple_from_1_to_20()

print num


erlang

-module(ej_005).
-export([first_multiple_from_1_to_20/0]).

is_multiple_from_11_to_18(_Value, 10) -> true;
is_multiple_from_11_to_18(Value, Number) ->
case Value rem Number == 0 of
true -> is_multiple_from_11_to_18(Value, Number - 1);
false -> false
end.

is_multiple_from_11_to_18(Value) -> is_multiple_from_11_to_18(Value, 18).

first_multiple_from_1_to_20(Count) ->
case is_multiple_from_11_to_18(Count) of
true -> Count;
false -> first_multiple_from_1_to_20(Count + 380)
end.

first_multiple_from_1_to_20() -> first_multiple_from_1_to_20(380).



lisp

(defun is-multiple-from-11-to-18 (value)
(= (loop for i from 18 downto 11 by 1
while (= (mod value i) 0) finally (return i)) 10))

(defun first-multiple-from-1-to-20 ()
(loop for i from 380 by 380
while (not (is-multiple-from-11-to-18 i))
finally (return i)))

(print (first-multiple-from-1-to-20))

Seguidores

Archivo del Blog