\chapter{Когда результаты отлично выглядят}
\label{chap:formatting}

\section{Форматированный вывод}
\label{sec:printf}

Обычно, когда вы пишете сценарий, и особенно когда вы хотите, чтобы
ваш сценарий был использован другими после вас, вы хотите, чтобы
результат был достаточно понятным. Ваш результат должен выводить
что-нибудь вроде следующих строк:
\begin{code}
The coefficient on X is Y, with standard error Z
\end{code}
где \texttt{X}, \texttt{Y} и \texttt{Z} --- заполнители для значений,
неизвестных на момент написания скрипта; они будут заполняться как
значения переменных или выражений при запуске скрипта. Скажем так, при
запуске, когда замены в приведенном выше предложении должны
происходить соответственно из переменных с именем \texttt{vname}
(строка), \texttt{b} (скалярное значение) и \texttt{se} (также
скалярное значение).

Во всем спектре языков программирования для этого есть два основных
способа. Один из способов берет свое начало в языке \textsf{C} и носит
имя \texttt{printf}. В этом подходе мы (а) заменяем общие формы
\texttt{X}, \texttt{Y} и \texttt{Z} более информативными
спецификаторами преобразования, и (b) добавляем переменные (или
выражения), которые должны быть вставлены в текст, по порядку. Вот
версия для Hansl:
\begin{code}
printf "The coefficient on %s is %g, with standard error %g\n", vname, b, se
\end{code}
Значение \texttt{vname} заменяет спецификатор преобразования
``\texttt{\%s},'', а значения \texttt{b} и \texttt{se} заменяют два
спецификатора ``\texttt{\%g}'' слева направо. Что касается Hansl, вот
основные моменты, которые вам необходимо знать: ``\texttt{\%s}''
соединяется со строковым аргументом, а ``\texttt{\%g}'' --- с числовым
аргументом.  Производная от \textsf{C} \texttt{printf} (либо в форме
функции, либо в форме команды, как показано выше) присутствует в
большинстве «серьезных» языков программирования. Она чрезвычайно
универсальна, и в своей расширенной форме позволяет программисту точно
контролировать вывод.  Однако в некоторых языках сценариев
\texttt{printf} считается «слишком сложной» для неспециалистов. В этом
случае обычно предлагается какая-то альтернатива. Мы скептически
относимся к этому: «упрощенные» альтернативы для данной функции могут
сбить с толку, и если в какой-то момент вам понадобится точный
контроль над выводом, они либо не поддерживают эту опцию, либо
поддерживают только через какой-то запутанный механизм. Типичная
альтернатива выглядит примерно так (обратите внимание,
\texttt{display} --- это НЕ команда Hansl, здесь она указана для
примера):

\begin{code}
display "The coefficient on ", vname, "is ", b, ", with standard error ", se, "\n"
\end{code}
То есть вы разбиваете строку на части и вставляете имена переменных,
которые нужно вывести. Требование предоставить спецификаторы
преобразования заменено автоматическим форматированием по умолчанию
для переменных в зависимости от их типа. Точно так же командная строка
усыпана запятыми и кавычками. Если данный способ кажется вам более
предпочтительным, вы можете добавить свою почту в список рассылки
gretl и выступать за их активное использование!  В любом случае, если
быть более точным в отношении \cmd{printf}, его синтаксис выглядит
следующим образом:
\begin{flushleft}
  \texttt{printf \emph{format}, \emph{arguments}}
\end{flushleft}
Формат используется для указания точного способа вывода аргументов.

\subsection{Строка формата}
\label{sec:fmtstring}

В общем случае формат \cmd{printf} должен представлять собой
выражение, которое вычисляется программой как строка, но в в
большинстве случаев это просто строковый литерал (буквенно-цифровая
последовательность, окруженная двойными кавычками). Однако некоторые
последовательности символов в данном формате имеют особое
значение. Как показано выше, те, которые начинаются со знака процента
(\texttt{\%}), интерпретируются как «заполнители» для элементов,
содержащихся в списках аргументов. Кроме того, специальные символы,
такие как символ новой строки, представлены через комбинации,
начинающиеся с обратной косой черты (\verb|\|).  Например,
\begin{code}
printf "The square root of %d is (roughly) %6.4f.\n", 5, sqrt(5)
\end{code}
выведет 
\begin{code}
The square root of 5 is (roughly) 2.2361.
(Квадратный корень из 5 будет (примерно) 2.2361.)
\end{code}
Давайте рассмотрим, как это происходит:
\begin{itemize}
\item Первая специальная последовательность \verb|%d| означает, что на
  выходе в этом месте нам нужно получить целое число; поскольку это
  крайнее левое «процентное» выражение, оно сопоставляется с первым
  аргументом, который равен 5.
\item Вторая специальная последовательность \verb|%6.4f| означает
  десятичное значение с 4 цифрами после запятой (десятичного
  разделителя)\footnote{В качестве десятичного разделителя во многих
    странах используют точку, но знак разделителя может обозначаться
    по-другому.} и шириной не менее 6 знаков; она будет сопоставлена
  со вторым аргументом. Обратите внимание, что аргументы отделяются
  запятыми. Также важно отметить, что в следующем примере второй
  аргумент не является ни скалярной константой, ни скалярной
  переменной, а выражением, которое исчисляется как скаляр.
\item Строка формата заканчивается последовательностью \verb|\n|,
  которая выводит новую строку.
\end{itemize}

Спецификаторы преобразования в примере с квадратным корнем довольно
необычны, но, как мы отметили ранее, \texttt{\%g} будет стабильно
работать почти для всех числовых значений в Hansl. Поэтому мы могли бы
использовать более простую форму для записи того же примера:
\begin{code}
printf "The square root of %g is (roughly) %g.\n", 5, sqrt(5)
\end{code}
Важно написать \texttt{\%g}, чтобы вывести число, содержащее до 6
значащих цифр (но с отбрасыванием конечных нулей); если число очень
велико или мало, научная запись числа включается автоматически. Итак,
результат здесь будет следующий:
\begin{code}
The square root of 5 is (roughly) 2.23607.
(Квадратный корень из 5 будет (примерно) 2.23607)
\end{code}
Распознаются такие escape-последовательности как: \verb|\n| (новая
строка), \verb|\t| (табуляция), \verb|\v| (вертикальная табуляция) и
\verb|\\| (обратная косая черта). Чтобы вывести буквальный знак
процента, используйте \verb|%%|.
Помимо последовательностей, показанных в вышеприведенном примере,
распознаются следующие числовые форматы \verb|%e|, \verb|%E|,
\verb|%f|, \verb|%g|, \verb|%G| и
\verb|%x|, в каждом случае с различными модификаторами, доступными в
C. Формат \verb|%s| используется для строковых данных. Как и в C,
числовые значения, составляющие формат или его части (ширина и / или
точность), могут быть заданы непосредственно в виде чисел, как в
\verb|%10.4f|, или могут быть заданы как переменные. В последнем
случае один помещает звездочки в строку формата и выводит
соответствующие аргументы по порядку. Например:
\begin{code}
  scalar width = 12 
  scalar precision = 6 
  printf "x = %*.*f\n", width, precision, x
\end{code}

Если аргумент матрицы задан в сочетании с числовым форматом,
печатается вся матрица используя указанный формат для каждого
элемента. Еще несколько примеров приведены в таблице
\ref{tab:printf-ex}.
\begin{table}[htbp]
  \centering
   {\small
    \begin{tabular}{p{0.45\textwidth}p{0.3\textwidth}}
      \textbf{Kоманда} & \textbf{Эффект} \\
      \hline
      \verb|printf "%12.3f", $pi| & 3.142 \\
      \verb|printf "%12.7f", $pi| & 3.1415927 \\
      \verb|printf "%6s%12.5f%12.5f %d\n", "alpha",| \\
      \verb|   3.5, 9.1, 3| &
      \verb| alpha     3.50000     9.10000 3| \\
      \verb|printf "%6s%12.5f%12.5f\t%d\n", "beta",| \\
      \verb|   1.2345, 1123.432, %11| &
      \verb|  beta     1.23450  1123.43200 11| \\
      \verb|printf "%d, %10d, %04d\n", 1,2,3| & 
      \verb|1,          2, 0003| \\
      \verb|printf "%6.0f (%5.2f%%)\n", 32, 11.232| & \verb|32 (11.23%)| \\
      \hline
    \end{tabular}
  }
  \caption{Примеры форматов вывода}
  \label{tab:printf-ex}
\end{table}

\subsection{Вывод в строку}
\label{sec:sprintf}

Подобного эффекта можно достичь с помощью функции \cmd{sprintf}:
вместо прямой печати результат сохраняется в вспециально названной
строковой переменной, как в

\begin{code}
  string G = sprintf("x = %*.*f\n", width, precision, x)
\end{code}
после чего переменная \texttt{G} может стать объектом дальнейшей обработки.

\subsection{Вывод в файл}
\label{sec:outfile}

Hansl не имеет файла или «stream» файла, как такового, но команда
\cmd{outfile} может использоваться для перенаправления вывода в
специально обозначенный текстовый файл. Чтобы начать такое
перенаправление, вы должны указать имя файла; новый файл создается по
умолчанию, а также можно перезаписать существующий файл, но
\option{append} можно использовать для добавления материала в
существующий файл. Таким образом, в каждый момент времени можно
открыть только один файл. Перенаправление вывода продолжается до тех
пор, пока не будет дана команда \cmd{end outfile}, затем вывод
возвращается к установкам по умолчанию. Так выглядит пример подобного
использования:

\begin{code}
  printf "One!\n"
  outfile "myfile.txt"
    printf "Two!\n"
  end outfile
  printf "Three!\n"
  outfile "myfile.txt" --append
    printf "Four!\n"
  end outfile
  printf "Five!\n"
\end{code}
После применения данного скрипта файл \texttt{myfile.txt} будет
содержать строки
\begin{code}
Two!
Four!  
\end{code}
Доступны три варианта для работы с вышеперечисленным. Если вы укажете
ключевое слово \texttt{null} вместо реального имени файла вместе с
параметром записи, результатом будет подавление всего вывода до
завершения перенаправления. Если вместо обычного имени файла указано
одно из ключевых слов \texttt{stdout} или \texttt{stderr}, результатом
будет соответственное перенаправление вывода на стандартный вывод или
стандартный вывод ошибок. Эта команда также поддерживает опцию
\option{quiet}: ее действие заключается в отключении дублирования
команд и вывода вспомогательных сообщений во время перенаправления
вывода. Это эквивалентно выполнению команд

\begin{code}
  set echo off 
  set messages off
\end{code}
перед вызовом \cmd{outfile}, за исключением того, что по окончании
перенаправления предыдущие значения команд и другие сообщения
восстанавливаются.

\section{Графика}

Основная команда построения графиков в Hansl --- это \texttt{gnuplot},
которая, как следует из названия, фактически предоставляет интерфейс к
программе \texttt{gnuplot}. Она используется для построения рядов в
наборе данных (см. Часть ~\ref{part:hp-data}) или столбцов в
матрице. Для получения информации по данной команде (и некоторым
другим, более специализированным, таких как \texttt{boxplot} и
\texttt{qqplot}), см. Справочник по командам \GCR.

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "hansl-primer"
%%% End: 
