Mostrando entradas con la etiqueta la vida del currito-picacódigo. Mostrar todas las entradas
Mostrando entradas con la etiqueta la vida del currito-picacódigo. Mostrar todas las entradas

viernes, 26 de febrero de 2010

Otro test de agudeza visual: ¿qué código es peor?

Opción 1:


Dim intVariable as Integer

Try
intVariable = LlamadaaMetodoQuePuedeDevolverNothing()
Catch ex as Exception
intVariable = 0
End Try



Opción 2:


Dim intVariable as Integer = 0

Try
intVariable = LlamadaaMetodoQuePuedeDevolverNothing()
Catch ex as Exception

End Try





Respuesta: la opción 2, que provoca un precioso "agujero negro de excepciones".

PD: los 2 ejemplos están basados en hechos reales, que no tengo tanta imaginación :P

miércoles, 30 de diciembre de 2009

Propósitos para el 2010

Pues eso, a falta de horas para que acabe el año se me ha dado por hacer una lista de los propósitos para el 2010, a ver si consigo cumplir con alguno :P

- Ser bueno ... no, voy a seguir siendo malo que es más divertido :D

- Acabar alguno de los 2 libros que tengo sobre Arquitectura de aplicaciones en .NET

- Probar la beta 2 del Visual Studio 2010, a ver si este cambio de versión no me pilla el toro :P

- Sacarme el MCPD Enterprise Application Developer 3.5 on Visual Studio 2008, que aún me quedan 4 exámenes.

- Aprobar entre 4 y 6 asignaturas de la carrera.

- Viajar, conocer gente interesante y disfrutar de la vida :D


Pero para todo eso necesito dormir 2 horas o que los días tengan unas 30 o 36 horas ... más :P

FELIZ AÑO A TOD@S ;)

viernes, 18 de diciembre de 2009

Establecer propiedades del IDE de Visual Studio dependiendo del proyecto que se abre

En el proyecto en el que estoy trabajando tenemos en el Team Foundation un branch con la solución de desarrollo y otro con la misma solución de producción. Considero que es una buena práctica que evita subir código no probado a producción y por ahora nos está llendo bastante bien.

El "problema" es que a veces tenemos que tener ambas soluciones abiertas a la vez, y como los cambios que tienen suelen ser muy pequeños, hay que tener mucho cuidado para no meter la pata y no modificar el código en el branch que no toca.

Comentándolo con mi compañero Pere, se me ocurrió que estaría bien tener un IDE diferente para cada una de las soluciones, algo sencillo, como cambiar el color de fondo o el tipo de letra. Y nos pusimos a buscar cómo hacerlo, gracias a San Google encontramos rápido la solución:

En este post: http://geekswithblogs.net/sdorman/archive/2007/04/25/111981.aspx

se explican 2 formas de hacerlo, una con macros que a mí me pareció un poco complicada y otra bastante más sencilla ejecutando el Visual Studio desde línea de comandos.

Los pasos que hay que seguir:

1 - En el menú Tools - Options dentro Environment - Fonts and Colors, establecemos el tipo de letra y los colores que queramos para, por ejemplo, la solución de desarrollo.

2 - Exportamos los settings desde el menú Tools - Import and Export Settings...

3 - Seleccionamos la opción Export selected enviromment settings, marcamos todos los settings y seleccionamos una ruta para guardar el fichero, por ejemplo: "C:\VSSettings\Desarrollo.vssettings"

Repetimos los pasos con un fondo distinto o un tipo de letra diferente y lo guardamos en "C:\VSSettings\Produccion.vssettings"

4 - Creamos un acceso directo en el escritorio, en el destino seleccionamos el fichero devenv.exe que es el que lanza el Visual Studio (generalmente está en C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE).

5 - Abrimos las propiedades del acceso directo y cambiamos el destino por:

devenv.exe "C:\Mi_Solucion_Desarrollo\MiSolucion.sln" /resetsettings "C:\Vssettings\desarrollo.vssettings"

6 - Creamos otro acceso directo como en el paso 4.

7- Cambimos el destino por:

devenv.exe "C:\Mi_Solucion_Produccion\MiSolucion.sln" /resetsettings "C:\Vssettings\Produccion.vssettings"


Y listo, ya tenemos un acceso directo para que nos abra cada solución con una configuración del IDE de Visual Studio diferente.

Lo cierto es que tarda un poco más en iniciarse ya que tiene que cargar la configuración pero creo que nos evitará muchos dolores de cabeza :)


Happy codding ;)

miércoles, 30 de septiembre de 2009

Que gran verdad!!

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

Alguna gente, cuando se enfrentan a un problema piensan: "Ya sé, usaré expresiones regulares." Ahora tienen 2 problemas.


Jaime Zawinski



Yo diría más, si encuentras expresiones regulares en el código, busca al que lo haya programado y dale una colleja (y otra de mi parte).

martes, 10 de marzo de 2009

Truco rápido: todos los mensajes de error de SQL Server a mano

Cuando trabajas con SQL Server estás acostumbrado a que los mensajes de error que aparecen en el fichero ERRORLOG o en el visor de sucesos sean bastante crípticos y lo normal es acabar tirando de [ponga aquí su buscador favorito] para saber de qué se trata.

Pues bien, hace tiempo que descubrí ,dentro de la enormidad que son los libros en pantalla de SQL Server, una página con los códigos de error organizados por número, y desde entonces es mi primera opción a la hora de buscar, así que aquí la tenéis:

http://technet.microsoft.com/es-es/library/cc645603.aspx (en castellano)

http://technet.microsoft.com/en-us/library/cc645603.aspx (en inglés)


Espero que os sirva de ayuda ;)

viernes, 23 de enero de 2009

Leones o lobos: ¿cómo es tú organización?

[WARNING: post de desahogo]

¿Quién no se ha pasado alguna tarde muerta viendo documentales de naturaleza?

El mundo animal es fascinante y es curioso ver cómo se organizan las diferentes especies para lograr su objetivo: la supervivencia. Pongamos 2 ejemplos, los leones y los lobos.

Los leones

Los leones viven en la sabana, espacios abiertos y (en la época de lluvias) grandes manadas de gacelas, ñus y antílopes (vamos, comida) a su disposición. Se organizan en clanes, con uno o varios machos (aunque sólo uno es el dominante) y unas 5 o 6 leonas.

Las leonas son las encargadas de cazar y cuidar a las crías. Suele haber una leona veterana (no siempre la de más edad) que es la que organiza la caza, la que selecciona el objetivo y la que inicia el ataque. Esta leona es la que más probabilidades tiene de salir herida del choque, ya que es la que ataca cuando la presa no está herida ni cansada.

Por su parte los leones ... pues no hacen gran cosa, se pasan durmiendo entre 16 y 20 horas al día, son incapaces de cazar y en el momento que las leonas traen lo que han conseguido (con mucho esfuerzo y dejándose la piel en ello) van los leones y se quedan con la mejor parte.

¿Es esto justo? No, no es justo, es la ley del más fuerte.

¿Cuál es entonces la función de los leones? Básicamente, defender el territorio cuando llegan otros leones jóvenes a ocuparlo. Cuando un león se hace adulto y en su clan ya hay un macho dominante lo que tienen que hacer es ir a ocupar el territorio de otro clan. Esto sólo hay una forma de hacerlo y es venciendo al macho dominante del otro clan. Luchan y el que gane se queda el territorio. Si el que gana ya era el dueño del territorio, no pasa nada, todo sigue igual. Pero si el que gana es el macho joven que viene de otro clan, entonces se queda con todas las leonas y mata a todas las crías que haya. Esto lo hace por pura supervivencia, ya que esas crías son del anterior macho dominante y lo podrán poner en peligro en el futuro.

Cuando un león pierde un combate por el territorio, es desterrado y suele morir de hambre en pocos días, porque depende absolutamente de las leonas para conseguir comida.


Los lobos

Los lobos suelen vivir en bosques y terrenos más escarpados, con pocas presas a su disposición. También se asocian en clanes, con territorios muy marcados, suele haber varios machos y hembras, con un macho dominante que es el que guía al clan, pero también es el que organiza la caza y la defensa del territorio.

En un clan de lobos, todos cazan y la comida se reparte entre todos. Todos defienden el territorio y todos tienen, más o menos, las mismas obligaciones. Aunque se tiene la creencia de que los lobos son carroñeros, únicamente cazan animales sanos, y a veces se ven obligados a cazar animales más grandes que ellos, lo que entraña un gran peligro ya que suelen salir heridos del choque y sin sacar beneficio.

A veces uno o varios lobos abandonan el clan, pero como siempre han compartido las tareas de caza con sus compañeros, son capaces de sobrevivir y pueden llegar a formar su propio clan.



Las organizaciones

No sé si habéis visto la similitud que quería crear entre cómo se organizan los animales con la organización de las empresas, pero por si acaso me explico:

Hay empresas que son leones, hay un león que manda y que es el que se lleva el mérito de todo, pero son las leonas las que trabajan, se dejan la piel y ven como es el león el que se lleva la mejor parte de lo obtenido. Este primer caso se suele dar más en las grandes empresas, con varios leones defendiendo su territorio y sus leonas del ataque de otros machos jóvenes.

Los leones ocupan los puestos de gestión, ya sea dirigiendo proyectos o departamentos enteros con otros leones a sus órdenes. A veces llega otro león más joven y los echa de su territorio, y como pierde sus leonas es incapaz de sacar nada de trabajo adelante ya que es incapaz de cazar.

Hay otras organizaciones que son como un clan de lobos, todos reman en la misma dirección y, más o menos, el trabajo y el beneficio se reparten entre todos por igual. Suele darse más en empresas pequeñas y suele ser más gratificante trabajar en ellas.



A mí desde siempre me gustan más los lobos, pero por desgracia ahora estoy en un clan de leones ... y me toca cazar :(

martes, 20 de enero de 2009

Nada que añadir

El que trabaje en el desarrollo de software y no se vea reflejado en esto es que o es una rata o tiene una patata cocida en vez de corazón:

Fuckowski, memorias de un ingeniero

GRANDE Fuckowski, muy grande ;)




PD: es un tocho pero no tiene desperdicio, por favor, leerlo hasta el final.
PD2: sí, es de hace tiempo, pero Stairway to Heaven también y no deja de ser genial :D

miércoles, 7 de enero de 2009

Pasar filas a columnas con T-SQL: PIVOT() y las cosas que te alegran el día :)

English version

A veces las cosas que parecen complicadas tienen una solución muy fácil pero que no siempre es la primera que se nos ocurre (no es exactamente el principio de la navaja de Ockham, pero se le parece).

Veamos, el caso es que hay una tabla de logs en la que varios procesos van insertando el resultado de su paso por diferentes estados, algo como esto:



Proceso Estado Timestamp

Proceso1 10 2008/12/21 12:22:05.320
Proceso2 10 2008/12/21 12:22:05.358
Proceso1 11 2008/12/21 12:22:06.210
Proceso1 12 2008/12/21 12:22:06.588
Proceso2 11 2008/12/21 12:22:10.100
Proceso2 12 2008/12/21 12:22:10.048
Proceso3 10 2008/12/21 14:30:05.358
Proceso3 11 2008/12/21 14:30:20.052



Para poder hacer un seguimiento de los procesos y así identificar problemas de rendimiento en ciertos momentos: entran muchos procesos a la vez, se hacen copias de seguridad, el servidor se queda sin memoria, ... sacamos una consulta agrupando por proceso y hora.

SELECT proceso, count(*) as peticiones, datepart(hh,Timestamp) as hora
FROM MiLOG with (nolock)
GROUP BY proceso, datepart(hh,Timestamp)
ORDER BY 1,3

Con esta consulta teníamos un resultado parecido a este:


Proceso Peticiones Hora
Proceso1 10 12
Proceso1 2 13
Proceso2 5 12
Proceso2 3 13
Proceso3 25 14
Proceso3 4 15



Pero claro, esta salida es un poco complicada de tratar porque aunque estén agrupados por el proceso y la hora cuando hay muchos datos se vuelve muy farragoso comprobarlos, y acabamos llevando los resultados a una hoja de cálculo para que se viesen más claro. Entonces me pregunté, ¿no habrá una forma de hacerlo desde T-SQL para que me convierta las filas en columnas? Vamos, que haya una columna por cada hora y una única fila para cada proceso.

Como siempre la primera solución en una consulta complicada es una sub-consulta (no sé porqué pero es así, alguien tendría que estudiarlo :P) pero en este caso no se trataba de una sub-consulta, sino más bien de 24 sub-consultas, todas atacando a la misma tabla y todas usando la función datepart(hh,Timestamp). Seguro que con eso obtendríamos en resultado esperado, pero a costa de un rendimiento muy muy pobre.

Como esta situación es muy común tenía que haber una forma fácil que solucionarlo, así que en una primera búsqueda de Google no me sorprendió los primeros resultados mostrasen la misma solución de las sub-consultas (por el principio de que la primera solución en una consulta complicada es una sub-consulta :P) ya me veía haciendo una mega-consulta con sub-consultas, JOINs sobre la misma tabla y demás, pero ya en la primera página de resultados encontré una solución mucho más simple: la cláusula PIVOT (que es una novedad SQL Server 2005, así que no lo intentéis con versiones anteriores).

Así que con una consulta como esta:

WITH Procesos( proceso, peticiones, hora)
AS(
SELECT proceso, count(*) as peticiones, datepart(hh,Timestamp) as hora
FROM MiLOG with (nolock)
GROUP BY proceso, datepart(hh,Timestamp)
)
SELECT * FROM Procesos PIVOT(SUM(peticiones) FOR Hora IN ([0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23])) AS Resultado
order by proceso

sí que tenemos el resultado esperado:


Proceso 0 1 2 ... 21 22 23

Proceso1 0 10 23 4 5 21
Proceso2 12 11 15 22 17 8
Proceso3 9 7 2 19 9 13


Como curiosidad decir que la cláusula PIVOT() únicamente acepta funciones de agregado (COUNT, SUM, MAX, AVG, ...), lo cual es totalmente lógico.

Otra cosa, igual os extraña ese

WITH Procesos( proceso, peticiones, hora) AS(...)

se trata de una expresión de tabla común (CTE) que es una forma de especificar un conjunto de resultados temporal con un nombre que puede ser usado en otras consultas.

Bueno, para empezar el año creo que está bien :D

Happy codding ;)



Bola extra: después de pensar en las sub-consultas y antes de descubrir la cláusula PIVOT, pensé en usar CUBE, que también podía servir, pero no era exactamente lo que buscaba, aquí tenéis un muy buen tutorial sobre CUBE.

miércoles, 31 de diciembre de 2008

Propósitos para 2009

Como siempre que se acaba algo es bueno echar la vista atrás y hacer un poco de reflexión de cómo ha sido el año, personalmente el 2008 ha sido decepcionante en algunos aspectos, vamos que no será un año que recuerde con nostalgia, pero no quiero ser pesimista (mi carácter me lo impide) y tengo que reconocer que este año he sacado unas cuantas buenas experiencias que merecieron la pena ser vividas :)

Y como cada vez que se empieza algo, también es bueno tener un plan, por pequeño que sea, de cómo nos gustaría hacer las cosas, así que hay van mis propósitos para 2009:

En lo personal, intentar ser feliz, que con la que está cayendo creo que ya es bastante. Y disfrutar un poco más de la vida, ser un poco más irresponsable y hacer las cosas que me apetece hacer antes de las que “debería” hacer.


En lo profesional:

  • Darle un poco de caña al tema web, que lo tengo bastante abandonado desde hace tiempo y siempre es bueno cambiar de chip de vez en cuando y actualizarse un poco.
  • Poner en práctica las cosas nuevas que he aprendido este año, como SCRUM.
  • Mantenerme al día de las novedades que vayan apareciendo en .NET (.NET 4.0 y VS 2010 ya están a la vuelta de la esquina), pero sin volverme loco, que para estar al corriente de todo hay que ser un super-desarrollador :P
  • Intentar escribir cosas más interesantes en el blog, que lo tengo un poco abandonado pero ganas no me faltan.
  • Seguir aprendiendo cosas nuevas, que aunque no tengan que ver directamente con el trabajo, siempre aportan algo.

Seguro que cuando vaya avanzando el 2009 mis prioridades irán cambiando, como siempre lo afronto con ilusión y ganas, a ver qué tal sale todo :)

FELIZ AÑO A TOD@S y happy codding ;)

martes, 30 de diciembre de 2008

Problema (y solución) al instalar .NET Framework 3.5 (V)

Seguimos con errores al instalar el .NET Framework 3.5 SP1, esta vez se trata de un Windows XP SP2 que, aparentemente, no tienen ningún .NET Framework instalado:


[XX/XX/08,16:24:15] RGB Rast: [2] Error: Installation failed for component RGB Rast. MSI returned error code 1625
[XX/XX/08,16:24:30] WapUI: [2] DepCheck indicates RGB Rast is not installed.

Intentamos instalar manualmente el componente RGB RAST pero se produce el siguiente error:

MSI (s) (9C:AC) [16:26:53:437]: Machine policy value 'DisableUserInstalls' is 0
MSI (s) (9C:AC) [16:26:53:453]: File will have security applied from OpCode.
MSI (s) (9C:AC) [16:26:53:453]: SOFTWARE RESTRICTION POLICY: Verifying package --> 'C:\dotnetfx30\RGB9RAST_x86.msi' against software restriction policy
MSI (s) (9C:AC) [16:26:53:453]: SOFTWARE RESTRICTION POLICY: C:\dotnetfx30\RGB9RAST_x86.msi has a digital signature
MSI (s) (9C:AC) [16:26:53:531]: SOFTWARE RESTRICTION POLICY: SaferComputeTokenFromLevel reported failure. Assuming untrusted. . . (GetLastError returned 1260)
MSI (s) (9C:AC) [16:26:53:531]: La instalación de C:\dotnetfx30\RGB9RAST_x86.msi no está permitida debido a un error en el proceso de directiva de restricción del software. No hay confianza en el objeto.
MSI (s) (9C:AC) [16:26:53:531]: Note: 1: 1718 2: C:\WINDOWS\Installer\1b5ea04.msi
MSI (s) (9C:AC) [16:26:53:531]: MainEngineThread is returning 1625
MSI (c) (74:88) [16:26:53:640]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1
MSI (c) (74:88) [16:26:53:640]: MainEngineThread is returning 1625


Como os podéis imaginar, en las políticas de restricción de software del equipo no había ABOSLUTAMENTE NADA!!! Tenía permisos de administrador pero por algún motivo no me dejaba instalar un componente de la propia Microsoft.


Buscando un poco encuentro la solución en esta página: http://support.microsoft.com/kb/925336 que consiste en:


1. Haga clic en Inicio y en Ejecutar, escriba regedit y haga clic en Aceptar.


2. En el Editor del Registro, busque la clave siguiente y después haga clic en ella:
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers

Nota: antes de modificar la clave, recomendamos que haga un copia de seguridad. Para ello, haga clic con el botón secundario en CodeIdentifiers y, a continuación, haga clic en Exportar. Guarde el archivo en una ubicación donde pueda buscarlo en el equipo.

3. Cambie el valor del Registro PolicyScope. Para ello, haga doble clic en PolicyScope y, a continuación, cambie la configuración de 0 a 1.

4. Cierre el Editor del Registro.

5. Haga clic en Inicio y en Ejecutar, escriba cmd y, a continuación, haga clic en Aceptar para abrir una ventana de símbolo del sistema.

6. En el símbolo del sistema, escriba el comando siguiente y presione ENTRAR:

net stop msiserver

Este comando detiene el servicio Windows Installer si se está ejecutando actualmente en segundo plano. Cuando el servicio se haya detenido, cierre la ventana de símbolo del sistema y, a continuación, vaya al paso 7.

Nota: si recibe el mensaje siguiente en el símbolo del sistema, cierre la ventana de símbolo del sistema y, a continuación, vaya al paso 7: El servicio Windows Installer no se inicia

7. Instale el paquete que estaba intentando instalar cuando recibió el mensaje de error que se menciona en la sección "Síntomas".

8. Después de instalar el paquete, repita los pasos 1 y 2. A continuación, vuelva a establecer el valor del Registro PolicyScope en 0.

9. Si desconectó el equipo de un dominio, vuelva a unirse al dominio y, a continuación, reinicie el equipo.Nota: si no desconectó el equipo de un dominio, no tiene que reiniciarlo.

Lo curioso del tema es la posible explicación que dan, que dice algo como: “Si un archivo de paquete .msi o .msp es demasiado grande para caber en una parte contigua de memoria virtual, Windows Installer no puede comprobar que el paquete es correcto.”

Y claro, en vez de decir que no puede instalarlo porque no tiene memoria virtual suficiente, pues nos dice que no tenemos permisos porque hay una política de restricción de software que lo impide, todo muy coherente, sí señor ¬¬


Volviendo al tema, una vez modificada la entrada en el registro, se intenta la instalación, pero vuelve a fallar, esta vez con el error :


[09/03/08,11:30:32] Microsoft .NET Framework 2.0a: [2] Error: Installation failed for component Microsoft .NET Framework 2.0a. MSI returned error code 1603
[09/03/08,11:32:03] WapUI: [2] DepCheck indicates Microsoft .NET Framework 2.0a is not installed.

Este ya es un error conocido, y lo solucioné como otras veces: Problema (y solución) al instalar .NET Framework 3.5 (II)

Relacionado:
Problema (y solución) al instalar .NET Framework 3.5 (I)
Problema (y solución) al instalar .NET Framework 3.5 (II)
Problema (y solución) al instalar .NET Framework 3.5 (III)
Problema (y solución) al instalar .NET Framework 3.5 (IV)

jueves, 6 de noviembre de 2008

Try ...Catch y RAISERROR en T-SQL: ¿es un bug o una feature?

No voy a entrar a explicar cómo se usan los bloques Try...Catch en T-SQL, que para eso ya está el MSDN: http://msdn.microsoft.com/es-es/library/ms179296(SQL.90).aspx

si no que os voy a contar un caso curioso que nos ha pasado estos últimos días:

Tenemos una aplicación en VB 6.0 (sí, tiene que ser en VB 6.0 por narices, así que es lo que hay) que tiene que llamar a store procedures de una base de datos SQL Server 2005 usando ADO (sí, el clásico no el .NET), bueno, el caso es que en algunos store procedures tenemos algo parecido a esto:


CREATE PROCEDURE Mi_Procedure
AS
BEGIN
BEGIN TRY
... Código antes del RAISERROR
RAISERROR(...) -- Este RAISERROR provoca que se vaya al bloque CATCH
... Código después del RAISERROR que no se ejecuta
END TRY
BEGIN CATCH
Exec Otro_Procedure @parametro1, @parametro2
RAISERROR(...) -- Este RAISERROR debería propagar el error al que ha llamado al store procedure
END CATCH
END


Bien, es algo bastante básico, pero lo curioso del tema es que tal y como está, desde ADO no se captura el error, ni se dispara un error interceptable ni está en la colección de errores de la conexión.

Investigando un poco descubrí que en Otro_Procedure que se llama desde aquí había una llamada a sp_executesql y esto provoca que por algún motivo se genere un entorno de ejecución diferente, lo que a su vez provoca que el ADO no capture el error.

¿Cuál puede ser la solución?
Teniendo en cuenta que no podíamos obviar la llamada a Otro_Procedure y tampoco a sp_executesql se me ocurrió la idea de darle la vuelta al bloque CATCH y hacer el RAISERROR antes de la llamada a Otro_Procedure. La idea parece un poco absurda si pensamos que el bloque TRY...CATCH funcionase como, por ejemplo, en C#, pero aquí viene el origen del post, el bloque TRY...CATCH en T-SQL te permite ejecutar cualquier instrucción después de hacer un RAISERROR.

O_o

¿¿¿ Eing???

Pues sí, la lógica dice que en un CATCH cuando hagas un RAISERROR este se propagará hacia arriba hasta llegar al llamador del procedure, pero la implementación en T-SQL hace que esto no sea así y que no se finalice la ejecución hasta llegar al END CATCH, con lo que después del RAISERROR podemos poner la/s instrucciones que queramos que se van a ejecutar.

Por supuesto, haciendo la misma llamada al store procedure desde .NET con ADO.NET siempre se intercepta el error, esté el RAISERROR del CATCH antes o después de la llamada a Otro_Procedure, con lo que +1 para ADO.NET :)

Happy coding ;)

jueves, 9 de octubre de 2008

Con ofertas como esta dan ganas de dejar de trabajar

Iba a empezar el post diciendo algo como “Leo sorprendido en Halón Disparado una oferta de trabajo...” pero la verdad es que me di cuenta que no me sorprendió tanto, debe ser que de ver cosas como esta te acabas curtiendo.


Para el que no vea bien la imagen os lo transcribo, se trata de una oferta para un desarrollo en Argentina con las siguientes condiciones:


“Busco desarrollar lo siguiente:
Un Panel de control para un sitio web de una inmobiliaria, solamente el desarrollo del panel y la base de datos ya que el diseño corre por nuestra cuenta:


- Debe poder soportar múltiples usuarios (con diferentes perfiles – administrador y empleados-)
- Se debe poder cargar los inmuebles de las propiedades conectando con una base de datos mysql
- Las imágenes de los inmuebles se deben guardar en una carpeta del servidor
- Se debe poder destacar las imágenes para que puedan aparecer en el index.php como imágenes destacadas
- Debe poseer diversos parámetros: cantidad de habitaciones, superficie, precio, dirección, provincia, ciudad y observaciones adicionales.
- Debe poseer una interfaz de carga ágil, dinámica y sencilla de entender.
- Debe poseer un buscador interno de propiedades con varios parámetros de búsqueda.
- Debe poseer un ABM de propiedades, entendible.
- Se debe confeccionar manual de operaciones del panel de control
”

Bien, son una serie de requerimientos bastante imprecisos para un desarrollo de algo tan complejo, pero lo mejor viene con las condiciones de la oferta:

Tiempo de entrega: 15 días
Presupuesto: 200,00 ARS (46,72 EUR)

Ante esto sólo me vino una cosa a la mente WTF!!! Es que estamos tontos o qué es lo que pasa. Vale que haya una acuciante crisis mundial (sinceramente yo ni me he enterado, pero bueno es lo que tiene no tener dinero para invertir :P) pero es que ese presupuesto no se le puede considerar un sueldo, es poco menos que una propina :(

¿En serio piensan que alguien en su sano juicio desperdiciará 15 días de su vida por menos de 50 €? 46,72 € /15 días = 3,11 €/día!!!!! Vamos, que no te da ni para pagarte un desayuno.

¿En qué clase de mundo vive el que hace esta oferta? Seguro que piensa que hay algún desarrollador web por ahí que tiene algo parecido ya hecho y no le importa venderlo, pero ¿alguien vendería su trabajo por esa miseria?


Mientras escribo el post me he vuelto a leer la oferta y me llaman la atención un par de cosas más:

- Al principio de la oferta dicen que ya se encargarán ellos del diseño (¿buscarán un diseñador que se lo haga por 20 €?) pero también piden que tenga “una interfaz de carga ágil, dinámica y sencilla de entender”. Y digo yo, la interfaz y el diseño como que van bastante de la mano, así que la mayor parte de SU trabajo ya estaría hecho, ¿no?


- Me encanta como describen lo que tiene que convertirse en el diseño de la base de datos: “Debe poseer diversos parámetros: cantidad de habitaciones, superficie, ...” Y el resto te lo inventas que para eso te pagamos un pastón.


- Dicen que “las imágenes se deben guardar en una carpeta en el servidor”, que seguro que llegan allí por arte de magia y se relacionan con los inmuebles por telepatía.


- Buscador interno, múltiples usuarios, ... vamos lo normal, pero lo mejor es que “Se debe confeccionar manual de operaciones”, claro que sí, y en varios idiomas y todo. Y aún querrán los fuentes y que les des mantenimiento de la aplicación 24 horas/365 días, como si lo viera.

Tengo que reconocer que en mientras estudiaba aproveché que teníamos que hacer un proyecto de tienda virtual (o e-commerce que mola más) para una asignatura y con un compañero se lo “vendimos” a una tienda real (de cómics, juegos de rol, y frikadas varias) y no le cobramos nada.

Pero es que a mí personalmente me sirvió de mucho ya que teníamos que hacerlo de todas formas para la asignatura y así aprendimos lo que es una implantación real y los problemas que plantea. Pero lo de esta oferta es de juzgado de guardia, no sólo quieren que algún pobre desgraciado les haga un proyecto bastante complejo (porque son muy listos y la mitad de las cosas obvias que hay que hacer no las ponen como requerimientos) en 15 días, si no que quieren pagar una auténtica miseria por ello.

Espero que todo esto se trate de un error al poner el presupuesto, porque de ser real esta gente piensa que los desarrolladores somos completamente estúpidos :( Lo malo es que se trate o no de un error existe gente que piensa así, y que nuestro trabajo no vale el precio que le ponemos porque total, ya está todo hecho.

PD: No sé qué es un ABM, si alguien lo sabe por favor que me lo diga por si acaso algún cliente me lo pide algún día y así no me quedo con cara de tonto.

PD2: He puesto esta entrada en la categoría de Humor porque es mejor no tomarse estas cosas en serio.

miércoles, 1 de octubre de 2008

.NET Framework 4.0 y Visual Studio 10: que paren que yo me bajo

Leo en varios blogs como este, o este otro (en inglés) o la nota de prensa oficial (también en inglés) la noticia de que los chicos de Microsoft ya tienen bastante definidos lo que será el próximo .NET Framework (y ya vamos por el 4.0) y la nueva versión de Visual Studio (que como siempre van de la mano).

No me voy a parar en comentar las novedades que prometen porque ya hay un montón de gente que sabe más que yo de esto que lo están haciendo, pero el hecho de que salga la noticia me plantea un par de preguntas que lanzo al aire:

  • ¿Por qué pasa tan poco tiempo entre una versión y la siguiente?
  • ¿Son imprescindibles los cambios que aportan las nuevas versiones? ¿Los vamos a usar al 100%? ¿Alguien los va a llegar a usar todos o una gran parte de ellos?
  • ¿Acabamos los desarrollos que tenemos entre manos con la versión actual o nos conviene esperar a las novedades de la nueva? ¿Sacamos una nueva versión cuando salga el nuevo Framework?
  • ¿Alguien es capaz de seguir este ritmo? ¿Estamos locos los desarrolladores?


Cuando mucha gente aún no se ha pasado a la versión 3.5 del .NET Framework, se encuentran con que ya está prevista la 4.0, cosa bastante natural con la forma de trabajar de Microsoft. Pero es que hay que recordar que el .NET Framework sólo lleva entre nosotros desde 2002, con lo que tenemos que en 6 años han aparecido 5 versiones (1.0, 1.1, 2.0, 3.0 y 3.5), casi a versión por año (y eso sin contar con los Service Packs).


¿Qué aportaron estas nuevas versiones en su momento? Recordando así por encima, la 2.0 aportó bastantes mejoras en el Framework, sobre todo en ADO.NET y ASP.NET. La 3.0 nos introdujo WCF, WF, WPF y esa cosa que llamaron CardSpace pero que no he visto funcionando en ningún sitio. Y la 3.5 es una revisión de la 3.0 y además nos trae LINQ y en paralelo apareció Entity Framework.


Tanto la nueva versión del .NET Framework como la del Visual Studio prometen lo de siempre: mejorar la vida de los desarrolladores para que podamos crear aplicaciones de gran calidad en el menor tiempo posible. Vaya, pues si es así lo quiero YA!!!


Pero es esto que se llama la Vida Real™ los pobres curritos-pica-código nos encontramos con que la mayoría de “mejoras” no nos servirán absolutamente para nada cuando tenemos el plazo de finalización del proyecto echándonos el aliento en la nuca (que mal rollo que da esa frase :P) y los pocos que nos servirían implican cambiar tantas cosas que tendríamos que modificar la mitad del proyecto o empezarlo casi de 0, porque, reconozcámoslo, nunca se hacen las cosas tan bien que sean totalmente reutilizables.


Después están los que lo prueban todo, desde las versiones alfa, y ya empiezan los nuevos proyectos con las nuevas versiones cuando no han ni empezado a asomarse. Pero yo creo que esa gente no es de este planeta, porque entre el tiempo que dedican al trabajo, el de probar las nuevas versiones, escribir en diferentes blogs, leer lo que escriben los demás, preparar podcast, webcast y presentaciones,... a mí no me quedaría tiempo para casi nada, así que me imagino que o no comen, o no duerme o tienen un reloj que les permite viajar en el tiempo. O tal vez sus horas tienen 99 minutos porque encontraron un bug en el sistema horario.


Menos mal que estos son 4 elegidos por el ente supremo (llámalo Dios o el monstruo espagueti volador) porque si no todos los que nos dedicamos a esto y no tenemos sus superpoderes nos quedaríamos en el paro. Porque últimamente es muy pero que muy complicado ser desarrollador en .NET y no morir bajo la avalancha de novedades que nos llega casi sin avisar.

Así que creo que para los simples mortales nos quedan 3 opciones claras:



  • Dejar la programación y dedicarnos al cultivo del tomate (así por lo menos tendremos algo que comer)

  • Detenernos en una versión y meternos en una cueva aislada del mundo hasta finalizar nuestros proyectos.

  • Echarle ... narices e intentar mantenernos al día de todas las novedades, pero sin perder la perspectiva de que hay que acabar los proyectos porque hay jefes/clientes que esperan las cosas para ayer. O casi mejor al revés (más que nada para que no nos despidan), finalizar nuestros proyectos pero sin perder de vista las novedades y las futuras versiones.

Ahora es decisión vuestra como desarrolladores elegir la mejor opción, yo por mi parte ya tengo con quien abrir una plantación de tomates :P


PD: debo dar las gracias al compañero Ipas por los links y a Santi por inspiarar este post.