Jorge Dieguez Blog
SherPoint Customization Best Practices
Mayo 31st, 2008 - [Enlace local]
SharePoint es una tecnología que ofrece a los usuario de negocio un marco de trabajo flexible, adaptable, fácil de usar que permite gestionar la información, facilitar la colaboración y facilitar la participación de personas en procesos de negocio.
Este marco de trabajo esta compuesto por una multitud de componentes, cuando un usuario de SharePoint necesita resolver alguna necesidad solo tiene que combinar los componentes de una forma determinada.
Por ejemplo para habilitar un repositorio de documentos el Consultor:
- Creara y configurara el sitio
- Creara la biblioteca de documentos
- Creara los tipos de contenido
- Configurara las vistas
- Aplicara la seguridad
- Creara las paginas y las configurara con distintos WebParts
En este punto se podrá dar acceso a personas del negocio para que usen esta solución, publiquen nuevos documentos, los etiqueten, realicen búsquedas y consuman los documentos.
SharePoint es un marco de trabajo que permite por otro lado que los desarrolladores añadan nuevos componentes, extiendan o personalicen los existentes. Por ejemplo crear nuevas paginas maestras, webparts, plantillas de sitio, etc.
En MSDN encontramos un interesante apartado que recoge la lista de los elementos que pueden ser creados, modificados, extendidos. Cada elemento de la lista cuenta con una descripción, un ejemplo funcional, detalle técnico.
Es importante que al plantear una solución basada en SharePoint se revise esta lista y se encuentren el/los componente/s mas apropiados para el caso en cuestión. Al final lo bonito es que el nuevo componente pueda re utilizar múltiples veces.
» Leer más, comentarios, etc...
Jorge Dieguez Blog
SherPoint Customization Best Practices
Mayo 31st, 2008 - [Enlace local]
SharePoint es una tecnología que ofrece a los usuario de negocio un marco de trabajo flexible, adaptable, fácil de usar que permite gestionar la información, facilitar la colaboración y facilitar la participación de personas en procesos de negocio.

Este marco de trabajo esta compuesto por una multitud de componentes, cuando un usuario de SharePoint necesita resolver alguna necesidad solo tiene que combinar los componentes de una forma determinada.

Por ejemplo para habilitar un repositorio de documentos el Consultor:
- Creara y configurara el sitio
- Creara la biblioteca de documentos
- Creara los tipos de contenido
- Configurara las vistas
- Aplicara la seguridad
- Creara las paginas y las configurara con distintos WebParts

En este punto se podrá dar acceso a personas del negocio para que usen esta solución, publiquen nuevos documentos, los etiqueten, realicen búsquedas y consuman los documentos.
SharePoint es un marco de trabajo que permite por otro lado que los desarrolladores añadan nuevos componentes, extiendan o personalicen los existentes. Por ejemplo crear nuevas paginas maestras, webparts, plantillas de sitio, etc.
En MSDN encontramos un interesante apartado que recoge la lista de los elementos que pueden ser creados, modificados, extendidos. Cada elemento de la lista cuenta con una descripción, un ejemplo funcional, detalle técnico.
Es importante que al plantear una solución basada en SharePoint se revise esta lista y se encuentren el/los componente/s mas apropiados para el caso en cuestión. Al final lo bonito es que el nuevo componente pueda re utilizar múltiples veces.
» Leer más, comentarios, etc...
Javier Perez
Perfiles existentes en el desarrollo web
Mayo 31st, 2008 - [Enlace local]
En el mundo del desarrollo web existen una serie de perfiles, a veces no muy bien diferenciados ni separados. Incluso los perfiles, más que perfiles, son considerados roles que pueden ser asignados a trabajadores de una empresa.
Ni siquiera los que trabajamos en esto desde hace años nos ponemos de acuerdo en nomenclaturas, definiciones, y alcances de cada uno de los perfiles, así que tampoco pretendo dar una definición universal de cada uno, sino más bien mostrar mi visión de lo que es cada perfil en base a mi experiencia y mi opinión profesional.
Maquetador
El maquetador debe convertir un diseño hecho por los diseñadores, normalmente varios ficheros Photoshop, en páginas estáticas XHTML/CSS con las imágenes recortadas en formatos adaptados para la web.
Con el tiempo este trabajo se convierte en muy mecánico y aburrido, y de hecho, normalmente, este perfil es únicamente un trampolín de acceso a un perfil programador servidor. Cuando se domina por completo XHTML y CSS, se empieza a trabajar con lenguajes de servidor, como PHP.
Dependiendo de la capacidad y experiencia del maquetador, puede hacer las funciones de programador cliente, es decir, programará algunas funciones en Javascript, como validaciones de campos de formularios, algunos efectos DHTML, etc.
Este trabajo, en ocasiones, dependiendo de la capacidad de la empresa, es ocupado por el diseñador, quien debe diseñar y maquetar, entregando al programador servidor su trabajo.
Programador cliente
El programador cliente es un peldaño más que el maquetador. No sólo domina la maquetación en XHTML y CSS, sino que además domina Javascript y la modificación del DOM (DHTML).
Es un perfil en desuso y a extinguir, ya que el dominio de Javascript y la manipulación del DOM es algo que cada vez más se le exige (o se le debería exigir) al programador servidor, y más aún a los desarrolladores web, debido a la estrechez que separa a ambos entornos; por ejemplo, crear un servicio web en PHP para que sea consumido por AJAX: es el programador servidor, el creador del servicio web en PHP, quien debería desarrollar también el cliente en AJAX (programación cliente), que aunque no tenga que ser extrictamente necesario, ahorra mucho tiempo de desarrollo.
Aún así, muchas empresas continúan usando los servicios de este perfil, aunque es del todo desaconsejable pretender especializarse en este perfil si valoramos nuestro futuro profesional.
Programador servidor
Los buenos suelen ser considerados frikis, excepto por las grandes empresas, quienes les dan los más grandes sueldos de la empresa y lujosos chalets en California...
Aunque ciertamente el mundo de los programadores servidor es un mundo extraño y diverso. Hay buenos y mediocres; los hay quienes disfrutan como un enano con su trabajo, y los hay quienes lo odian o no saben y se meten a Jefes de Proyecto; hay quien programa de verdad, y hay quien se sumerge en sitios oscuros...
El programador servidor sólo tiene que hacer una cosa: programar. Pero debe hacerlo bien, muy bien, sin errores. Si un proyecto sale mal, todos mirarán al programador servidor. Y si sale bien, será el último mono en ser felicitado. Es un trabajo muy mal reconocido, aunque muy gratificante si realmente disfrutas programando.
Un programador servidor (de web) debería tener al menos unos conocimientos medios de XHTML, CSS, y Javascript/DOM.
Al contrario que los diseñadores, los programadores, por norma general, visten camisetas frikis, y además feas. Y aunque exista el mito de que el programador suele ser un tipo antisocial incluido con las personas del sexo contrario, lo cierto es que no es así, y como prueba tenemos su variado argot, donde se pueden encontrar cosas tan sensuales como: "modelo de datos", "entidad relación", "control de flujo", "inyección escuel", etc., que a la luz de unas velas con un buen vino no hay mujer que se resista...
Desarrollador web
Podríamos ver al perfil de desarrollador web como un contenedor de perfiles... un desarrollador web hace de todo, y muy bien: maqueta, programa en cliente y en servidor, e incluso puede hacer diseños, dependiendo de la capacidad artística de cada uno. No basta con que sepa un poco de HTML y un poco de PHP. Es decir, como el mismo nombre induce a entender, un desarrollador web es un experto en desarrollo web, y debe dominar todas las tecnologías que convergen en una web. Es el desarrollador total.
En mi opinión, una empresa que se dedique a crear tecnología web, no debería tener perfiles maquetadores, ni programadores clientes, ni programadores servidor, es decir, no debería hacer esas divisiones de trabajo, sino únicamente contar con perfiles desarrolladores web, juniors y seniors. Aunque desgraciadamente seguimos arrastrando viejos vicios de la web 1.0, aquella que desapareció en una burbuja, o casi...
Estos perfiles son considerados simplemente programadores de alto nivel, aunque yo prefiero etiquetarlos y definirlos como desarrolladores web.
Por supuesto, el desarrollador web no viste camisetas frikis, sino que es un señor elegante que normalmente va de traje y corbata.
Administrador
Este perfil es fundamental y muy importante en toda empresa que se dedique a trabajar sobre Internet. Debe haber una persona que se encargue de configurar servidores (web, correo, ftp, ssh, mail, etc.), mantener la red (LAN, ADSL/Cable, Impresoras, etc.), establecer políticas de seguridad/acceso, crear y configurar bases de datos, etc.
Un programador, por ejemplo, no debería perder su tiempo en instalar y configurar una Debian con LAMP en el hosting dedicado del cliente, ni haciendo copias de seguridad de la base de datos, ni preocupándose de actualizar los paquetes con fallos de seguridad, etc.
El administrador, por norma general, es el que mejor vive de toda la empresa, incluido el director general de no ser porque éste gana más dinero. Se pasan el día viendo páginas porno sobre administración de servidores y cosas de esas, o incluso, en ocasiones, trabajando, y cuando necesitas de sus servicios, obviamente, te contestan que están muy ocupados...
Son unos maestros en culpar a la red de todo... si algo falla, la culpa es de la red, que es una mierda. Algo que es muy comprensible trabajando en un país como España, con esta maravillosa infraestructura de redes tan baratas de tan alta velocidad españolas.
Son los protagonistas de la mundialmente (mundo de los IT-frikis) conocida serie IT Crowd.
Diseñador
También conocidos como diseñatas (habla un programador)... tienen la rara habilidad de parecer frikis y cool a la vez. Visten camisetas extrañas que sólo usaría un friki, pero como son bonitas, pues no pasa nada...
Los hay buenos, y los hay muy buenos. A los malos no los quiere nadie, e incluso de pequeños sus madres les daban la espalda en lugar del pecho.
El diseñador es el que puede alardear de haber hecho una web, aunque su trabajo "sólo" haya consistido en darle forma y maquillaje, ya que es lo que el homo sapiens sapiens ve. Y es que es muy humillante para un programador que, después de tratar de explicar durante un buen rato a un amigo ajeno a la profesión en qué consiste su trabajo, tenga que recurrir finalmente a "nada, nada, olvídalo, que soy diseñador web".
Jefe de Proyecto
Los Jefes de Proyecto son los encargados de diseñar el plan de trabajo, es decir, son los que crean el famoso Project, junto con los analistas. Deciden la división de procesos en tareas, los tiempos de desarrollo que llevará cada tarea, quién se encargará de cada una, etc.
Algunas empresas tienen un perfil Jefe de Proyecto confundido con el de Comercial o Gestor de Cuentas, que, en mi opinión, desliga a este perfil de la tecnología, llevándolo hacia el terreno del márketing. Por lo tanto ese perfil más comercial y menos técnico no entra dentro de este artículo.
Hay dos tipos de Jefes de Proyecto (técnico), los que fueron malos programadores y/o no les gustaba programar, y los que fueron buenos programadores (a día de hoy no se conoce de la existencia de un Jefe de Proyecto que lo fuera).
Los Jefes de Proyecto que saben programar se dedican a programar en el proyecto una vez terminó la primera fase de análisis y planificación. Y en ocasiones (la mayoría) Jefe de Proyecto, Analista, y Programador Servidor son una misma persona.
Este perfil no tiene una vestimenta común, por lo que son difícilmente reconocibles a simple vista, e incluso es posible que debido a esa falta de frikez textil pasen por personas totalmente ajenas a la informática.
Analista
El perfil de Analista es normalmente ocupado por los programadores servidor o desarroladores web. Es el encargado de realizar el análisis de un proyecto: toma de requisitos, y planificación junto con el Jefe de Proyecto, si es que existe.
Otros
User Experience (UX), Animadores, Comerciales, Soporte, Mantenimiento... Animo a mis lectores a que definan otros perfiles que intervienen en el desarrollo de aplicaciones web.
¿Y tú qué perfil eres?
» Leer más, comentarios, etc...
soft·in·spain
Firefox 3
Mayo 31st, 2008 - [Enlace local]
Hoy he actualizado el Ubuntu que tengo en el portátil y se ha actualizado el Firefox, parece que ya no es la Beta 5 sino la definitiva, pero en la web de Mozilla no dice nada, por lo que no lo se. En el “Acerca de…” no dice nada de beta por lo que entiendo que es la definitiva.
Por cierto, cada vez más contento con Ubuntu, no he echado de menos Windows en este tiempo. Pero sobre el tema quiero escribir otro artículo más extenso.
» Leer más, comentarios, etc...
Bitácora de Javier Gutiérrez Chamorro (Guti)
Ventajas ocultas de x64
Mayo 31st, 2008 - [Enlace local]
A estas alturas, y aunque el apoyo de la industria no es el adecuado, parece que a nivel general quien más y quien menos es consciente de las ventajas que aporta la arquitectura x86-64 sobre la x86. A saber, soporte de instrucciones generales de 8 bytes, y la posibilidad de direccionar cantidades de memoria más grandes.
Sin embargo son mucho menos conocidas algunas ventajas añadidas de esta arquitectura. La más evidente es que en las CPU que soportan x64, las instrucciones extendidas como SSE están siempre disponibles, por lo que la mayoría de herramientas de desarrollo tomarán ventaja de este hecho, generándolas cuando pueda resultar ventajoso. En cambio si nos movemos en 32 bits, la mayoría de programas no las usarán, al poder no estar disponibles en determinado procesador, o bien debido a la complejidad adicional a nivel de desarrollo que requiere detectar las capacidades de la CPU, y ejecutar fragmentos optimizados para él en tiempo de ejecución.
Obviamente no es una ventaja absoluta, pues aunque pocas, hay aplicaciones de 32 bits que requieren y utilizan SSE (principalemente juegos), y algunas otras que si están disponibles esas extensiones las utilizan (mayoritariamente desarrollos con Intel C++/Fortran.
Los procesadores que soportan x86-64, además del citado duplicado en el tamaño de registros que les permiten gestionar mayores bloques de memoria, y realizar operaciones con datos más grandes, incluyen ciertas mejoras a nivel de arquitectura. Por un lado son procesadores de generaciones más nuevas que los de 32 bits, lo que hace que las instrucciones suelan estar más optimizadas, y por tanto requieran menos ciclos de reloj para ser ejecutadas. Esto quiere decir, que a igualdad de frecuencia (Ghz), normalmente un procesador de 64 bits ejecutará los programas más velozmente que uno de 32. Esto es válido tanto para programas de 32 como de 64 bits. Pero es que además, incluyen nuevos registros internos, que solamente una aplicación diseñada para estas arquitecturas podría explotar, evitando accesos a memoria redundantes, y por tanto mejorando el rendimiento general.
Otro punto ventajoso muy a tener en cuenta, y probablemente el más importante de todos es el nuevo convenio de llamadas a funciones en Win64: X64, en contraposición a stdcall de Win32. Gracias a los nuevos registros, las llamadas a funciones, tanto del sistema, como del propio programa, pueden pasar los parámetros usando los nuevos registros, en vez de utilizar la memoria de pila como se hacía tradicionalmente. Esto redunda, que sin ningún cambio, las llamadas a procedimientos y funciones, son más eficientes en la nueva arquitectura.
Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti) - http://guti.bitacoras.com.
» Leer más, comentarios, etc...
niko's mini factory
Links for 2008-05-30 [del.icio.us]
Mayo 31st, 2008 - [Enlace local]
» Leer más, comentarios, etc...
PHP Senior
SURFORCE-CMS: solicitud de colaboración para hacer testing y refactoring
Mayo 30th, 2008 - [Enlace local]
El proyecto SURFORCE-CMS está en su primera versión "madura" por decirlo de alguna manera (¿1.0?), pero quedan algunos pendientes que me preocupan:
- El primero, hacer refactoring del código que genera el menú, ya que actualmente es "estructurado" y con mucho "hardcode" (fue uno de los primeros códigos que se implementaron cuando empezamos con el CMS, cuando no teníamos nada de experiencia en Zend).
- Segundo, hacer el testing de la aplicación en general, reportando bugs para que los solucionemos. Por ejemplo, un colega me reportó que al crear un sub-sitio / sección (ABM Sitios) si no le ingresa la "url home" del mismo (la página por defecto) el sitio no arranca y da un error.
Hay muchos detalles como estos que están para resolver, así como ver qué partes no se entienden o no están del todo correctas (tanto funcionales como internas del código) y mejorarlas.
Cada quien encuentre un bug iré autorizando los permisos para que puedan subir el código al svn y pasar a la fama como parte del proyecto (bueno, por lo menos aparecerán en el listado del proyecto en Google Code ;-)
Espero comentarios al respecto.
» Leer más, comentarios, etc...
EsLoMas.com
Mejoras destacables en MythTV y Ubuntu
Mayo 30th, 2008 - [Enlace local]
Hace unos meses publiqué una entrada en la que explicaba como configurar MythTV con Ubuntu y una tarjeta Hauppage WinTV Nova-T-500. La arquitectura que monté en su día se basa en un servidor de archivos Linux en el que instalé el backend de MythTV y la tarjeta con los dos sintonizadores. La parte frontend consta de un Mac Mini conectado a la televisión por HDMI y un portátil con Ubuntu, ambos con el frontend de MythTV. Los frontends son capaces de acceder a la programación de TV del servidor, así como a los recursos multimedia como música, vídeos y fotos del servidor a través de conexiones NFS.
Desde que escribí esos artículos he utilizado este sistema prácticamente a diario, principalmente para la visualización de videos. Sin embargo me he encontrado con bastantes problemas con la parte de visualización de la TV, en parte por problemas con el modulo dvb de Linux y en parte por la mala calidad de la señal que llega hasta mi casa. Además también he tenido bastantes problemas a la hora de configurar la visualización de videos en el Mac Mini, que hacía con el Mplayer, ya que aunque me permitía ver los vídeos sin problemas, no me dejaba ni pausarlos ni volver al menú una vez empezada la visualización.
Sin embargo con la reciente llegada de Ubuntu 8.04 Hardy Heron y MythTV 0.21, todo esto se ha resuelto y ya dispongo de una infraestructura completamente satisfactoria.
» Leer más, comentarios, etc...
Infectogroovalistic
Ubuntu 8.04 con Compiz sobre AIGLX para ATI
Mayo 30th, 2008 - [Enlace local]
Con los nuevos drivers fglrx para placas de video ATI, ya podemos disfrutar de Compiz haciendo unos simples toques al archivo /etc/X11/xorg.conf
Lo que debemos hacer es dejar las secciones de nuestro xorg.conf con las siguientes opciones (las que estan en rojo)
Section "Module"
Load "dri"
Load "v4l"
Load "dbe"
Load "glx"
EndSection
Section "Device"
Identifier "Generic Video Card"
BusID "PCI:1:0:0"
Driver "fglrx"
Option "AIGLX" "true"
EndSection
Section "DRI"
Mode 0666
EndSection
Section "Extensions"
Option "Composite" "Enable"
EndSection
Y listo, el resto de las secciones no necesitan tocarse.
Una vez que hacemos esto, reiniciamos (el servidor X) e instalamos compiz desde Synaptic o desde tu administrador de paquetes preferido.
Luego en el menu: Sistema->Preferencias->Apariencia, en la solapa "Efectos" activamos los efectos de escritorio y ya, debería estar funcionando.
» Leer más, comentarios, etc...
programania
Ez Components junto a Zend Framework
Mayo 30th, 2008 - [Enlace local]
Al grano, ésta es la manera de integrar los Ez Components con el ZF durante el bootstraping:
require_once "Base/base.php";
spl_autoload_register(array('ezcBase', 'autoload'));
include "Zend/Loader.php";
spl_autoload_register(array('Zend_Loader', 'autoload'));
Los Ez Components tienen muchos componentes que te ofrecen lo mismo que el Zend Framework. Pero hay unos cuantos que no:
- Ez Graph: para la generación de gráficos. Funciona muy bien, te permite bastantes formatos y los gráficos son visualmente bastante atractivos.
- Ez Database: ofrece lo mismo que las del ZF pero además puedes hacer algún tipo de ORM.
- Ez Workflow: éste me parece muy interesante. Te permite configurar flujos de trabajo (roles, documentos, estados) para implementar procesos.
Otra ventaja más del ZF: se puede combinar con Ez Components para aprovechar las ventajas de los dos y simplificar más todavía el desarrollo de aplicaciones…
» Leer más, comentarios, etc...
Bitácora de Javier Gutiérrez Chamorro (Guti)
Funciones Javascript en Dreamweaver CS4
Mayo 30th, 2008 - [Enlace local]
Aunque soy de aquellos que se sienten más cómodos escribiendo códigos basados en HTML desde un editor no visual, me gusta de Dreamweaver las funciones Javascript que incluye para realizar tareas comunes.
Utilizo estas funciones, que son en general compactas y eficientes, pero sobretodo que están probadas, y son compatibles con un amplio espectro de navegadores y versiones.
Aprovechando la disponibilidad en beta de Adobe Dreamweaver CS4 (10.0.3963), he aprovechado para recogerlas, e irlas actualizando progresivamente de mis proyectos.
Viendo los fuentes de multitud de web, se que hay gente que está en la misma situación que yo, así que dejo aquí las funciones, para que las uséis si lo creéis conveniente.
Antes de que os adelantéis a preguntarlo, no hay demasiados cambios de momento en DW CS4 comparado con el anterior CS3, las apenas 490 compilaciones que han pasado de uno a otro, dan fe de ello.
function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
if (a.indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a;}}
}
function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a)&&x.oSrc;i++) x.src=x.oSrc;
}
function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers.document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}
function MM_swapImage() { //v3.0
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
if ((x=MM_findObj(a))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}
function MM_getProp(obj, prop) { //v8.0
if (!obj) return ("");
if (prop == "L") return obj.offsetLeft;
else if (prop == "T") return obj.offsetTop;
else if (prop == "W") return obj.offsetWidth;
else if (prop == "H") return obj.offsetHeight;
else {
if (typeof(window.getComputedStyle) == "undefined") {
if (typeof(obj.currentStyle) == "undefined"){
if (prop == "P") return MM_scanStyles(obj,"position");
else if (prop == "Z") return MM_scanStyles(obj,"z-index");
else if (prop == "V") return MM_scanStyles(obj,"visibility");
} else {
if (prop == "P") return obj.currentStyle.position;
else if (prop == "Z") return obj.currentStyle.zIndex;
else if (prop == "V") return obj.currentStyle.visibility;
}
} else {
if (prop == "P") return window.getComputedStyle(obj,null).getPropertyValue("position");
else if (prop == "Z") return window.getComputedStyle(obj,null).getPropertyValue("z-index");
else if (prop == "V") return window.getComputedStyle(obj,null).getPropertyValue("visibility");
}
}
}
function MM_changeProp(objId,x,theProp,theValue) { //v9.0
var obj = null; with (document){ if (getElementById)
obj = getElementById(objId); }
if (obj){
if (theValue == true || theValue == false)
eval("obj.style."+theProp+"="+theValue);
else eval("obj.style."+theProp+"='"+theValue+"'");
}
}
function MM_showHideLayers() { //v9.0
var i,p,v,obj,args=MM_showHideLayers.arguments;
for (i=0; i<(args.length-2); i+=3)
with (document) if (getElementById && ((obj=getElementById(args))!=null)) { v=args[i+2];
if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
obj.visibility=v; }
}
function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
if (a.indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a;}}
}
function MM_checkBrowser(NSvers,NSpass,NSnoPass,IEvers,IEpass,IEnoPass,OBpass,URL,altURL) { //v5.0
var newURL='', userAgent=navigator.userAgent, version=0;
if (userAgent.indexOf('Netscape') != -1) {
version = parseFloat(userAgent.substring(userAgent.indexOf('Netscape')+9,userAgent.length));
if (version >= NSvers) {if (NSpass>0) newURL=(NSpass==1)?URL:altURL;}
else {if (NSnoPass>0) newURL=(NSnoPass==1)?URL:altURL;}
} else if (userAgent.indexOf('MSIE') != -1) {
version = parseFloat(userAgent.substring(userAgent.indexOf('MSIE')+4,userAgent.length));
if (version >= IEvers)
{if (IEpass>0) newURL=(IEpass==1)?URL:altURL;}
else {if (IEnoPass>0) newURL=(IEnoPass==1)?URL:altURL;}
} else if (OBpass>0) newURL=(OBpass==1)?URL:altURL;
if (newURL) { window.location=unescape(newURL); document.MM_returnValue=false; }
}
function MM_checkPlugin(plgIn, theURL, altURL, autoGo) { //v4.0
var ok=false; document.MM_returnValue = false;
with (navigator) if (appName.indexOf('Microsoft')==-1 || (plugins && plugins.length)) {
ok=(plugins && plugins[plgIn]);
} else if (appVersion.indexOf('3.1')==-1) { //not Netscape or Win3.1
if (plgIn.indexOf("Flash")!=-1 && window.MM_flash!=null) ok=window.MM_flash;
else if (plgIn.indexOf("Director")!=-1 && window.MM_dir!=null) ok=window.MM_dir;
else ok=autoGo; }
if (!ok) theURL=altURL; if (theURL) window.location=theURL;
}
function MM_openBrWindow(theURL,winName,features) { //v2.0
window.open(theURL,winName,features);
}
function MM_validateForm() { //v4.0
if (document.getElementById){
var i,p,q,nm,test,num,min,max,errors='',args=MM_validateForm.arguments;
for (i=0; i<(args.length-2); i+=3) { test=args[i+2]; val=document.getElementById(args);
if (val) { nm=val.name; if ((val=val.value)!="") {
if (test.indexOf('isEmail')!=-1) { p=val.indexOf('@');
if (p<1 || p==(val.length-1)) errors+='- '+nm+' must contain an e-mail address.\n';
} else if (test!='R') { num = parseFloat(val);
if (isNaN(val)) errors+='- '+nm+' must contain a number.\n';
if (test.indexOf('inRange') != -1) { p=test.indexOf(':');
min=test.substring(8,p); max=test.substring(p+1);
if (num<min || max<num) errors+='- '+nm+' must contain a number between '+min+' and '+max+'.\n';
} } } else if (test.charAt(0) == 'R') errors += '- '+nm+' is required.\n'; }
} if (errors) alert('The following error(s) occurred:\n'+errors);
document.MM_returnValue = (errors == '');
} }
function MM_nbGroup(event, grpName) { //v6.0
var i,img,nbArr,args=MM_nbGroup.arguments;
if (event == "init" && args.length > 2) {
if ((img = MM_findObj(args[2])) != null && !img.MM_init) {
img.MM_init = true; img.MM_up = args[3]; img.MM_dn = img.src;
if ((nbArr = document[grpName]) == null) nbArr = document[grpName] = new Array();
nbArr[nbArr.length] = img;
for (i=4; i < args.length-1; i+=2) if ((img = MM_findObj(args)) != null) {
if (!img.MM_up) img.MM_up = img.src;
img.src = img.MM_dn = args[i+1];
nbArr[nbArr.length] = img;
} }
} else if (event == "over") {
document.MM_nbOver = nbArr = new Array();
for (i=1; i < args.length-1; i+=3) if ((img = MM_findObj(args)) != null) {
if (!img.MM_up) img.MM_up = img.src;
img.src = (img.MM_dn && args[i+2]) ? args[i+2] : ((args[i+1])? args[i+1] : img.MM_up);
nbArr[nbArr.length] = img;
}
} else if (event == "out" ) {
for (i=0; i < document.MM_nbOver.length; i++) {
img = document.MM_nbOver; img.src = (img.MM_dn) ? img.MM_dn : img.MM_up; }
} else if (event == "down") {
nbArr = document[grpName];
if (nbArr)
for (i=0; i < nbArr.length; i++) { img=nbArr; img.src = img.MM_up; img.MM_dn = 0; }
document[grpName] = nbArr = new Array();
for (i=2; i < args.length-1; i+=2) if ((img = MM_findObj(args)) != null) {
if (!img.MM_up) img.MM_up = img.src;
img.src = img.MM_dn = (args[i+1])? args[i+1] : img.MM_up;
nbArr[nbArr.length] = img;
} }
}
function MM_goToURL() { //v3.0
var i, args=MM_goToURL.arguments; document.MM_returnValue = false;
for (i=0; i<(args.length-1); i+=2) eval(args+".location='"+args[i+1]+"'");
}
function MM_jumpMenuGo(objId,targ,restore){ //v9.0
var selObj = null; with (document) {
if (getElementById) selObj = getElementById(objId);
if (selObj) eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
if (restore) selObj.selectedIndex=0; }
}
function MM_dragLayer(objId,x,hL,hT,hW,hH,toFront,dropBack,cU,cD,cL,cR,targL,targT,tol,dropJS,et,dragJS) { //v9.01
//Copyright 2005-2006 Adobe Macromedia Software LLC and its licensors. All rights reserved.
var i,j,aLayer,retVal,curDrag=null,curLeft,curTop,IE=document.all;
var NS=(!IE&&document.getElementById); if (!IE && !NS) return false;
retVal = true; if(IE && event) event.returnValue = true;
if (MM_dragLayer.arguments.length > 1) {
curDrag = document.getElementById(objId); if (!curDrag) return false;
if (!document.allLayers) { document.allLayers = new Array();
with (document){ if (NS) { var spns = getElementsByTagName("span"); var all = getElementsByTagName("div");
for (i=0;i<spns.length;i++) if (MM_getProp(spns,'P')) allLayers[allLayers.length]=spns;}
for (i=0;i<all.length;i++) {
if (MM_getProp(all,'P')) allLayers[allLayers.length]=all;
}
} }
curDrag.MM_dragOk=true; curDrag.MM_targL=targL; curDrag.MM_targT=targT;
curDrag.MM_tol=Math.pow(tol,2); curDrag.MM_hLeft=hL; curDrag.MM_hTop=hT;
curDrag.MM_hWidth=hW; curDrag.MM_hHeight=hH; curDrag.MM_toFront=toFront;
curDrag.MM_dropBack=dropBack; curDrag.MM_dropJS=dropJS;
curDrag.MM_everyTime=et; curDrag.MM_dragJS=dragJS;
curDrag.MM_oldZ = MM_getProp(curDrag,'Z');
curLeft = MM_getProp(curDrag,'L');
if (String(curLeft)=="NaN") curLeft=0; curDrag.MM_startL = curLeft;
curTop = MM_getProp(curDrag,'T');
if (String(curTop)=="NaN") curTop=0; curDrag.MM_startT = curTop;
curDrag.MM_bL=(cL<0)?null:curLeft-cL; curDrag.MM_bT=(cU<0)?null:curTop-cU;
curDrag.MM_bR=(cR<0)?null:curLeft+cR; curDrag.MM_bB=(cD<0)?null:curTop+cD;
curDrag.MM_LEFTRIGHT=0; curDrag.MM_UPDOWN=0; curDrag.MM_SNAPPED=false; //use in your JS!
document.onmousedown = MM_dragLayer; document.onmouseup = MM_dragLayer;
if (NS) document.captureEvents(Event.MOUSEDOWN|Event.MOUSEUP);
} else {
var theEvent = ((NS)?objId.type:event.type);
if (theEvent == 'mousedown') {
var mouseX = (NS)?objId.pageX : event.clientX + document.body.scrollLeft;
var mouseY = (NS)?objId.pageY : event.clientY + document.body.scrollTop;
var maxDragZ=null; document.MM_maxZ = 0;
for (i=0; i<document.allLayers.length; i++) { aLayer = document.allLayers;
var aLayerZ = MM_getProp(aLayer,'Z');
if (aLayerZ > document.MM_maxZ) document.MM_maxZ = aLayerZ;
var isVisible = (MM_getProp(aLayer,'V')).indexOf('hid') == -1;
if (aLayer.MM_dragOk != null && isVisible) with (aLayer) {
var parentL=0; var parentT=0;
if (NS) { parentLayer = aLayer.parentNode;
while (parentLayer != null && parentLayer != document && MM_getProp(parentLayer,'P')) {
parentL += parseInt(MM_getProp(parentLayer,'L')); parentT += parseInt(MM_getProp(parentLayer,'T'));
parentLayer = parentLayer.parentNode;
if (parentLayer==document) parentLayer = null;
} } else if (IE) { parentLayer = aLayer.parentElement;
while (parentLayer != null && MM_getProp(parentLayer,'P')) {
parentL += MM_getProp(parentLayer,'L'); parentT += MM_getProp(parentLayer,'T');
parentLayer = parentLayer.parentElement; } }
var tmpX=mouseX-((MM_getProp(aLayer,'L'))+parentL+MM_hLeft);
var tmpY=mouseY-((MM_getProp(aLayer,'T'))+parentT+MM_hTop);
if (String(tmpX)=="NaN") tmpX=0; if (String(tmpY)=="NaN") tmpY=0;
var tmpW = MM_hWidth; if (tmpW <= 0) tmpW += MM_getProp(aLayer,'W');
var tmpH = MM_hHeight; if (tmpH <= 0) tmpH += MM_getProp(aLayer,'H');
if ((0 <= tmpX && tmpX < tmpW && 0 <= tmpY && tmpY < tmpH) && (maxDragZ == null
|| maxDragZ <= aLayerZ)) { curDrag = aLayer; maxDragZ = aLayerZ; } } }
if (curDrag) {
document.onmousemove = MM_dragLayer;
curLeft = MM_getProp(curDrag,'L');
curTop = MM_getProp(curDrag,'T');
if (String(curLeft)=="NaN") curLeft=0; if (String(curTop)=="NaN") curTop=0;
MM_oldX = mouseX - curLeft; MM_oldY = mouseY - curTop;
document.MM_curDrag = curDrag; curDrag.MM_SNAPPED=false;
if(curDrag.MM_toFront) {
var newZ = parseInt(document.MM_maxZ)+1;
eval('curDrag.'+('style.')+'zIndex=newZ');
if (!curDrag.MM_dropBack) document.MM_maxZ++; }
retVal = false; if(!NS) event.returnValue = false;
} } else if (theEvent == 'mousemove') {
if (document.MM_curDrag) with (document.MM_curDrag) {
var mouseX = (NS)?objId.pageX : event.clientX + document.body.scrollLeft;
var mouseY = (NS)?objId.pageY : event.clientY + document.body.scrollTop;
var newLeft = mouseX-MM_oldX; var newTop = mouseY-MM_oldY;
if (MM_bL!=null) newLeft = Math.max(newLeft,MM_bL);
if (MM_bR!=null) newLeft = Math.min(newLeft,MM_bR);
if (MM_bT!=null) newTop = Math.max(newTop ,MM_bT);
if (MM_bB!=null) newTop = Math.min(newTop ,MM_bB);
MM_LEFTRIGHT = newLeft-MM_startL; MM_UPDOWN = newTop-MM_startT;
if (NS){style.left = newLeft + "px"; style.top = newTop + "px";}
else {style.pixelLeft = newLeft; style.pixelTop = newTop;}
if (MM_dragJS) eval(MM_dragJS);
retVal = false; if(!NS) event.returnValue = false;
} } else if (theEvent == 'mouseup') {
document.onmousemove = null;
if (NS) document.releaseEvents(Event.MOUSEMOVE);
if (NS) document.captureEvents(Event.MOUSEDOWN); //for mac NS
if (document.MM_curDrag) with (document.MM_curDrag) {
if (typeof MM_targL =='number' && typeof MM_targT == 'number' &&
(Math.pow(MM_targL-(MM_getProp(document.MM_curDrag,'L')),2)+
Math.pow(MM_targT-(MM_getProp(document.MM_curDrag,'T')),2))<=MM_tol) {
if (NS) {style.left = MM_targL + "px"; style.top = MM_targT + "px";}
else {style.pixelLeft = MM_targL; style.pixelTop = MM_targT;}
MM_SNAPPED = true; MM_LEFTRIGHT = MM_startL-MM_targL; MM_UPDOWN = MM_startT-MM_targT; }
if (MM_everyTime || MM_SNAPPED) eval(MM_dropJS);
if(MM_dropBack) {style.zIndex = MM_oldZ;}
retVal = false; if(!NS) event.returnValue = false; }
document.MM_curDrag = null;
}
if (NS) document.routeEvent(objId);
} return retVal;
}
Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti) - http://guti.bitacoras.com.
» Leer más, comentarios, etc...
niko's mini factory
Links for 2008-05-29 [del.icio.us]
Mayo 30th, 2008 - [Enlace local]
- InfoQ: Scalability Best Practices: Lessons from eBay
- Pattern Based Development with Mule 2.0 | Architects Zone
» Leer más, comentarios, etc...
Programacion, literatura y otras artes menores
World-Of-WarCraft o los clientes del mundo inamovible
Mayo 30th, 2008 - [Enlace local]
Desde hace algunas semana una amiga me inició en la falsa inmensidad de este juego. Antes de seguir debo aclarar que lo disfruto, de hecho me gusta mucho, pero…
Siempre es igual, osea, es grande, inmenso, pero es una inmensidad estática, los personajes evolucionan, pero su evolución no modifica al mundo en donde viven, quizás influya en sus compañeros de juego, pero no dejará ninguna marca que pueda ver algún recién llegado.
Nunca he entrado en Second Life, ni pienso hacerlo, pero por lo que he oído ahí sí se modifica permanentemente el entorno, y el universo de Second Life tiene una vida propia, sin obligar a los jugadores hacer las mismas Quests una y otra vez, lo cual es divertido, a mi me divierte, pero no es natural que te manden a buscar los restos de alguien y que luego de entregarlos venga otro y se los pidan igual o.0
En general el juego está muy bien, pero lo genial sería algo como una generación de quests, quizás surgiendo como consecuencia de actos de otros jugadores y/o darle cierta autonomía a los bots del juego, no necesariamente IA, sino que se rijan por ciertas reglas, lo bastante amplias o sencillas como para permitir el surgimiento de comportamientos inesperados, aunque coherentes con el personaje.
Resumiendo, darle vida al universo, que si de pronto todos los jugadores se pusieran de acuerdo y dejaran de jugar por una semana, al re-entrar el mundo de WorldCraft hubiera evolucionado por sí mismo.
Como no me gusta pedir, sobre todo si no puedo dar nada a cambio, tuve(tengo) la peregrina idea de iniciar un proyecto de motor lógico que permita justamente eso, construir encima de él un mundo autónomo, y como sé que no lo lograré, pues la tarea es titánica y no tengo los conocimientos matemáticos que se que hará falta, pues decidí que sí lo voy a intentar(la ignorancia es atrevida ), me voy a meter años(o solo meses), y al final lo desecharé, pero mientras dure será entretenido, y ya que estoy en eso, lo intentaré en Haskell(el cual recién estoy aprendiendo ahora, así que imagínense).
En fin, me deseo suerte
» Leer más, comentarios, etc...
Programacion, literatura y otras artes menores
Paradojas cliente-cliente-servidor-cliente-etc…
Mayo 29th, 2008 - [Enlace local]
Uf, llevo días intentando utilizar los servicios web de un tercero, estos señores tienen los servicios divididos en dos grupos:
- Servicios públicos
- Servicios protegidos(SSL y WS-Security)
De entrada empiezo con el gran problema que nunca en mi vida he usado servicios web, aunque en realidad muchas veces empecé a estudiarlos, jamás pude profundizar en ellos debido a la falta de tiempo y a cosas más interesantes que estudiar. Bueno, sin miedo le entré a los públicos, que parecían los más fáciles de consumir, y lo fueron, el amistoso NetBeans me ayudó tremendamente y en un dos por tres ya estaban integrados a mi plataforma de pago.
El lío vino después.
Primero el https, la susodicha empresa había configurado su SSL de manera que hacía falta autenticación de parte del cliente, para lo cual me enviaron un keystore… sin la clave. Aqui viene la primera odisea, parece que esas personas son MUY ocupadas, pues durante 2 días de correos y correos jamás obtuve la contraseña del keystore, así que tuve que acudir a medidas desesperadas ¡¡y me funcionó!!
Perfecto, pero me faltaba(falta) lo mejor: WS-Security.
Si hay algún lector de este blog que tenga *alguna* experiencia con WS-Security, y sea capaz de reírse de mis vicisitudes, pues además de que lo admiro muchísimo, por favor que se ponga en contacto conmigo >.<
Sigo, resulta que una y otra vez el servidor del cliente me devolvía el código de erro 401: acceso denegado, onda hollywood, busqué y busqué y vi en la especificación del esquema de seguridad que me mandaron que usaban los userNameTokens, algo que ya había supuesto luego de bucear por la red. Entonces empecé a intentar meterlo los dichos tokens a los mensajes salientes, probé en la configuración de glassfish, pero nada, probé con un MessageHandler, nada.
Hasta los señores del jurado tuvieron la condescendencia de enviarme un código de ejemplo para un cliente, en el que usaban XFire…¡y funcionó!
Ah, que alegría… y que poco me duró.
Resulta que los servicios estos usan un montón de tipos complejos, que aparentemente el XFire no sabe como tratar, y me da stackoverflow una y otra vez…
En fin, ahí sigo, estoy convencido que si uso jaxb esto me funcionaría sin lío, pero maldito usernametoken.
… y maldito XFire >.<
» Leer más, comentarios, etc...
{ Radamanthys }
Cuando el plugin OO no trabaja como debe con NetBeans
Mayo 29th, 2008 - [Enlace local]
Existe un inconveniente en Debian Testing con el paquete de desarrollo del OpenOffice 2.4 openoffice.org-dev 2.4.0-5 tal y como sucede en Ubuntu 8.04.
Cuando intento compilar y generar el Addin desde el NetBeans(version 6.0.1), este no encuentra las herramientas provista por UNO, y despliega este error :
setting up UNO environment ... /usr/lib/openoffice/sdk/linux/bin/idlc: 4: basename: not found /usr/lib/openoffice/sdk/linux/bin/idlc: 4: /usr/lib/openoffice/sdk/linux/bin/.bin: not found /home/mbrenes/NetBeans/cword/build-uno-impl.xml:49: apply returned: 127 BUILD FAILED (total time: 0 seconds)
El problema radica en los wrappers que estan en /usr/lib/openoffice/sdk/linux/bin/, los cuales configuran las rutas de estan herramientas, pero sucede que no lo hacen bien, debido a que el comando usado para devolver esta informacion tampoco es encontrado(basename).
#!/bin/sh # wrapper script for OOos SDK programs LD_LIBRARY_PATH=/usr/lib/openoffice/program /usr/lib/openoffice/sdk/linux/bin/`/usr/bin/basename $0`.bin "$@"
Asi que, lo que se debe hacer para resolverlo es modificar cada script de estos(la lista acontinuacion) y cambiar donde es llamado este comando por su ruta absoluta, es decir, que donde aparece basename deberia quedar /usr/bin/basename :
* regmerge
* cppumaker
* idlc
* unoapploader
* regview
* javamaker
* xml2cmp
* rdbmaker
* uno-skeletonmaker
* sp2bv
* regcomp
* autodoc
* regcompare
* idlcpp
Mas Informacion: http://qa.openoffice.org
» Leer más, comentarios, etc...
{ Radamanthys }
Problema con el depurador de Java en NetBeans
Mayo 29th, 2008 - [Enlace local]
no carga el modulo JPDA
Esto me sucede en Debian Lenny sobre arquitectura i386, Netbeans(paquete version 6.0.1+dfsg-1), y el JDK(paquete sun-java6-jdk version 6-06-1).
En sintesis, lo que sucede es que no puede encontrar la ruta del JDK automaticamente, asi que hay que pasarselas a mano.
/usr/bin/netbeans –jdkhome /usr/lib/jvm/java-6-sun-1.6.0.06/
El bug ya esta reportado.
Mas Informacion: http://java.sun.com
» Leer más, comentarios, etc...
Yet Another Programming Weblog
Varios sobre concurrencia: Lock-free en Java, STM vs locks y consejos
Mayo 29th, 2008 - [Enlace local]
Varios sobre concurrencia (versión n)
- Cliff Click hizo una presentación sobre estructuras sin bloqueos en Java en la JavaOne 2008. El (interesante) pdf de la presentación está online y, no sé si más interesante, el código fuente: Highly Scalable Java en SourceForge
- En el blog del mismo Cliff Click hay una argumentadísima discusión de STM vs locks (Bloqueos frente a memoria transaccional por software) Esto si son discusiones :) (por cierto, que la original está en STM criticism from Azul Systems)
- Por último, Herb Sutter en Maximize Locality, Minimize Contention da consejos sobre programación concurrente, algunos de sentido común. Además propone un ejemplo muy claro de falsa compartición y remedios un poco drásticos de evitarla.
La misma entrada y más comentarios en Lock-free en Java, STM vs locks y consejos en barrapunto
» Leer más, comentarios, etc...
Picando Código
Siete razones por las que “Amo escribir código”
Mayo 29th, 2008 - [Enlace local]
Petar Radosevic escribe en su blog Wunki: Top seven reasons “Why I love to write code”.
Traducido al español sería algo así como “Las siete razones principales por las que amo escribir código”.
“Amo escribir código. Programar es una de las cosas en la vida que me hacen feliz”, dice en su post. En algunas ocasiones, seguramente a muchos de nosotros nos pasa lo mismo por la cabeza. A continuación enumero y comento las siete razones que Petar describe en su blog:
7: Ser un nicho.
“No muchas de las personas que conozco, saben cómo programar o menos configurar su computadora. Si ven que trabajas con la computadora, se asombran (y piensan que sos un geek). Es el mismo tipo de asombro de cuando veo a un físico trabajar en o con una fórmula. Para mí es totalmente incomprensible, para él es muy fácil. Como mucha gente sigue mistificada por las computadoras, eres al que llaman cuando algo sale mal. Reparar una computadora por semana significa que una vez por semana no tengo que comprar la comida. También significa que puedo ser un valor positivo para mis hermanas.”
Respecto a este punto, hay que tomarlo con cuidado, el tema de reparar computadoras a amigos o conocidos a la larga se puede volver molesto. Es como que le estés pidiendo a un amigo doctor que te diagnostique algo, o un amigo arquitecto que te diseñe una casa
Es un punto bastante relativo, según los gustos de cada uno.
Confieso alguna vez haber tenido el diálogo siguiente:
Yo - “¿Entendés lo que dice acá?”
Otra persona - “No, ni idea, ¡parece griego!”
Yo - “¡Ja! Lo escribí todo yo, y sé lo que hace!”
Bueno, puede existir la posibilidad de que tenga un problema…
6: Siempre hay más por aprender.
“En todos los campos siempre hay mucho más para aprender, pero creo que el campo de la programación es uno de los cuales el conocimiento crece más rápido. No pasa un día sin que hayas aprendido algo que te haga un mejor programador. Nuevas metodologías, implementaciones más rápidas y automatizaciones sencillas. Un beneficio de nuestra área es que el conocimiento es fácil de obtener, casi siempre de forma gratuita en la web. Google es nuestro amigo, y por nuestro perfil tecnológico, sabemos cómo usarlo y encontrar ese conocimiento que está escondido de los demás.”
En ésto estoy totalmente de acuerdo. El mundo de la programación cambia constantemente a un ritmo muy ágil, por lo que nunca faltan cosas nuevas para aprender. También estoy de acuerdo con que es así en casi todos los campos de conocimiento. Ah, y hay demasiada gente al frente de una computadora que no sabe usarla, mucho menos encontrar algo en Google…
5: Solitario.
“Admito que soy un poco solitario. Un solitario en el sentido de que me encanta sentarme solo en mi cuarto y trabajar en mis habilidades para programar. Ser un programador es una compañía perfecta para éste desorden. Un trago y yo le damos duro a una noche salvaje de escribir clases (escribir esto me asustó hasta a mí, pero es la verdad, lo sabés).”
De acuerdo con esto. Habemos muchos que pasamos noches despiertos programando algo… Noctámbulos y solitarios pasamos horas frente a la computadora tirando código. En la mañana surgen los mejores proyectos listos ![]()
4: Orgulloso de tu trabajo
“Has usado las tecnologías más nuevas. Tus líneas de código no podrían estar mejor adaptadas al tipo de programa. El software corre establemente sin caerse y la gente usa tu mundo. El mundo que has creado con tus reglas. Éstas cosas de las que puedes estar orgulloso porque te llevó largas noches crearlo.”
También se refleja cuando por ejemplo, creamos un mini-proyectito libre, y nos llega un mail de alguien que lo está usando, y lo mejoró, o cambió, o corrigió errores. Es un orgullo y una satisfacción bastante particular.
3: Herramientas del ramo
“Nos toca usar herramientas geniales. Las más grandes primero, nos toca jugar con la computadora y entender qué está haciendo. A ésta computadora están conectados lindos teclados de tipeo y mouse que navegan suavemente. La pantalla está limpia y perfectamente ajustada a tu gusto. Aparte de la parte del hard, está nuestro software. Me encanta personalizar mi IDE. Nuevos atajos, macros y temas son cosas de alegría.”
Si un programador no ha desarrollado un poco saludable cariño por sus herramientas, tanto de hardware como de software, no está completo…
2: Ayudas a los demás.
“El software que creas es usado a menudo por otros. Están usando tu software para enriqueces sus vidas. Ver que está siendo usado es una de las alegrías de un programador. No fuiste el único que pensó que tal programa podría ser útil. El feedback (positivo) te da ganas de crear otro gran producto que sea mejor, más grande y suave.”
Respecto a ayudar a los demás, creo que éste punto es esencialmente importante cuando el software que programamos es Software Libre. No solo estamos ayudando a los usuarios aportándoles algo útil, sino también a otros programadores.
1: Soy el creador de mundos.
“Creo mundos y les digo “Hola”. Pudiendo programar, soy capaz de crear un mundo nuevo con mis reglas. Cada persona en mi mundo debe tener un nickname que sea alfanumérico y una contraseña de al menos ocho caracteres que identifiquen quién es. Cada persona me dice lo que están haciendo y mis validaciones me dicen si es ilegal. Es genial poder crear tu propio mundo donde nada es imposible y todo se comporta como tú hiciste que se comportara.”
Sí, está bueno, crear un mundo. Will Wright siempre vió la programación de esa forma, y así le fué…
En verdad hay muchas más satisfacciones que se van viviendo día a día en la programación. Seguramente puedan recomendar más en los comentarios.
» Leer más, comentarios, etc...
psé
Bugs en la centralita de mi coche
Mayo 29th, 2008 - [Enlace local]
![]()
Cuando hablamos de un bug en una aplicación para dibujar hablamos de una pequeña putada, llega grafista, dibuja un logotipo de muerte y tras 3 horas intenta grabar y la aplicación casca. No pasa nada, el grafista pierde 3 horas de su vida, se cabrea y listo. Si hablamos de un software que se ejecuta en un hardware que controla un vehículo, un avión o un sistema donde se hacen transacciones bancarias la cosa cambia. Un error puede matar a una persona que circula en su vehículo y pierde los frenos.
Dada el impacto que puede producir un error en un software de estas características cabe pensar que los desarrolladores de estas aplicaciones estén muy formados y que las pruebas de calidad que pasen sean muy minuciosas.
Hace unos días me llegó una carta certificada de Renault, indicándome que tenía que llevar mi coche a un concesionario oficial para hacerme una reprogramación por peligro de "bloqueo del motor durante su utilización". No creo que después de 50mil kilómetros me vaya a petar el motor, aunque quien sabe. En resumen, me ha cambiado el software que controla la inyección de carburante, que suena importante.
Me imagino que el software de inyección irá en un hardware aparte que el ordenador de a bordo, el cual me estima mi consumo instantáneo, medio, etc. Bien, después de este reinicio ahora el coche no calcula bien el consumo medio, lo que me hace pensar que el software de mi ordenador de a bordo no se ha enterado de la reprogramación del software de inyección y por tanto sigue teniendo "algunos" datos antiguos y algunos otros nuevos. En resumen, mi consumo medio es 0.1 litros/100km (al precio del gasoil es una ganga).
Pero bueno, es un caso muy raro, se puede tolerar, sin embargo hay otro problema que me da más que pensar: 2000 kilómetros antes de cambiar el aceite me avisa y justo cuando llega ese aviso el ordenador curiosamente corrige otro bug, este es de la máquina de estados que controla lo que se muestra en pantalla. Cuando me ha avisado siempre vuelve a la pantalla a la que estaba después de usar el regulador. Cuando pongo el regulador en la pantalla me muestra la velocidad y en su funcionamiento normal se queda fijo, sin embargo, como digo, después del aviso vuelve a mostrarme lo que tenía. Esto me dice dos cosas:
1.- Los que prueban y programan no saben el comportamiento que debe tener, de otra forma se hubiesen dado cuenta de lo que tenía que pasar.
2.- No usan ningún tipo de test y si lo hacen no tienen un informe de cobertura de test. En caso de que lo usaran podría haber detectado rápidamente que el caso de funcionamiento con aviso de ir al taller estaba testeado. Un artículo referente a esto en el blog de testing de google.
No quiero ni decir nada acerca de algún que otro código que he visto que controla ciertas transacciones con tarjetas de crédito, ahora me da miedo real pagar con tarjeta de crédito.
Para cuando un coche donde dejen el código fuente abierto y cada uno podamos programarnos nuestro software a medida ? :D Hay gente que hace hacks (con arduino por cierto), pero no lo veo muy claro
pd: la imagen está tomada de la wikipedia en inglés
» Leer más, comentarios, etc...
jordisan.net blog: sobre lo humano, lo divino... y lo técnico: desarrollo
Programar y escribir para la web: no tan diferentes
Mayo 29th, 2008 - [Enlace local]
Leo un artículo en el blog de Ricardo Galli titulado Tratar al código fuente como un ensayo que me ha vuelto a crear una conexión entre dos temas que en principio parecen poco relacionados pero de los que se puede extraer alguna enseñanza común; en este caso, la programación y la redacción de textos para la web.
Ricardo habla de un libro (Beautiful Code) y, más concretamente, de un capítulo titulado como su artículo: Treating Code As an Essay. En él se señala la similitud entre el código fuente de un programa y un ensayo, en el sentido de que, si bien en ambos casos su propósito es lo fundamental ("¿de qué se trata?"; "¿qué hace?"), no debe descuidarse el estilo en que... [sigue ...]
» Leer más, comentarios, etc...
Navegapolis
Las mejores prácticas de CMMI-ACQ
Mayo 29th, 2008 - [Enlace local]
Cuando hay problemas en los proyectos de software (en tres de cada cuatro) no sólo hay que buscar las causas en el vendedor, sino también en el comprador.
De todos los procesos necesarios para llevar a cabo un sistema, todos son responsabilidad del suministrador, menos uno: el de adquisición (ISO/IEC 12207 ).
SEI publicó el año pasado un modelo específico para el proceso de adquisición: CMMI for Acquisition (CMMI-ACQ), pero con sus 22 áreas de proceso descritas en 441 páginas resulta inadecuado para no iniciados, por eso ha visto la luz una versión "light": CMMI for Acquisition Primer: 57 páginas, con una exposición más de manual rápido, que de modelo CMMI, que contienen el extracto de las mejores prácticas del modelo completo.
» Leer más, comentarios, etc...
Navegapolis
Las mejores prácticas de CMMI-ACQ
Mayo 29th, 2008 - [Enlace local]
Cuando hay problemas en los proyectos de software (en tres de cada cuatro) no sólo hay que buscar las causas en el vendedor, sino también en el comprador.
De todos los procesos necesarios para llevar a cabo un sistema, todos son responsabilidad del suministrador, menos uno: el de adquisición (ISO/IEC 12207 ).
SEI publicó el año pasado un modelo específico para el proceso de adquisición: CMMI for Acquisition (CMMI-ACQ), pero con sus 22 áreas de proceso descritas en 441 páginas resulta inadecuado para no iniciados, por eso ha visto la luz una versión "light": CMMI for Acquisition Primer: 57 páginas, con una exposición más de manual rápido, que de modelo CMMI, que contienen el extracto de las mejores prácticas del modelo completo.
» Leer más, comentarios, etc...
Picando Código
Firefox Download Day: Buscando el Record Mundial Guiness
Mayo 29th, 2008 - [Enlace local]
Establece un récord mundial Guinness
Disfruta una web mejor
Parece un buen trato, ¿verdad? Todo lo que tienes que hacer es descargar Firefox 3 durante el Download Day para ayudar a establecer el récord del software con más descargas durante 24 horas - es así de fácil. No te estamos pidiendo que te tragues una espada o que mantengas en equilibrio 30 cucharas sobre tu cara, aunque eso también sería bastante impresionante.
Por cierto, la fecha oficial de lanzamiento de Firefox 3 se publicará aquí pronto - ¡así que visítanos a menudo! Únete a nuestra comunidad hoy.
Ésta es la iniciativa que plantea la gente de Mozilla para el lanzamiento de Firefox 3. Al momento de publicar esta noticia, 125 personas (126 conmigo) se habían inscripto desde Uruguay, siendo España, Alemania y Polonia los países europeos con más inscriptos, Japón el de mayor inscriptos asiáticos, y Estados Unidos el de más inscriptos en América.
Ya hay cerca de 100.000 personas dispuestas a descargar Firefox 3 el día de su lanzamiento, y ayudarlo ser el software con más descargas en 24 horas. Van a tener que preparar sus servidores muy bien para ese día…
» Leer más, comentarios, etc...
Bloggingg
Ruby, Python, Groovy y compañía nunca reemplazarán a Java
Mayo 29th, 2008 - [Enlace local]
Últimamente, día sí y día también no cesan en la web artículos donde pronostican la muerte de Java para ser reemplazado por cualquiera de los nuevos lenguajes de moda. Y por fin encuentro un artículo (en inglés) 13 reasons why Ruby, Python and the gang will push Java to die… of old age donde puedes encontrar 13 razones contundentes donde afirman todo lo contrario. El autor se documenta a partir de varios índices de popularidad: TIOBE Index y langpop.com. Coincido en la mayoría de puntos con el autor, pero aquí voy a describir por encima sólo las que me parecen más importantes.
Para empezar vayamos analizando la siguiente gráfica que mide la popularidad de los lenguajes (mayo 2008):
Lo que más llama la atención, además de que Java sea el primero, es que los lenguajes con una sintaxis parecida a Java: C, C++, Java y C# forman el 49,915% de popularidad, casi la mitad que todo el resto de lenguajes. De aquí podemos obtener la primera razón:
1) Los programadores que quieran cambiar de lenguaje, tendrán que hacer más esfuerzo al aprender un lenguaje con una sintaxis muy diferente a la de Java, porque, además de la sintaxis, tienen conceptos también bastantes diferentes.
Si echamos un vistazo al grupo de los candidatos: Python + Ruby + Lisp/Scheme + Lua + SmallTalk + Haskell + Groovy + Erlang + Caml + Scala = 8,985 %. Podemos concluir la segunda razón:
2)Es una cifra insignificante comparada con la primera, además, estos 10 lenguajes hacen mucho ruido, son muchos y los programadores no tenemos tiempo para evaluarlos todos y seguir de cerca su evolución. Si quisiésemos reemplazar a Java por uno de estos diez, ¿cuál elegirías?
Sigamos analizando otra gráfica: la tendencia de popularidad de los últimos 7 años:

En un vistazo rápido podemos ver una tendencia al alta de la popularidad general de todos los lenguajes, hay algunas variaciones temporales, pero a la larga, nada cambia significativamente.
Razón número 3: No hay presión sobre los programadores para que cambien de lenguaje, el mercado ya es estable, los lenguajes que ya existen funcionan aceptablemente bien para lo que fueron diseñados, así que los jefes de proyecto no tienen porqué obligar a los programadores a aprender nuevos lenguajes. Para mí es la razón la más importante de todas.
Otra gráfica interesante es la evolución en las tendencias de trabajo:

Razón número 4: No hay un gran incentivo para cambiar de trabajo, aprender un nuevo lenguaje no tiene porqué traducirse en un aumento de sueldo, al menos, a corto plazo.
Otro hecho importante que hay que tener en cuenta es que los lenguajes populares deben de tener un éxito relativamente rápido, si los programadores ven una evolución muy lenta sobre un lenguaje con varios años de vida, entonces la conclusión es que no merece la pena aprender ese lenguaje, si no ha tenido éxito, por algo será.
Como curiosidad, aquí muestro una lista de los lenguajes pretendientes y sus años de nacimiento:
Ruby (mid 1990s), Python (1991), Lisp (1958), Scheme (1970s), Lua (1993), Smalltalk (1969-1980), Haskell (1990), Erlang (1987), Caml (1985), OCaml (1996), Groovy (2003), Scala (2003)
y aquí la lista con los lenguajes más populares y sus años de nacimiento: C (1972), C++ (1983), Java (1995), C# (2001), BASIC (1964), Pascal (1970), FORTRAN (1957), Ada (1983), COBOL (1959).
La conclusión que saco de aquí es que estos lenguajes han perdido ya el tren, si de verdad desbancarían a Java, ya lo tendrían que haber hecho.
Para terminar, mi conclusión final es que Java será remplazado por un lenguaje que herede todo lo que tenga Java pero que corrija los fallos que tiene Java. Por ejemplo, Java nació a partir de los problemas que los programadores sufrían con C y C++ (complejidad y gestión de memoria). Al evitarle al programador tener que gestionar la memoria, los programadores se evitaron un montón de rompederos de cabeza corrigiendo bugs generados por los memory leaks.
Que quede claro que no desaconsejo nunca aprender o usar alguno de estos lenguajes, de hecho intento seguir la evolución y aprender alguno de ellos (en concreto Ruby y Python), me parecen muy interesantes algunas características y peculiaridades de las que Java podría incorporar.
» Leer más, comentarios, etc...
.: El Blog de Inwe :. » Programación
Internet in 2035
Mayo 29th, 2008 - [Enlace local]
Ayer martes asistimos a la conferencia que dió Vint Cerf (vicepresidente de Google, Premio Príncipe de Asturias 2002, considerado uno de los padre de Internet, etc..)en la Universidad de Murcia. En un principio la temática era el Software Libre, pero la conferencia empezó con un futurista Internet in 2035.

Y la verdad es que me encantó, no sólo por la temática (que ahora comentaré), si no por lo bien que lo comunicó y por lo cercano que estuvo (al final nos hicimos unas fotos con él).
Empezó la conferencia dando estadísticas hacerca del uso de Internet en el mundo hoy en día, su penetración, número de dispositivos capaces de acceder a Internet, etc. Y también nos dió datos de lo que el predice (junto con estadísticas de la ONU) que pasará en los próximos 50 años, tales como el aumento de la población, la penetración que tendrá esta dentro de 50 años, así como el número de dispositivos que tendrían acceso. Más o menos preveía que para una población de unos 9 mil millones de personas (previsión media) habría unos 10 mil millones de teléfonos móviles y unos 12 mil millones de aparatos capaces de acceder a Internet, evidentemente la porporción por habitante crecía si hablamos de paises desarrollados o subdesarrollados.
Comentó también como broma, que ahora se están migrando las IPs de IPv4 a IPv6 (que dentro de pocos años sólo habrán IPs de esta versión), y que entona el “Mea Culpa”, ya que cuando en el 1979 (creo recordar) eligió los actuales 32 bits de las direcciones IPs, pensó que para un experimento (recordemos el uso militar que en un principio tenía Internet), los 2.2 mil millones de direcciones distintas habría de sobra.
A continuación nos puso el ejemplo del frigorífico del futuro, capaz de saber la cantidad de comida que hay dentro de él. Así, cuando llegues a casa, dependiendo de lo que quede en la nevera, consultará en Internet recetas que contengan dichos ingredientes y te lo presentará. Otro caso de uso sería cuando vayas al supermercado, te llegará un sms al móvil diciendo: Hola soy el frigorífico, no te olvides de comprar leche. Y por último, cuando vayas al médigo y te diga que tienes sobrepeso, cuando llegues a casa el frigorífico te mostrará dieta a seguir, ya que se conectó a Internet y vió que el médico te había puesto el sobrepeso en su informe.
Hacia el final de la charla habló de las comunicaciones InterPlanetarias (InterPT), por ejemplo la comunicación de robots en Marte con la Tierra, y nos contó que quisieron establecer una conexión TPC/IP pero que era imposible dado las distancias “astronómicas” de las que hablamos, ya que la emisión de radio de Marte a la Tierra tardan sobre 15 minutos, y claro, no es posible mantener una cominicación en la que la emisión y la respuesta tarde tanto tiempo. También tenían el problema de que los planetas tienen la mala costumbre de rotar, por lo que cuando permanecen en el lado oculto, la conexión se interrumpe. Por ello, apostaron por una comicación como la de los correos electrónicos, es decir, tú mandas el mensaje (comunicación) y no sabes si el receptor estará on-line y podrá leerlo, por lo que se queda almacenado hasta que el receptor pueda abrirlo, y lo mismo con la respuesta. Por último, habló también que en el futuro cuando se vaya a otro planeta, lo que harán será portar los mismos procedimientos que están haciendo en Marte.
conferencia, internet, vint cerf
