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