Archive for the 'Ciencia' category

Programación. ¿Ciencia o Ingeniería?

mar 09 2012 Published by under Ciencia, Pensamientos

Cuando inicié este blog, además de servir de soporte a algunos artículos técnicos sobre programación que fueran más o menos novedosos, también me movió la idea de aportar reflexiones sobre algunos temas interdisciplinares que constantemente me hacía debido a mi formación científica y que he ido acumulando durante todos estos últimos años. Creo que es momento de empezar con ellos…

En busca de la materia gris

Todavía persiste el mito de considerar que un informático es una especie de chamán que con unos cuantos pases mágicos delante de una pantalla es capaz de hacer que un ordenador tome vida. Muy pocos asumen que un informático pueda tener una formación científica o técnica seria que se encuentre al mismo nivel que un médico o un ingeniero. Y así nos van las cosas.

No tomarse en serio la formación de un informático está llevando a que muchas empresas del sector no valoren suficientemente la destreza de sus empleados. Asumen que siempre podrán encontrar nuevos empleados a los que poder darles una pequeña formación suficiente para encargarse de cualquier proyecto que tengan en marcha. Si supieran un mínimo de ingeniería, sabrían que siempre hay un límite en todo proyecto en el que añadiendo más recursos nunca se consigue acelerar el desarrollo, si no más bien lo contrario. Momentos de dificultad que desemboca en una crisis1, donde prima más la experiencia que la cantidad de manos disponibles.

La actual crisis económica ha venido a agravar más el panorama al minusvalorar aún más a los profesionales de informática. Los buenos profesionales optan por emigrar a otros países donde sean mejor considerados, mientras que aquí las empresas compiten bajando más y más los precios, sin tener en consideración ni la calidad ni la idoneidad del producto que desarrollan.

Estamos inmersos entre sistemas informáticos y de telecomunicaciones que se están colapsando debido a malos diseños y falta de mantenimiento, con usuarios que asumen por normal que un sistema pueda fallar, que los virus puedan entrar hasta las entrañas del ordenador, o que un hacker pueda bloquear cualquier sistema gubernamental y robar identidades,… y lo único que importa a los responsables es que alguna empresa sin escrúpulos asuma la culpa por el menor precio posible.

El fin de la ley de Moore

Es sabido que por la Ley de Moore en estos 50 años pasados, se estaba cumpliendo que cada dos años los ordenadores doblaban su velocidad, mientras se hacían cada vez más y más baratos. Como consecuencia, las aplicaciones mal diseñadas aún se podían sobrellevar gracias a la reducción de costes y mejoras de velocidad que ofrecían los nuevos sistemas.

Lamentablemente, la ley de Moore llega a su final. Se intenta prorrogar su vigencia metiendo más cores en cada cpu, pero si bien se sigue contando con procesadores más baratos y más rápidos, un sistema multicore no es aprovechable por una aplicación mal diseñada. Para aprovechar una cpu multicore, se requiere de nuevas aplicaciones diseñadas específicamente para ellos. Hoy en día, muchos sistemas operativos sólo son capaces de aprovechar un core de todos los disponibles, lo que no deja de ser un engaño para el usuario que piensa que debería ir todo más rápido. Estamos muy cerca de una nueva crisis similar a la crisis del software, pero con hardware esta vez.

Es una burbuja que pronto va a estallar como tantas otras antes.

Poner en valor al programador

Hace tiempo que se perdió el significado de ser un “programador”. Con ese nombre se ha pasado a denominar un puesto técnico de trabajo que está por debajo de analista y un poco por encima de reparador de hardware. Nada que tenga qué ver con un trabajo metodológico y, en cierta medida, creativo.

Y, sin embargo, contar con buenos programadores debería ser parte del activo de una empresa que la ponga en valor. No es entendible que haya empresas que busquen programadores después de haberse comprometido con un proyecto de desarrollo. Debería ser más bien al revés, que para conseguir un proyecto se haya valorado antes qué programadores dispone la empresa en nómina.

Puedo asegurar que hay alguna empresa que cuenta con un núcleo de buenos programadores, normalmente gente joven que montan su propia empresa, que nunca les falta trabajo. Pero son mucho más numerosas las empresas vacías que se dedican a quemar sistemáticamente a toda su plantilla en proyectos difíciles de asumir sin la gente y los medios adecuados.

Contar con programadores experimentados no es tarea fácil. Toda empresa debería asegurar a sus programadores más valiosos, nunca deberían considerarlos inferiores a analistas, ya que asumen roles distintos. Un buen programador puede ser un pésimo analista y viceversa. Un buen programador debería estar bien pagado simplemente como programador, y no verse presionado para ser analista si quiere ascender y cobrar más.

Programación. ¿Ciencia o Ingeniería?

Según donde busques, la programación es parte de la Ciencia de la Computación o es parte de la Ingeniería del Software. Personalmente, me inclino más por que sea una ciencia. Un buen programador siempre intenta comprender el funcionamiento de un programa con el fin de crear nuevos y mejores programas. Usa un ciclo de análisis, desarrollo, prueba y refactorización que tanto se parece al “método científico”, experimentando hipótesis hasta dar con una solución. La ingeniería entraría cuando se requiere que la aplicación se ajuste a determinados requisitos, donde a veces no importa tanto la optimización del programa como el que se ajuste su funcionamiento a los parámetros requeridos.

¿Es posible buscar la belleza entre líneas de código? ¿Evolucionamos hacia mejores lenguajes de programación?

Temas para próximos artículos.

6 responses so far

Estudio función factorial

jun 06 2011 Published by under Matemáticas, Python

Hace un tiempo me dió por recopilar distintas funciones en python para calcular el factorial. Aquí van todas, algunas bastante curiosas. Si conoces algún tipo más, no dejes de añadirla en los comentarios.

Versión recursiva

Todo programador ha tenido que ver esta definición como ejemplo de funciones recursivas :

def fact(n):
    if n==0:
        return 1
    else:
        return n*fact(n-1)

Se podría hacer algo más compacta usando el operador ternario:

def fact(n):
    return 1 if n==0 else n*fact(n-1)

Como toda función recursiva en python, existe el peligro de que nunca termine la función. Es el motivo por el que python tiene fijado un límite de recursividad dado por sys.getrecursionlimit(), que por defecto es de 1000 invocaciones recursivas o, lo que es lo mismo, que no podamos calcular factoriales mayores de 1000.

Podemos incrementar el límite con sys.setrecursionlimit(n), pero seguirá siendo una solución provisional. Lo mejor es pasarnos a una solución “iterativa”.

Versión iterativa

También es una de la funciones más conocidas por todo programador:

def fact(n):
    res=1
    for i in xrange(1,n+1):
        res*=n
    return res

Normalmente, todo lenguaje tiene un límite en el tamaño de un entero que hace que esta función no pueda calcular factoriales muy grandes. Pero python tiene la característica de pasar de entero a entero largo cuando así lo requiera la operación, lo que hace que se puede calcular cualquier número factorial, con el único límite de tiempo para calcularlo. Por lo general, con número grandes cuesta menos calcular el factorial que imprimirlos en pantalla.

Versión aproximada (función de Stirling)

Para número muy grandes, existe una aproximación llamada “Aproximación de Stirling” que se suele usar en mecánica estadística.

import math
def fact(n):
    return math.sqrt(2*math.pi*n)*math.pow(n/math.e,n)

Lamentablemente, los números reales (tipo double) son aquí una limitación de tamaño, por lo que no podemos hacer cálculos para números altos (precisamente, para los que teóricamente iba mejor esta función).

Versiones one-line

Muchas veces, los programadores se toman como reto poder expresar una fórmula compleja en una sóla línea, de modo que se pueda sustituir la llamada a la función por la definición de esta directamente. Son las llamadas funciones “oneline”.

reduce(lambda x,y:x*y,xrange(1,n+1),1)

Podemos aprovechar que tenemos el operador multiplicación y con ello evitar la función lambda (últimamente, en desuso):

import operator
reduce(operator.mul, xrange(1,n+1),1)

Algo más bizarro, evitando lambda y reduce:

[j for j in [1] for i in range(2,n+1) for j in [j*i]][-1]

Esta versión es en realidad un “reduce sin usar reduce”. Para entender cómo funciona, lo mejor es verlo como varios fors anidados:

def fact(n):
    for j in [1]:
        for i in range(2,n+1):
            for j in [j*i]:
                yield j

res=list(fact(n))[-1]

El primer for tan sólo sirve para dar una valor inicial a la variable j, y el tercer for sería el equivalente “oneline” de j=j*i.

En realidad, esta función no está muy optimizada ya que mantiene en memoria la lista completa de todos los resultados intermedios. Un modo más inteligente de usar esta expresión sería como un iterador, donde los resultados intermedios ya no son almacenados:

for res in (j for j in [1] for i in range(2,n+1) for j in [j*i]):
    pass

Aunque funciona perfectamente, no se puede considerar como función de una sóla línea. Para conseguirlo, tenemos que ir a algo totalmente críptico, incluyendo reduce y lambda, que acabaría siendo el siguiente engendro:

reduce(lambda x,y:y,(j for j in [1] for i in range(2,n+1) for j in [j*i]))

Actualización: Si queremos alguna solución sin reduce ni lambda, teniendo en cuenta que la función factorial es incremental, podemos emplear max() para obtener una versión con iterador de una sóla línea:

max(j for j in [1] for i in range(2,n+1) for j in [j*i])

¿Se os ocurren otras formas de expresar el factorial en una sóla línea?

6 responses so far

La paradoja de Monty Hall

mar 21 2011 Published by under Matemáticas

Este fin de semana me plantearon el conocido como Problema de “Monty Hall”. Que me perdonen los matemáticos y estadísticos, pero no estoy de acuerdo con su planteamiento ni con sus conclusiones (antes de seguir, recomiendo una lectura del problema).

Supongamos que el presentador actúa de la siguiente forma: cuando el concursante elige una puerta, se le permite optar entre quedarte con esa puerta o quedarse con el resto de puertas. Evidentemente, el concursante debería cambiar ya que la probabilidad aumenta cuanta más puertas tengas. Justamente, coincide con la solución probabilística que se da a este problema (2/3 de conseguir el coche) y es la razón por la que se debería cambiar siempre.

El error está en desconsiderar que cuando el presentador va abriendo (conscientemente) las puertas con cabra, la puerta elegida inicialmente también aumenta su probabilidad de tener un coche simplemente por el hecho de estar eliminando elecciones del planteamiento inicial, alcanzando el 50% cuando sólo quedan dos puertas (tal como nos indica nuestra intuición). Al eliminar puertas, estamos eliminando posibles fallos, lo que equivale a aumentar la posibilidad de que hayamos acertado en primera instancia. La decisión consciente del presentador está actuando sobre las condiciones iniciales del concurso y debe ser tenido en cuenta.

Pienso que este problema es confuso por el hecho de intentar aplicar métodos probabilísticos a un problema que no se rige enteramente por el azar. Si crees que estoy confundido, espero tus comentarios al respecto

14 responses so far