File:  [Local Repository] / processmail / process.tex
Revision 3.2: download - view: text, annotated - select for diffs - revision graph
Fri Oct 11 15:39:35 2013 UTC (10 years, 7 months ago) by boris
Branches: MAIN
CVS tags: HEAD
Lev's changes

%$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>