Rutas
/
Common Lisp
Common Lisp
/
Ejercicios
/
Presentarse al servicio
Presentarse al servicio

Presentarse al servicio

Ejercicio de aprendizaje

Introducción

Formato: lo básico

Common Lisp tiene un concepto llamado The Printer que incluye todas las funciones para escribir representaciones textuales de datos de Lisp. Una de esas funciones es format, que permite dar formato a los datos a gusto de quien programa.

Las capacidades de format y del Printer de Lisp en general son un tema amplio; aquí se describirán los aspectos básicos del uso de format.

La función FORMAT

La función format recibe al menos dos argumentos: un stream al que imprimir y un string de control que define qué se va a imprimir y cómo.

Los streams son un concepto aparte y se describirán en otro sitio. Pero por ahora basta con saber que la impresión se hace en el stream y que hay dos valores especiales para este argumento: t y nil. t significa imprimir en la salida estándar (en realidad, el stream al que está ligada la variable *standard-output*), y nil significa crear un string y devolverlo.

Ten en cuenta que format siempre se evalúa a nil, excepto en ese último caso en el que se especifica nil como stream. Esta es una forma habitual de hacer una simple interpolación o construcción de strings.

(format nil "hello world") ; => "hello world"
(format t "hello world")   ; => NIL (but "hello world" is printed to standard output)

Directivas de formato

El string de control puede contener «directivas de formato» que le dan instrucciones a format sobre qué imprimir y cómo interpretar cualquier otro parámetro que reciba. En cierto sentido, el string de control es un programa que format interpretará y ejecutará. Todas las directivas empiezan por ~ y van seguidas de un carácter (p. ej., ~A, ~D, ~&). El uso de mayúsculas o minúsculas en ese carácter da igual.

La mayoría de las directivas de formato simplemente interpolan en la salida un argumento de format. Se dice que «consumen» el argumento. Algunas directivas no consumen argumentos, o consumen más de uno. Una directiva incluso te permite saltar de un sitio a otro en la lista de argumentos u omitir argumentos.

Formato básico

Una directiva de formato muy polivalente es ~A. Imprime una versión de los datos «legible por humanos».

(format nil "Value = ~a" 10)                ; => "10"
(format nil "hello ~a" "world")             ; => "hello world"
(format nil "The list is: ~A" (list 1 2 3)) ; => "The list is: (1 2 3)"

Otra directiva de formato útil es ~S. Imprime una versión de los datos «legible por máquinas». Puede resultar muy útil si quieres poder interpretar la salida generada como datos de Lisp. En muchas cosas se verá igual que ~A, pero fíjate en que, por ejemplo, en el caso de los strings la salida incluirá las comillas (escapadas cuando se incluyen dentro de otro string), de modo que el valor se pueda volver a leer como el parámetro string.

(format nil "~s" 10)            ; => "10"
(format nil "~s" "hello world") ; => "\"hello world\""
(format nil "~s" (list 1 2 3))  ; => "(1 2 3)"

Otras dos directivas muy útiles son ~% y ~&. La primera genera un carácter de nueva línea, mientras que la segunda genera una «línea nueva». La diferencia es que ~% siempre genera una nueva línea, mientras que ~& solo la genera si no estás al principio de una línea. Ninguna de las dos consume argumentos.

(format nil "~%new~%lines") ; => "
                                  new
                                  lines"

(format nil "~&new~&lines"  ; => "new
                                  lines"

Por último, ~~ es una directiva sencilla que genera un ~ literal.

Instrucciones

Como casi cualquier persona con un trabajo, Layla, la alienígena de Lisp, a veces necesita hacer informes para que los demás conozcan cierta información. Te pregunta si puedes ayudarla a dar formato a los datos que tiene para estos informes.

1. Dar formato a valores trimestrales

Lo primero que necesita Layla es una función: format-quarter-value, que toma dos parámetros, el trimestre del calendario y el valor, y les da formato para un informe. Debe evaluarse a un string.

(format-quarter-value "last" 3.14) ; => "The value last quarter: 3.14"
(format-quarter-value "this" 0) ; => "The value this quarter: 0"

2. El informe de dos trimestres

Layla te da las gracias por la función format-quarter-value y dice que será muy útil en la siguiente función que se necesita.

El siguiente informe debe mostrar el trimestre y el valor de 2 trimestres impresos en dos líneas.

Además, la salida debe ir al stream proporcionado como primer argumento.

Por ejemplo: (format-two-quarters t "last" 3.14 "this" 0) producirá lo siguiente en la salida estándar:


The value last quarter: 3.14
The value this quarter: 0

Fíjate en las líneas en blanco que lo rodean.

3. Legible para humanos y para alienígenas de Lisp

Layla olvidó decirte que a los alienígenas de Lisp les gusta ver los valores de una forma que sea legible como datos de Lisp. Así que necesitan una nueva función cuyo resultado pueda leerse como datos de Lisp (de nuevo, en el stream indicado):

(format-two-quarters-for-reading nil "last" 3.14 "this" 0) ; =>

"(\"The value last quarter: 3.14\" \"The value this quarter: 0\")"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Common Lisp Exercism

¿Listo para empezar Presentarse al servicio?

Regístrate en Exercism para aprender y dominar Common Lisp con 27 conceptos92 ejercicios y mentoría humana real, todo gratis.