Percursos
/
Common Lisp
Common Lisp
/
Exercícios
/
Pronto para o serviço
Pronto para o serviço

Pronto para o serviço

Exercício de aprendizagem

Introdução

Formato - Noções básicas

O Common Lisp tem um conceito, o The Printer, que inclui todas as funções para escrever representações textuais de dados Lisp. Uma dessas funções é a format, que permite ao programador formatar os dados como quiser.

As capacidades da format, e do Printer de Lisp em geral, são um tema vasto; aqui vamos descrever as noções básicas da utilização da format.

A função FORMAT

A função format recebe pelo menos dois argumentos: um fluxo para onde imprimir e uma string de controlo que define o que imprimir e como.

Os fluxos são um conceito à parte e serão descritos noutro lugar. Mas, para já, só precisas de saber que a impressão é feita para o fluxo e que há dois valores especiais para este argumento: t e nil. t significa imprimir para a saída padrão (na verdade, o fluxo ao qual está associada a variável *standard-output*), e nil significa criar uma string e devolvê-la.

Repara que a format é sempre avaliada como nil, exceto nesse último caso, em que nil é indicado como o fluxo. É uma forma comum de fazer simplesmente interpolação ou construção de strings.

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

Diretivas de formato

A string de controlo pode conter "diretivas de formato", que dão instruções à format sobre o que imprimir e como interpretar os restantes parâmetros passados à format. De certa forma, a string de controlo é um programa que a format vai interpretar e executar. Todas as diretivas começam com ~ e são seguidas de um caráter (por exemplo, ~A, ~D, ~&). Não importa se o caráter está em maiúscula ou em minúscula.

A maioria das diretivas de formato limita-se a interpolar na saída um dos argumentos da format. Diz-se que a diretiva "consome" o argumento. Algumas diretivas não consomem argumentos, ou consomem mais do que um. Há até uma diretiva que te permite saltar dentro da lista de argumentos ou ignorar argumentos.

Formatação básica

Uma diretiva de formato muito versátil é a ~A. Imprime uma versão 'legível por humanos' dos dados.

(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)"

Outra diretiva de formato útil é a ~S. Imprime uma versão 'legível por máquinas' dos dados. Isto pode ser muito útil se quiseres conseguir interpretar a saída produzida como dados Lisp. Para muitas coisas, o resultado é igual ao da ~A, mas repara que, no caso das strings, por exemplo, a saída inclui as aspas (escapadas quando incluídas noutra string), para que o valor possa ser lido de volta como o 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)"

Mais duas diretivas muito úteis são a ~% e a ~&. A primeira emite um caráter de nova linha, enquanto a segunda emite uma "linha nova". A diferença é que a ~% emite sempre uma nova linha, ao passo que a ~& só a emite se não estiveres já no início de uma linha. Nenhuma delas consome um argumento.

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

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

Por fim, a ~~ é uma diretiva simples que emite um ~ literal.

Instruções

Como quase toda a gente que tem um trabalho, a Layla, a alienígena do Lisp, às vezes precisa de fazer relatórios para dar informações a outras pessoas. Pergunta-te se a podes ajudar a formatar os dados que tem para esses relatórios.

1. Formatar valores trimestrais

A primeira coisa de que a Layla precisa é de uma função, format-quarter-value, que recebe dois parâmetros: o trimestre do calendário e o valor, e que os formata para um relatório. Deve resultar numa string.

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

2. O relatório dos dois trimestres

A Layla agradece-te a função format-quarter-value e diz que vai ser muito útil na próxima função de que precisamos.

O relatório seguinte tem de mostrar o trimestre e o valor de dois trimestres, impressos em duas linhas.

Além disso, a saída tem de ser enviada para o stream fornecido como primeiro argumento.

Por exemplo: (format-two-quarters t "last" 3.14 "this" 0) produz o seguinte na saída padrão:


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

Repara nas linhas em branco à volta.

3. Legível para humanos vs. para alienígenas do Lisp

A Layla esqueceu-se de te dizer que os alienígenas do Lisp gostam de ver os valores de uma forma que seja legível como dados Lisp. Por isso, precisamos de uma nova função que possa ser lida como dados Lisp (mais uma vez, para o 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 via GitHub A ligação abre numa nova janela ou separador
Common Lisp Exercism

Estás pronto para começar Pronto para o serviço?

Inscreve-te no Exercism para aprenderes e dominares Common Lisp com 27 conceitos92 exercícios, e mentoria humana real, tudo grátis.