programación - Tienda de ultramarinos
logo Tienda de Ultramarinos
Etiquetas: programación

Incremento y decremento

Hoy toca post para informáticos. Como bien sabréis, muchos lenguajes disponen de una forma abreviada de indicar incrementos y decrementos, que son ‘++‘ y ‘--‘. Esto, además de facilitar la vida a los programadores evitándoles escribir a=a+1, es también de utilidad para las optimizaciones que hace el compilador, puesto que en la mayoría de arquitecturas existen instrucciones de incremento y decremento que se ejecutan utilizando menos recursos que una suma convencional.

En algunos lenguajes, como en C y Java, se puede utilizar este operador delante y detrás de las variables, pero tiene un comportamiento distinto. Si el operador está delante, se hace primero la resta y se evalúa el resultado; mientras que si está detrás, primero se devuelve el valor, y después se realiza la resta.

Así, si b=10 y hacemos a=--b, a y b terminarán con valor 9, pero a=b-- terminará con a=10 y b=9.

Bien, recordado esto, en mis apuntes de compiladores se menciona como un código algo lioso a primera vista, la siguiente instrucción c=a---b--. A raíz de ello, he decidido pensar en  situaciones similares a ésta, que son:

c = --a---b;
c = --a-b--;
c = a-----b;
c = a---b--;
c = a---b;

Suponiendo que es ilegal --n--, y obviando la última (hay que acordar cómo se comporta) ¿Alguien se anima a hacer la traza? Es facilita, la hice ayer a mano en lugar de seguir estudiando :P.

Aunque todas salvo la última parezcan correctas y sin ambigüedades, curiosamente hay dos de ellas que ni C ni Java aceptan (con los compiladores GCC 2.8.1, Borlandc 3.0 y JDK 1.6). Son la primera y la tercera, y ocurre lo mismo si en lugar de ‘--‘ utilizamos ‘++‘. ¿Por qué? Pues imagino que por el tipo de análisis que hace el compilador.

Tal y como veo que se comporta (he hecho más pruebas aparte de esos 5 casos), cuando el analizador léxico lee el código carácter a carácter, siempre que encuentra dos ‘-‘ seguidos, los considera un único token ‘--‘ y así es como los envía al siguiente nivel.

Después, en el analizador sintáctico/semántico debe de existir algún tipo de precedencia asignada al operador ‘--‘ por encima de la resta y el opuesto, de modo que cuando se encuentra con --a, ó a--, hace directamente una reducción y pasa a considerar la expresión como una constante, a la que ya no tiene sentido volver a aplicar otro ‘--‘.

En el caso “especial” c=a---b, a mi juicio el único que es ambiguo y del que debería quejarse el compilador, se opta por aplicar el operador ‘--‘ a la variable a; siendo equivalente a ejecutar c=a-b y después a--.

También acepta correctamente c=-a--; // c = -a (y decrementar después a).

Otras asignaciones que dan error de compilación, y comentado a lo que debería corresponder:

c = ---a; //c = – (decremento de a)

c = --a--b; //c = (decremento de a) menos (-b)

c = a--b; // c = a menos (-b)

c = a----b; // c = a menos (-b) [y después decrementar a]

Por los errores que da el compilador, en el primer caso creo que intentar aplicar el operador ‘--‘ sobre ‘-‘, y en el tercer caso, evalua ‘a--‘, y después encuentra la b sin operadores entre ellos. En el segundo fallan dos cosas: primero aplica correctamente --a, pero al resultado no se le puede aplicar otra vez ‘--‘; el segundo fallo es que ha consumido el token ‘--‘ y se encuentra, de nuevo, con una b solitaria sin operadores entre la a. En el cuarto tenemos otros dos fallos similares al anterior.

¿Ocurrirá así en todos los compiladores de C, o habrán tenido esto en cuenta en algún caso? ¿O es algo definido directamente en el estándar? He echado un vistazo rápido al ANSI C buscando “decrement”, pero no he leído nada destacable.

Jornadas R-Project finalizadas

ACTUALIZADO: Están disponibles en internet los videos de todas las charlas.


Como advertía hace un mes, la semana pasada se celebró la I Conferencia Hispana R-Project, unas jornadas que nacieron con la pretensión de reunir y afianzar el grupo de usuarios de R de la comunidad hispanoparlante, objetivos que creo han logrado.

No voy a hacer un resumen del programa, pues de eso ya se encargó Carlos Gil Bellosta hace un par de días con bastante precisión y todo lo que yo dijera sería redundante. De modo que me limito a citarlo (a modo de trabajo colaborativo, como bromeó Francesc Carmona en su blog).

Yo no utilizo habitualmente R, de hecho mi contacto con él se limitó a las prácticas de Estadística en la universidad y al desarrollo de mi PFC; al cual precisamente se debía mi presencia en estas jornadas, pues está hecho de tal forma que cualquiera puede ampliarlo con poco esfuerzo para que distribuya el código que necesite a través de una mini-red de computadores que se cree personalmente.

La verdad es que estaba bastante nervioso (¡nunca había hablado en un congreso!) y no sabía cómo iba a calar la aplicación entre los asistentes, pero parece ser que a algunos les pareció interesante y así me lo hicieron saber; lo cual no deja de ser reconfortante. Dejo enlace al pdf con mi presentación.

Debo decir, que pese a mi escasa relación con R-project, he disfrutado bastante de las charlas. Había gente de todas las áreas, tanto estadísticos puros salidos de matemáticas, como físicos, biólogos, informáticos… La inmensa mayoría pertenecían al ámbito universitario, pero también había una pequeña representación de gente venida de empresas.

El caso es que siempre hay conocimientos transversales, útiles para todos, y como informático también me ha resultado interesante desde el punto de vista de cómo se organiza una comunidad en torno al software libre.

Muchos hablaron de sus comienzos utilizando R, en los que se encontraban prácticamente solos en su entorno —robinsones como alguien definió muy acertadamente— aprendiendo poco a poco con lo que podían encontrar en internet —en inglés, claro— y sintiéndose los bichos raros de su comunidad. Más tarde llegó la lista de R-es y todo empezó a cambiar, hasta la semana pasada en la que empezaron a ponerse caras tras dos o tres años intercambiando mensajes y comenzaron a hablar de proyectos más serios para intercambiar material y conocimientos entre todos.

Casualmente esta tarde leyendo el libro Máquinas que piensan, de Pamela McCorduck he llegado al capítulo en el que relata de forma bastante detallada la que ahora se conoce como Conferencia de Dartmouth, que en 1956 sentó las bases de la investigación en Inteligencia Artificial durante las siguientes dos décadas, y que vertebró, en cierto modo, toda esta disciplina. Digo casualmente, porque esa reunión de miembros aislados de diversas áreas que fueron las jornadas de R, me ha recordado de alguna manera a lo que Pamela relata sobre aquel verano del 56 en el Darmouth College —salvando las distancias, claro—. Dice:

«[…] la Conferencia de Darmouth fue también una confluencia de diversas corrientes intelectuales del siglo XX. Ellos mismos provenían de otras corrientes, del trabajo de individuos aislados en los campos de las matemáticas, la estadística, la psicología, la ingeniería, la biología, la lingüística, y las emergentes disciplinas de la ciencia empresarial. Si algunos científicos no estuvieron presentes en la conferencia, su espíritu estuvo representado por su trabajo y algunas veces por sus colegas y alumnos.»

De algún modo, al leer estas líneas hoy en el autobús hacia la universidad, he sentido que acababa de participar en algo parecido.

Los listos del C

Tengo una hipótesis que espero poder convertir pronto en teoria.

En toda carrera de informática hay al menos un listo del C por curso. Los listos del C son esos tipos que presumen de llevar toda su puta vida programando en C y que se lo conocen al dedillo. Son los típicos que tienen que tener la última palabra en toda discusión con el profesor sobre algún tema al respecto, y que si no pueden lo critican al final de la clase afirmando: “Yo sé más de C que él“.

Que probablemente sabrán un huevo, porque seguro que han programado tanto que cuando escriben la dirección de su casa le cascan un & delante, pero la actitud que adoptan es del típico listillo que a nadie le gusta.

Algunos llegan de módulos, y otros simplemente han bajado demasiados manuales de internet o hecho varios cursos. Supongo que por éstos últimos podemos ampliar la teoría también a los módulos.

¿Y vosotros? ¿Sois “Los listos del C” de vuestra clase o conocéis a alguno?

gotoxy(x,y) y clrscr() de C sobre Linux

Se me había ocurrido compilar algunos de los programitas que hice hace dos o tres años en C en Windows y claro, ahora en Linux daban algunos fallos por librerías y funciones utilizadas. Lo normal.

Sin embargo, me ha llamado la atención de que no funcionaran ni gotoxy(x,y), ni clrscr(). La primera para ir a unas coordenadas de la pantalla para poder escribir a continuación allí, en lugar de línea a línea, y la segunda para limpiar toda la pantalla. Y da la casualidad de que ayer me aburría y me apeteció programarme un Juego de la Vida de Conway, de modo que necesitaba una función que sustituyese al gotoxy(x,y).

Así pues he intentado mirar en algún manual y luego he googleado un poco. Parece ser que estas dos funciones sólo están en librerías del DOS, y que no hay equivalente en librerías existentes en Linux. Hay bastantes hilos en foros de gente preguntando por eso mismo, y en algunos la solución que dan es definir esas funciones en tu propio código. Por supuesto, acompañan el código.

El clrscr() no puede ser más simple: un bucle con tantos intros como desees, unos 50 serán más que suficientes, aunque todo depende del tamaño de la ventana. ¿Para qué complicarse más la vida?

Para el gotoxy(x,y) ya es necesaria una secuencia de escape, la \033:

Escape sequences allow you to send nongraphic control characters to a display device. For example, the ESC character (\033) is often used as the first character of a control command for a terminal or printer. Some escape sequences are device-specific. For instance, the vertical-tab and formfeed escape sequences (\v and \f) do not affect screen output, but they do perform appropriate printer operations.

He encontrado el código para la función gotoxy(x,y) en dos sitios, uno más largo y otro más reducido. He comprobado que funcionan ambas. Copio aquí el reducido:

#define MAX_SCREEN_AREA 100
int gotoxy(int x, int y){
char essq[MAX_SCREEN_AREA]={0}; // String variable to hold the escape sequence
sprintf(essq, "\033[%d;%df", y,x);
printf("%s", essq);
return 0;
}

De todas formas, he descubierto que no es necesaria tanta línea. Analizando el código que visto cómo funcionaba y he probado a incluir la secuencia de escape directamente en un printf() y, voilá, funciona. Supongo queirá también con scanf() y otros.

printf("\033[9;9f asdf\n");

Teacher, I wanna make code

 Pues sí. Yo quiero programar. Entiendo que tengamos que documentarlo todo, hacer una Memoria explicando a qué necesidades responde nuestro proyecto, qué alternativas hay, razones por las que utilizar unas tecnologías u otras, detallar los métodos y como funciona… Entiendo incluso que tengamos que incluir diagramas de secuencia y de clases mediante UML que, aunque debiéramos hacerlos antes —durante las primeras fases de inicio/elaboración— para seguir una estructura, apliquemos al final utilidades de ingeniería inversaque nos las construyan automáticamente a partir del código hecho.

¡Pero lo que no soporto es la parte de la planificación! Estudiar cómo funcionará la aplicación para sacarse unos cálculos de la manga y permitan hacer una estimación del tiempo que costará. Aplicar fórmulas contando casos de uso, puntos de función, factores de complejidad, entradas de usuario… ¡Que en su mayoría no significan nada ni son aplicables a una aplicación específica! Y que además son desmedidos. Después de toda la tarde aplicando los cálculos, la estimación ha quedado en que mi proyecto requiere 2080 horas. ¡Dos mil ochenta! Eso es una maldita burrada. He hecho el 80% del proyecto en los dos últimos meses. Le he echado muchísimas horas diarias, sin tomarme fiesta la mayoría de fines de semana; pero aún así, diez horas al día durante dos meses son 600 horas. ¡Ni una tercera parte!

Pero lo peor no es esto. Es que ahora debo detallar las diversas tareas que suponen toda la realización y asignarles horas de trabajo, hasta alcanzar las 2080. Y no me gusta. ¡Teacher! ¡I wanna make code!

El nombre del post viene de una canción compuesta por Jerome Jerome, Richard Byron, Walter Kent y que, en la versión que he escuchado, interpreta Cab Calloway con la Cotton Club Orchestra en 1937. La canción es Mamma, I wanna make rhythm.

«Es la historia de un chaval que está estudia, está tocando clásico con el violín, sinfonias y  no sé qué, y lo que el quiere tocar es la batería, y ahí está su madre diciendo “ensaya, hijo, practica el violín” y él se para y dice “Mamá, yo quiero hacer ritmo”».

Toda la información anterior la contó Juan Claudio Cifuentes, Cifu para los amigos, en la emisión de Jazz Porque Sí del pasado 24 de octubre. Gracias a Pons Asinorum me enteré el mes pasado de que RTVE ha decidido a publicar sus emisiones mediante podcast, de modo que ahora puedo seguir las emisiones de este programa cuando quiera. Me aficioné para septiembre del año pasado, cuando estaba en LA sin ordenador ni nada y lo escuchaba todas las noches. Luego, siempre se me pasa, o no puedo escucharlo o algo. Ahora me los descargo tranquilamente y los escucho cuando me apetece, reescuchando todo lo que quiero. 100% recomendable.

He cortado (con el mp3splt) el fragmento en el que la presenta, junto con Go South young man —puesto que las grabaron en la misma sesión— la reproducción de ambas y sus comentarios finales. Aquí os dejo el audio.

A continuación, por curiosidad, la letra de

Mamma, I wanna make rhythm

Yasha was a prodigy, since he was a kid of three
He could play a rhapsody as good as they come
But as strange as it may be, Yasha hated melody
He had a yen for tympani, he longed to play a drum
When his Mother made him practice on the fiddle every day
He’d stop right in the middle and he’d say….

Mama, I wanna make rhythm
Don’t wanta make music
Just wanna go zoozi-zah-zah-zoozi
Ooh-cah-dee-doodle-oodle-aah-doo

Mama, I wanna get hotcha
I wanta make boombah
I wanna go gah-gah
Za-rah-kah, zat-zow, ooh-dee-lah

I’ve got no desire to carry a Stradivarius, but
There’s no limit of primitive tom-tom in my tum-tum

Mama, I wanna make rhythm
Don’t wanta make music
Just wanna go wookee-ah-kay-a-kaya-kaya
Yag-a-yag-a-yag-a-yag

¿No os encanta cómo la gente intenta reproducir las locas partes de Scat?

Mente clara

Tras toda la mañana programando, y desde la hora de comer hasta media tarde me he bloquedado pensando cómo implementar una cosa. Para el Proyecto, del que aún debo alguna entrada aquí, necesito distribuir unas instrucciones entre diversos servidores de cálculo, que pueden estar ocupados computando anteriores, así que tenía que buscar una forma eficiente de comunicarse mediante mensajes para saber cuales están libres para enviarles su parte del procesamiento.

Y no se me ocurría nada decente, he pensado tumbado en la cama (muchas veces me tumbo unos instantes a pensarlo todo detenidamente y me vienen las ideas), le he dado vueltas mientras cagaba, conducía, comía… Y nada.

Así que a eso de las seis y media me he ido a escalar con un amigo, que el deporte viene bien para despejarse. Y al volver tres horas después, en la ducha, al acordarme del duro trabajo que me esperaba ahora y darle vueltas de nuevo al problema, en seguida me ha venido la solución a la cabeza.

Lo enfocaba mal, porque quería hacerlo todo con el método desde el que se solicita enviar todas las tareas a los servidores de cálculo. En la solución que he tomado, lo único que hace es enviar a todos ellos un mensaje preguntando por su estado. Lo que voy a hacer es que el método que procesa la respuesta con el estado de cada servidor, sea el que les envíe las órdenes si están libres.

Una solución sencilla en la que no había caído hasta que no he tenido la mente clara, durante la ducha después del ejercicio.

Maravillosa sensación

 Una de los mejores momentos en la vida de un programador es cuando todas esas clases que has ido implementando por separado se juntan por fin y todo adquiere significado.

java.util.Map

java.util.map