%$Id: process.tex,v 3.2 2013/10/11 15:39:35 boris Exp $
%$Log: process.tex,v $
%Revision 3.2 2013/10/11 15:39:35 boris
%Lev's changes
%
%Revision 3.1 2008-03-23 18:04:51 boris
%documentation update
%
%Revision 3.0 2008-03-23 17:50:50 boris
%Added Lev's corrections
%
%Revision 2.7 2005/02/20 03:24:43 boris
%Wrote readme
%
%Revision 2.6 2005/01/24 03:28:53 boris
%Re-added
%
%Revision 2.4 2002/02/04 16:53:15 boris
%Added numletters
%
%Revision 2.3 2002/02/04 16:52:37 boris
%Added num
%
%Revision 2.2 2002/02/04 15:43:34 boris
%Added new features
%
%Revision 2.1 2002/02/04 15:04:53 boris
%Started anew
%
%
%Revision 1.9 1998/11/29 21:56:12 boris
%Добавил благодарности
%
%Revision 1.8 1998/11/29 21:50:48 boris
%Добавил изменения в формате.
%
%Revision 1.7 1998/11/17 22:48:33 boris
%Отказался от попытки включить программу в файл -- не совместимы с кои-8
%:(
%
% Revision 1.6 1998/11/17 17:02:51 boris
% Добавил регистрационные номера в формат.
%
% Revision 1.5 1998/11/15 04:52:25 boris
% Написал интерфейс.
%
%Revision 1.4 1998/11/15 03:38:25 boris
%Написал раздел "Форматы"
%
%Revision 1.3 1998/11/15 02:35:43 boris
%Исправил заголовки
%
\documentclass{article}
%
% Руссификация. Бывает и новее...
%
\usepackage[koi8-r]{inputenc}
\usepackage[russian]{babel}
\usepackage{t1enc}
\usepackage{amsmath}
\newcommand{\prog}[1]{\ensuremath{\text{{\textsl{#1}}}}}
\begin{document}
\title{Программа для обработки писем в ИГП и ИЧБ}
\author{Boris Veytsman, \texttt{borisv@lk.net}}
\date{Март 2008}
\maketitle
\thispagestyle{empty}
\tableofcontents
\section{Введение}
С тех пор, как количество команд в IGP превысило первый десяток,
подведение итогов тура стало тяжким бременем для дежурной
команды. Прочесть невероятное количество писем, извлечь ответы,
составить таблицу, да еще Собрание Сочинений\dots{} На это вполне может
уйти целиком рабочий день. Именно с этой целью по предложению Якова
Зайдельмана написана эта программа. Позднее эта программа
переписывалась при изменении регламента соревнований, добавлении ИЧБ и
т.д.
Идея состоит в следующем. Самый важный этап в деятельности дежурной
команды---решить, заслуживает ли данный ответ плюса или минуса. Это мы
автоматизировать не можем. Но это автоматизировать и не надо. А вот
все остальное автоматизировать можно и нужно. Значит, программа должна
делать следующее:
\begin{enumerate}
\item Извлекать ответы из файла с письмами команд
\item Записывать их в файл, где все ответы были бы рядом, и было бы
оставлено место для оценки
\item Читать этот файл \emph{после} того, как дежурная команда
проставит оценки и составлять таблицу и собрание сочинений.
\item Время от времени создавать список команд, чьи ответы уже
получены, и слать на информационный лист.
\end{enumerate}
Необходимо учесть еще несколько важных обстоятельств:
\begin{enumerate}
\item Команда может прислать несколько писем. В этом случае более
позднее письмо считается более авторитетным, чем более раннее. Мы
будем предполагать для простоты, что более поздние письма находятся
в файле с письмами позже более ранних. Дело дежурной
команды---обеспечить такой порядок писем (может быть, вручную
корректируя взбрыки e-mailа).
\item Дежурная команда может оценивать ответы параллельно их
получению. Поэтому нельзя ``забывать'' старые оценки, читая новые.
\item В последнее время в ИГП и ИЧБ принято два зачёта: спринт и
стайер. При этом соблюдаются следующеи правила:
\begin{enumerate}
\item Если команда сдала ответ в спринте и не сдала ответ в стайере,
учитывается ответ, сданный в спринте.
\item При равенстве количества ответов в стайере победу в стайере
одерживает команда, показавшая лучший результат в спринте.
\end{enumerate}
\end{enumerate}
\section{Форматы}
\subsection{Письма с ответами}
\begin{enumerate}
\item Каждое письмо содержит в строке Subject: строку в латиннице:
\begin{verbatim}
Subject: Otvety komandy "Nazvanie_komandy", NNN
\end{verbatim}
При этом название команды не должно содержать кавычек, а
\prog{NNN}---регистрационный номер команды. Если у команды еще нет
регистрационного номера, допускается его НЕ указывать
\item В теле письма может быть все, что угодно, вплоть до строки
\begin{verbatim}
*** "Название_команды", NNN
\end{verbatim}
При этом название команды может быть как в латиннице, так и в
кириллице, но быть \emph{одинаковым} для всех писем от данной команды
\item Каждый ответ имеет следующую структуру:
\begin{verbatim}
#NN. Текст ответа
Текст ответа
...
\end{verbatim}
Здесь \prog{NN}---номер вопроса, а за ним следует текст ответа
(возможно, из нескольких строк)
\item Ответы заканчиваются строкой
\begin{verbatim}
***
\end{verbatim}
После этой строки может следовать все, что угодно.
\item В тексте письма не рекомендуется употребление символов
``\prog{\#}'' и ``\prog{*}'' и \emph{запрещается} их
употребление первыми в строке (или после пробелов).
\end{enumerate}
\paragraph{Пример:}
\begin{verbatim}
Date: 12 Nov 98 18:31:53 MSK
From: Aleksandr Ivanov <ivanov@boga.net>
To: catamaran@hal.plmsc.psu.edu
Subject: Otvety komandy "Stop", 222
Здравствуйте, уважаемые игроки Катамарана!
Большое спасибо за вопросы.
*** "Стоп", 222
#1. Сид
#2. Мышка-наружка
#3. Ллойд-Джордж
#4. В жирафа
#5. Шалтай-Болтай, Барклай де Толлли
#6. У Геркулесовых столпов.
#7. В коров
#8. Глокая куздра
#9. Александр Македонский и Гордий I
#10. Поставить точку над i.
#11. Кольцо Нибелунгов, Вагнер, Мефистофель
#12. Венера
***
Капитан команды "Стоп"
Александр Иванов
\end{verbatim}
\subsection{Формат файла с результатами}
Файл с результатами состоит из ответов. Каждый ответ имеет следующую
структуру:
\begin{enumerate}
\item Заголовок
\begin{verbatim}
#NN. Frequency: f. Score: s
\end{verbatim}
Здесь \prog{NN}---номер вопроса, а \prog{s}---оценка, один из
трех символов: \prog{+}, \prog{-} или \prog{?}.
\item Собственно текст ответа:
\begin{verbatim}
Текст ответа
Текст ответа
...
\end{verbatim}
При этом каждая строка текста начинается с двух пробелов.
\item В конце всех ответов идет строка из трех звездочек:
\begin{verbatim}
***
\end{verbatim}
\end{enumerate}
\subsection{Формат таблицы результатов}
У таблицы результатов есть три формата.
\begin{enumerate}
\item Длинный формат
\begin{verbatim}
N 1 2 3 4 5 6 7 8 9 10 11 12 О Р КОМАНДА
111 + + + + + + + + + + + + 12.04 359 Марсиане
436 + + + + + + + + + + + + 12.02 359 Venera II
[...]
\end{verbatim}
\item Промежуточный формат
\begin{verbatim}
N 12345 67890 12 О Р КОМАНДА
111 +++++ +++++ ++ 12.04 359 Марсиане
436 +++++ +++++ ++ 12.04 359 Venera II
[...]
Рейтинг
1 2 3 4 5 6 7 8 9 10 11 12
24 21 34 24 41 43 18 31 26 32 36 29
\end{verbatim}
\item Короткий формат
\begin{verbatim}
N 123456789012 О Р КОМАНДА
111 ++++++++++++ 12.04 359 Марсиане
436 ++++++++++++ 12.04 359 Venera II
[...]
Рейтинг
1 2 3 4 5 6 7 8 9 10 11 12
24 21 34 24 41 43 18 31 26 32 36 29
\end{verbatim}
\end{enumerate}
В последних графах стоит полное число взятых вопросов и суммарный
рейтинг соответственно. В последней строке таблицы---рейтинги
вопросов. В коротком формате вместо строки с рейтингом отдельная
таблица ``Рейтинг''. В графе ``О'' стоят набранные командой очки в
данном зачёте (до десятичной точки) и в предыдущем (после точки).
При печати незачетных вопросов взятый вопрос помечается буквой
\prog{X}, а невзятый, как обычно, \prog{-}.
\subsection{Формат собрания сочинений}
Собрание ответов на каждый вопрос имеет следующую структуру:
\begin{enumerate}
\item Заголовок раздела
\begin{verbatim}
ВОПРОС NN:
\end{verbatim}
\item По три заголовка подразделов:
\begin{verbatim}
ЗАСЧИТАНО:
\end{verbatim}
\begin{verbatim}
НЕ ЗАСЧИТАНО:
\end{verbatim}
и
\begin{verbatim}
НЕ ЯСНО:
\end{verbatim}
\item Каждый ответ имеет формат:
\begin{verbatim}
s Текст ответа
Текст ответа
... [f]
\end{verbatim}
Здесь \prog{s}---один из символов \prog{+}, \prog{-}, или \prog{?},
\prog{f}---частота ответа, которая печатается только если она не равна
единице.
\end{enumerate}
По умолчанию, заголовки всех подразделов выводятся даже если для данного
вопроса нет ответов, попадающих в какой-либо подраздел (подраздел пуст).
Это предсказуемо и удобно, но не всегда удобочитаемо с точки зрения
читателя-человека, поэтому по желанию возможна генерация промежуточного
или короткого вариантов собрания сочинений. От описанного выше полного
формата они отличаются режимом печати пустых подразделов:
\begin{enumerate}
\item В промежуточном формате подразделы \prog{ЗАСЧИТАНО} и
\prog{НЕ ЗАСЧИТАНО} показываются всегда (даже пустые), а подраздел
\prog{НЕ ЯСНО}---только если он не пуст.
\item В коротком формате все подразделы выводятся только если они
не пусты (исключения для \prog{ЗАСЧИТАНО} и \prog{НЕ ЗАСЧИТАНО}
не делаются).
\end{enumerate}
По мнению автора, промежуточный формат представляет собой оптимальный
компромисс между читаемостью и полнотой (и действительно, зачем
печатать пару десятков пустых \prog{НЕ ЯСНО} в официальной сводке,
в которой уже давно все ясно?)
\section{Пользовательский интерфейс}
\subsection{Файл настроек}
\label{sec:conf}
Настройки программы хранятся в файле \prog{parameters.pl}. Пример
этого файла приведен ниже:
\begin{verbatim}
# В этом файле собраны ЛОКАЛЬНЫЕ параметры -- "настройки"
#
# Количество зачётов
$ROUNDS=2;
###############################################################
# Следующие настройки индивидуальны для каждого раунда, начиная
# с первого
###############################################################
# Первый раунд
# Название раунда
$NAME[1]="Спринт";
# Вопросы раунда
$MINQUEST[1]=1;
$MAXQUEST[1]=12;
# Файлы раунда. Следующий перекрывает предыдущий.
# Список заключён в квадратные скобки, отдельные файлы разделены ЗАПЯТЫМИ.
# $FILES[1] = [ "sprint.mail", "sprint-extra.mail" ];
#
# ВНИМАНИЕ: формат этого параметра изменился с предыдущей версии!
$FILES[1]= [ 'sprint.mail' ];
# Внезачётные вопросы раунда. В квадратных скобках, номера разделены ЗАПЯТЫМИ.
# Во втором раунде эти вопросы тоже будут вне зачёта (но можно будет и
# учесть, см. ниже описание $NOCOUNT[2]).
# $NOCOUNT[1] = [];
# $NOCOUNT[1] = [ 2, 3, 4 ];
$NOCOUNT[1]= [];
# Второй раунд
# Название раунда
$NAME[2]="Стайер";
# Вопросы раунда
$MINQUEST[2]=1;
$MAXQUEST[2]=18;
# Список заключён в квадратные скобки, отдельные файлы разделены ЗАПЯТЫМИ.
# $FILES[2] = [ 'predvarit.mail', 'osnovn.mail' ];
#
# ВНИМАНИЕ: формат этого параметра изменился с предыдущей версии!
$FILES[2]= [ 'stayer.mail' ];
# Внезачётные вопросы в этом раунде. В квадратных скобках, через ЗАПЯТУЮ.
# Этот список ДОБАВЛЯЕТСЯ к уже перечисленным в $NOCOUNT[1]. Однако
# если вы хотите исключить какой-то из ранее указанных вопросов (например,
# в гипотетической ситуации "вопрос номер 5 был исправлен слишком поздно,
# поэтому в Спринте не учитывается, а для Стайера используется"), то
# укажите его номер со знаком минус: "3 -5 6"
# $NOCOUNT[2] = [];
# $NOCOUNT[2] = [ 3, -5, 6 ];
$NOCOUNT[2]= [];
#########################################################
# Теперь общие настройки
#########################################################
#
# Адрес листа z-info
#
$address = 'z-info@chgk.info';
#$address="boris";
#
# Обратный адрес дежурной команды и ее название
#
$fromaddress = 'Boris Veytsman <borisv@lk.net>';
$DK = '"Дракоша"';
#
# $date -- системная процедура, которая вычисляет МОСКОВСКОЕ
# время. В Линуксе zdump это делает хорошо. В других операционных
# системах надо как-то исхитряться... На самый худой конец, используйте
# $date='';
#
$date = "export TZ='Europe/Moscow'; date";
#
# Процедуры, которые печатают заголовок и конец мейла-напоминания
#
sub printheader
{
print <<"END";
To: $address
From: $fromaddress
Subject: Svodka
MIME-Version: 1.0
Content-type: text/plain; charset=koi8-r
Content-Transfer-Encoding: 8bit\n
Уважаемые знатоки!
С вами говорит робот команды $DK
END
print "На момент ", `$date`, "в зачёте '$NAME[$round]' сданы ответы от команд:\n\n";
}
sub printfooter
{
print <<END;
--
Good luck
-Robot
END
}
\end{verbatim}
\subsection{Основная программа}
Дежурный по туру складывает все письма в файл. Время от времени он
запускает команду
\begin{verbatim}
processmail.pl [-d] [-t table_file] [-o results]
\end{verbatim}
где
\begin{description}
\item[table\_file] файл с предыдущими оценками (по умолчанию
отсутствует),
\item[results] файл с результатами (по умолчанию---стандартный
выход).
\end{description}
В этом файле вручную расставляются плюсы и минусы.
Флаг \prog{-d} означает ``Debigging mode''. В этом режиме программа
печатает массу дополнительной информации.
\subsection{Сводка}
Время от времени дежурный запускает программу
\begin{verbatim}
reminder.pl [-r номер_раунда]
\end{verbatim}
Она генерирует список команд, которые имеются в файле с таблицей (по
умолчанию---стандартный вход), и посылает его на z-info.
\subsection{Результаты}
Итоговая таблица и собрание сочинений генерируются программами
\begin{verbatim}
createtable.pl [-d] [-s|-m] [-t table_file] [-o results]
collection.pl [-d] [-s|-m] [-t table_file] [-o results]
\end{verbatim}
Ключи имеют тот же смысл, что и у программы \prog{processmail.pl}.
Флаг \prog{-s} означает выбор короткой формы вывода, а флаг \prog{-m}
означает выбор промежуточной формы.
\section{Программа}
\subsection{Внутреннее представление данных}
Сведения о командах хранятся в хэше \prog{\%teams} со следующими
полями:
\begin{description}
\item[ключ] название команды
\item[элемент] ссылка на анонимный хэш \prog{\%teams\{\$team\}} с
полями:
\begin{description}
\item[\prog{regnum}] регистрационный номер
\item[\prog{numletters}] количество писем с ответами
\item[\prog{answers}] ссылка на массив из ответов
\item[\prog{score}] общий итог
\item[\prog{rating}] общий рейтинг
\end{description}
\end{description}
Сведения о вопросах хранятся в массиве \prog{\%answers}. Его
элементы---ссылки на анонимные хэши. Ключи в хэшах---тексты ответов,
а элементы---опять таки ссылки на хэши следующего содержания:
\begin{description}
\item[\prog{score}] \prog{+}, \prog{-} или \prog{?}
\item[\prog{teams}] хэш команд, давших этот ответ
\end{description}
\section{Благодарности}
Я благодарен Якову Зайдельману, Льву Горенштейну, Алексу Покрасу и
Дмитрию Рубинштейну за помощь в разработке этой программы. Версия~3
программы (поддержка незачетных вопросов и промежуточного формата
таблицы) была написана Львом Горенштейном.
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>