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, 8 months ago) by boris
Branches: MAIN
CVS tags: HEAD
Lev's changes

    1: %$Id: process.tex,v 3.2 2013/10/11 15:39:35 boris Exp $
    2: %$Log: process.tex,v $
    3: %Revision 3.2  2013/10/11 15:39:35  boris
    4: %Lev's changes
    5: %
    6: %Revision 3.1  2008-03-23 18:04:51  boris
    7: %documentation update
    8: %
    9: %Revision 3.0  2008-03-23 17:50:50  boris
   10: %Added Lev's corrections
   11: %
   12: %Revision 2.7  2005/02/20 03:24:43  boris
   13: %Wrote readme
   14: %
   15: %Revision 2.6  2005/01/24 03:28:53  boris
   16: %Re-added
   17: %
   18: %Revision 2.4  2002/02/04 16:53:15  boris
   19: %Added numletters
   20: %
   21: %Revision 2.3  2002/02/04 16:52:37  boris
   22: %Added num
   23: %
   24: %Revision 2.2  2002/02/04 15:43:34  boris
   25: %Added new features
   26: %
   27: %Revision 2.1  2002/02/04 15:04:53  boris
   28: %Started anew
   29: %
   30: %
   31: %Revision 1.9  1998/11/29 21:56:12  boris
   32: %Добавил благодарности
   33: %
   34: %Revision 1.8  1998/11/29 21:50:48  boris
   35: %Добавил изменения в формате.
   36: %
   37: %Revision 1.7  1998/11/17 22:48:33  boris
   38: %Отказался от попытки включить программу в файл -- не совместимы с кои-8
   39: %:(
   40: %
   41: % Revision 1.6  1998/11/17  17:02:51  boris
   42: % Добавил регистрационные номера в формат.
   43: %
   44: % Revision 1.5  1998/11/15  04:52:25  boris
   45: % Написал интерфейс.
   46: %
   47: %Revision 1.4  1998/11/15 03:38:25  boris
   48: %Написал раздел "Форматы"
   49: %
   50: %Revision 1.3  1998/11/15 02:35:43  boris
   51: %Исправил заголовки
   52: %
   53: \documentclass{article}
   54: %
   55: % Руссификация. Бывает и новее...
   56: %
   57: \usepackage[koi8-r]{inputenc}
   58: \usepackage[russian]{babel}
   59: \usepackage{t1enc}
   60: \usepackage{amsmath}
   61: \newcommand{\prog}[1]{\ensuremath{\text{{\textsl{#1}}}}}
   62: 
   63: 
   64: 
   65: \begin{document}
   66: 
   67: \title{Программа для обработки писем в ИГП и ИЧБ}
   68: \author{Boris Veytsman, \texttt{borisv@lk.net}}
   69: \date{Март 2008}
   70: \maketitle
   71: \thispagestyle{empty}
   72: \tableofcontents
   73: 
   74: \section{Введение}
   75: 
   76: С тех пор, как количество команд в IGP превысило первый десяток,
   77: подведение итогов тура стало тяжким бременем для дежурной
   78: команды. Прочесть невероятное количество писем, извлечь ответы,
   79: составить таблицу, да еще Собрание Сочинений\dots{} На это вполне может
   80: уйти целиком рабочий день. Именно с этой целью по предложению Якова
   81: Зайдельмана написана эта программа.  Позднее эта программа
   82: переписывалась при изменении регламента соревнований, добавлении ИЧБ и
   83: т.д. 
   84: 
   85: Идея состоит в следующем. Самый важный этап в деятельности дежурной
   86: команды---решить, заслуживает ли данный ответ плюса или минуса. Это мы
   87: автоматизировать не можем. Но это автоматизировать и не надо. А вот
   88: все остальное автоматизировать можно и нужно. Значит, программа должна
   89: делать следующее:
   90: \begin{enumerate}
   91: \item Извлекать ответы из файла с письмами команд
   92: \item Записывать их в файл, где все ответы были бы рядом, и было бы
   93:   оставлено место для оценки
   94: \item Читать этот файл \emph{после} того, как дежурная команда
   95:   проставит оценки и составлять таблицу и собрание сочинений. 
   96: \item Время от времени создавать список команд, чьи ответы уже
   97:   получены, и слать на информационный лист.
   98: \end{enumerate}
   99: Необходимо учесть еще несколько важных обстоятельств:
  100: \begin{enumerate}
  101: \item Команда может прислать несколько писем. В этом случае более
  102:   позднее письмо считается более авторитетным, чем более раннее. Мы
  103:   будем предполагать для простоты, что более поздние письма находятся
  104:   в файле с письмами позже более ранних. Дело дежурной
  105:   команды---обеспечить такой порядок писем (может быть, вручную
  106:   корректируя взбрыки e-mailа).
  107: \item Дежурная команда может оценивать ответы параллельно их
  108:   получению. Поэтому нельзя ``забывать'' старые оценки, читая новые. 
  109: \item В последнее время в ИГП и ИЧБ принято два зачёта:  спринт и
  110:   стайер.  При этом соблюдаются следующеи правила:
  111:   \begin{enumerate}
  112:   \item Если команда сдала ответ в спринте и не сдала ответ в стайере,
  113:     учитывается ответ, сданный в спринте.
  114:   \item При равенстве количества ответов в стайере победу в стайере
  115:     одерживает команда, показавшая лучший результат в спринте.
  116:   \end{enumerate}
  117: \end{enumerate}
  118: 
  119: 
  120: \section{Форматы}
  121: 
  122: 
  123: \subsection{Письма с ответами}
  124: 
  125: \begin{enumerate}
  126: \item Каждое письмо содержит в строке Subject: строку в латиннице:
  127: \begin{verbatim}
  128: Subject: Otvety komandy "Nazvanie_komandy", NNN
  129: \end{verbatim}
  130: При этом название команды не должно содержать кавычек, а
  131: \prog{NNN}---регистрационный номер команды. Если у команды еще нет
  132: регистрационного номера, допускается его НЕ указывать
  133: \item В теле письма может быть все, что угодно, вплоть до строки
  134: \begin{verbatim}
  135: *** "Название_команды", NNN
  136: \end{verbatim}
  137: При этом название команды может быть как в латиннице, так и в
  138: кириллице, но быть \emph{одинаковым} для всех писем от данной команды 
  139: \item Каждый ответ имеет следующую структуру:
  140: \begin{verbatim}
  141: #NN. Текст ответа
  142: Текст ответа
  143: ...
  144: \end{verbatim}
  145:   Здесь \prog{NN}---номер вопроса, а за ним следует текст ответа
  146:   (возможно, из нескольких строк)
  147: \item Ответы заканчиваются строкой
  148: \begin{verbatim}
  149: ***
  150: \end{verbatim}
  151: После этой строки может следовать все, что угодно.
  152: \item В тексте письма не рекомендуется употребление символов
  153:   ``\prog{\#}'' и ``\prog{*}'' и \emph{запрещается} их
  154:   употребление первыми в строке (или после пробелов).
  155: \end{enumerate}
  156: 
  157: \paragraph{Пример:}
  158: \begin{verbatim}
  159: Date: 12 Nov 98 18:31:53 MSK
  160: From: Aleksandr Ivanov <ivanov@boga.net>
  161: To: catamaran@hal.plmsc.psu.edu
  162: Subject: Otvety komandy "Stop", 222
  163: 
  164: Здравствуйте, уважаемые игроки Катамарана!
  165: 
  166: Большое спасибо за вопросы.
  167: 
  168: *** "Стоп", 222
  169: #1. Сид
  170: #2. Мышка-наружка
  171: #3. Ллойд-Джордж
  172: #4. В жирафа
  173: #5. Шалтай-Болтай, Барклай де Толлли
  174: #6. У Геркулесовых столпов.
  175: #7. В коров
  176: #8. Глокая куздра
  177: #9. Александр Македонский и Гордий I
  178: #10. Поставить точку над i.
  179: #11. Кольцо Нибелунгов, Вагнер, Мефистофель
  180: #12. Венера
  181: ***
  182: 
  183: Капитан команды "Стоп" 
  184: Александр Иванов
  185: \end{verbatim}
  186: 
  187: 
  188: \subsection{Формат файла с результатами}
  189: 
  190: Файл с результатами состоит из ответов. Каждый ответ имеет следующую
  191: структуру: 
  192: \begin{enumerate}
  193: \item Заголовок
  194: \begin{verbatim}
  195: #NN. Frequency: f. Score: s
  196: \end{verbatim}
  197:   Здесь \prog{NN}---номер вопроса, а \prog{s}---оценка, один из
  198:   трех символов: \prog{+}, \prog{-} или \prog{?}.
  199: \item Собственно текст ответа:
  200: \begin{verbatim}
  201:   Текст ответа
  202:   Текст ответа
  203:   ...
  204: \end{verbatim}
  205:   При этом каждая строка текста начинается с двух пробелов. 
  206: \item В конце всех ответов идет строка из трех звездочек:
  207: \begin{verbatim}
  208: ***
  209: \end{verbatim}
  210: \end{enumerate}
  211: 
  212: 
  213: \subsection{Формат таблицы результатов}
  214: 
  215: У таблицы результатов есть три формата. 
  216: \begin{enumerate}
  217: \item Длинный формат
  218: \begin{verbatim}
  219:     N  1  2  3  4  5  6  7  8  9 10 11 12 О     Р КОМАНДА
  220:   111  +  +  +  +  +  +  +  +  +  +  +  + 12.04 359 Марсиане
  221:   436  +  +  +  +  +  +  +  +  +  +  +  + 12.02 359 Venera II
  222: [...]
  223: \end{verbatim}
  224: 
  225: \item Промежуточный формат
  226: \begin{verbatim}
  227:     N  12345 67890 12  О     Р   КОМАНДА
  228:   111  +++++ +++++ ++  12.04 359 Марсиане
  229:   436  +++++ +++++ ++  12.04 359 Venera II
  230: [...]
  231: Рейтинг
  232:  1  2  3  4  5  6  7  8  9 10 11 12
  233: 24 21 34 24 41 43 18 31 26 32 36 29
  234: \end{verbatim}
  235: 
  236: 
  237: \item Короткий формат
  238: \begin{verbatim}
  239:     N  123456789012  О     Р   КОМАНДА
  240:   111  ++++++++++++  12.04 359 Марсиане
  241:   436  ++++++++++++  12.04 359 Venera II
  242: [...]
  243: Рейтинг
  244:  1  2  3  4  5  6  7  8  9 10 11 12
  245: 24 21 34 24 41 43 18 31 26 32 36 29
  246: \end{verbatim}
  247: \end{enumerate}
  248: В последних графах стоит полное число взятых вопросов и суммарный
  249: рейтинг соответственно. В последней строке таблицы---рейтинги
  250: вопросов. В коротком формате вместо строки с рейтингом отдельная
  251: таблица ``Рейтинг''.  В графе ``О'' стоят набранные командой очки в
  252: данном зачёте (до десятичной точки) и в предыдущем (после точки).
  253: 
  254: При печати незачетных вопросов взятый вопрос помечается буквой
  255: \prog{X}, а невзятый, как обычно, \prog{-}.
  256: 
  257: \subsection{Формат собрания сочинений}
  258: 
  259: Собрание ответов на каждый вопрос имеет следующую структуру:
  260: \begin{enumerate}
  261: \item Заголовок раздела
  262: \begin{verbatim}
  263: ВОПРОС NN:
  264: \end{verbatim}
  265: \item По три заголовка подразделов:
  266: \begin{verbatim}
  267: ЗАСЧИТАНО:
  268: \end{verbatim}
  269: 
  270: \begin{verbatim}
  271: НЕ ЗАСЧИТАНО:
  272: \end{verbatim}
  273: и
  274: \begin{verbatim}
  275: НЕ ЯСНО:
  276: \end{verbatim}
  277: \item Каждый ответ имеет формат:
  278: \begin{verbatim}
  279: s Текст ответа
  280:   Текст ответа
  281:   ...           [f]
  282: \end{verbatim}
  283: Здесь \prog{s}---один из символов \prog{+}, \prog{-}, или \prog{?},
  284: \prog{f}---частота ответа, которая печатается только если она не равна
  285: единице. 
  286: \end{enumerate}
  287: 
  288: По умолчанию, заголовки всех подразделов выводятся даже если для данного 
  289: вопроса нет ответов, попадающих в какой-либо подраздел (подраздел пуст).
  290: Это предсказуемо и удобно, но не всегда удобочитаемо с точки зрения 
  291: читателя-человека, поэтому по желанию возможна генерация промежуточного 
  292: или короткого вариантов собрания сочинений.  От описанного выше полного 
  293: формата они отличаются режимом печати пустых подразделов:
  294: \begin{enumerate}
  295: \item В промежуточном формате подразделы \prog{ЗАСЧИТАНО} и 
  296:  \prog{НЕ ЗАСЧИТАНО} показываются всегда (даже пустые), а подраздел
  297:  \prog{НЕ ЯСНО}---только если он не пуст.
  298: \item В коротком формате все подразделы выводятся только если они
  299:   не пусты (исключения для \prog{ЗАСЧИТАНО} и \prog{НЕ ЗАСЧИТАНО}
  300:  не делаются).
  301: \end{enumerate}
  302: 
  303: По мнению автора, промежуточный формат представляет собой оптимальный
  304: компромисс между читаемостью и полнотой (и действительно, зачем 
  305: печатать пару десятков пустых \prog{НЕ ЯСНО} в официальной сводке,
  306: в которой уже давно все ясно?)
  307: 
  308: 
  309: 
  310: 
  311: \section{Пользовательский интерфейс}
  312: 
  313: 
  314: \subsection{Файл настроек}
  315: \label{sec:conf}
  316: 
  317: Настройки программы хранятся в файле \prog{parameters.pl}.  Пример
  318: этого файла приведен ниже:
  319: \begin{verbatim}
  320: # В этом файле собраны ЛОКАЛЬНЫЕ параметры -- "настройки"
  321: #
  322: # Количество зачётов
  323: $ROUNDS=2;
  324: 
  325: ###############################################################
  326: # Следующие настройки индивидуальны для каждого раунда, начиная
  327: # с первого
  328: ###############################################################
  329: 
  330: # Первый раунд
  331: 
  332: # Название раунда
  333: 
  334: $NAME[1]="Спринт";
  335: 
  336: # Вопросы раунда
  337: 
  338: $MINQUEST[1]=1;
  339: $MAXQUEST[1]=12;
  340: 
  341: # Файлы раунда.  Следующий перекрывает предыдущий.
  342: # Список заключён в квадратные скобки, отдельные файлы разделены ЗАПЯТЫМИ.
  343: # 	$FILES[1] = [ "sprint.mail", "sprint-extra.mail" ];
  344: #
  345: # ВНИМАНИЕ: формат этого параметра изменился с предыдущей версии!
  346: 
  347: $FILES[1]= [ 'sprint.mail' ];
  348: 
  349: # Внезачётные вопросы раунда. В квадратных скобках, номера разделены ЗАПЯТЫМИ.
  350: # Во втором раунде эти вопросы тоже будут вне зачёта (но можно будет и
  351: # учесть, см. ниже описание $NOCOUNT[2]).
  352: # 	$NOCOUNT[1] = [];
  353: # 	$NOCOUNT[1] = [ 2, 3, 4 ];
  354: 
  355: $NOCOUNT[1]= [];
  356: 
  357: 
  358: # Второй раунд
  359: 
  360: # Название раунда
  361: 
  362: $NAME[2]="Стайер";
  363: 
  364: # Вопросы раунда
  365: 
  366: $MINQUEST[2]=1;
  367: $MAXQUEST[2]=18;
  368: 
  369: # Список заключён в квадратные скобки, отдельные файлы разделены ЗАПЯТЫМИ.
  370: # 	$FILES[2] = [ 'predvarit.mail', 'osnovn.mail' ];
  371: #
  372: # ВНИМАНИЕ: формат этого параметра изменился с предыдущей версии!
  373: 
  374: $FILES[2]= [ 'stayer.mail' ];
  375: 
  376: # Внезачётные вопросы в этом раунде.  В квадратных скобках, через ЗАПЯТУЮ.
  377: # Этот список ДОБАВЛЯЕТСЯ к уже перечисленным в $NOCOUNT[1].  Однако
  378: # если вы хотите исключить какой-то из ранее указанных вопросов (например,
  379: # в гипотетической ситуации "вопрос номер 5 был исправлен слишком поздно,
  380: # поэтому в Спринте не учитывается, а для Стайера используется"), то
  381: # укажите его номер со знаком минус: "3 -5 6"
  382: # 	$NOCOUNT[2] = [];
  383: # 	$NOCOUNT[2] = [ 3, -5, 6 ];
  384: 
  385: $NOCOUNT[2]= [];
  386: 
  387: 
  388: #########################################################
  389: #   Теперь общие настройки
  390: #########################################################
  391: 
  392: 
  393: #
  394: # Адрес листа z-info
  395: #
  396: $address = 'z-info@chgk.info';
  397: #$address="boris";
  398: #
  399: # Обратный адрес дежурной команды и ее название
  400: #
  401: $fromaddress = 'Boris Veytsman <borisv@lk.net>';
  402: $DK = '"Дракоша"';
  403: #
  404: # $date -- системная процедура, которая вычисляет МОСКОВСКОЕ
  405: # время. В Линуксе zdump это делает хорошо. В других операционных 
  406: # системах надо как-то исхитряться...  На самый худой конец, используйте
  407: # 	$date='';
  408: #
  409: $date = "export TZ='Europe/Moscow'; date";
  410: 
  411: #
  412: # Процедуры, которые печатают заголовок и конец мейла-напоминания
  413: #
  414: sub printheader
  415: {
  416: print  <<"END";
  417: To: $address
  418: From: $fromaddress
  419: Subject: Svodka
  420: MIME-Version: 1.0
  421: Content-type: text/plain; charset=koi8-r
  422: Content-Transfer-Encoding: 8bit\n
  423: 
  424: Уважаемые знатоки!
  425: 
  426: С вами говорит робот команды $DK
  427: 
  428: END
  429: print "На момент ", `$date`, "в зачёте '$NAME[$round]' сданы ответы от команд:\n\n"; 
  430: }
  431: 
  432: 
  433: sub printfooter
  434: {
  435:     print  <<END;
  436: 
  437: --
  438: Good luck
  439: 
  440: -Robot
  441: END
  442: 
  443: }
  444: \end{verbatim}
  445: 
  446: 
  447: \subsection{Основная программа}
  448: 
  449: Дежурный по туру складывает все письма в файл. Время от времени он
  450: запускает команду
  451: \begin{verbatim}
  452: processmail.pl [-d] [-t table_file]  [-o results] 
  453: \end{verbatim}
  454: где 
  455: \begin{description}
  456: \item[table\_file] файл с предыдущими оценками (по умолчанию
  457:   отсутствует), 
  458: \item[results] файл с результатами (по умолчанию---стандартный
  459:   выход). 
  460: \end{description}
  461: 
  462: В этом файле вручную расставляются плюсы и минусы.
  463: 
  464: Флаг \prog{-d} означает ``Debigging mode''. В этом режиме программа
  465: печатает массу дополнительной информации.
  466: 
  467: \subsection{Сводка}
  468: 
  469: Время от времени дежурный запускает программу
  470: \begin{verbatim}
  471: reminder.pl [-r номер_раунда]
  472: \end{verbatim}
  473: Она генерирует список команд, которые имеются в файле с таблицей (по
  474: умолчанию---стандартный вход), и посылает его на z-info.
  475: 
  476: 
  477: \subsection{Результаты}
  478: 
  479: Итоговая таблица и собрание сочинений генерируются программами
  480: \begin{verbatim}
  481: createtable.pl [-d] [-s|-m] [-t table_file]  [-o results] 
  482: collection.pl  [-d] [-s|-m] [-t table_file]  [-o results] 
  483: \end{verbatim}
  484: Ключи имеют тот же смысл, что и у программы \prog{processmail.pl}. 
  485: Флаг \prog{-s} означает выбор короткой формы вывода, а флаг \prog{-m}
  486: означает выбор промежуточной формы.
  487: 
  488: \section{Программа}
  489: 
  490: 
  491: \subsection{Внутреннее представление данных}
  492: 
  493: Сведения о командах хранятся в хэше \prog{\%teams} со следующими
  494: полями:
  495: \begin{description}
  496: \item[ключ] название команды
  497: \item[элемент] ссылка на анонимный хэш \prog{\%teams\{\$team\}} с
  498:   полями: 
  499:   \begin{description}
  500:   \item[\prog{regnum}] регистрационный номер
  501:   \item[\prog{numletters}] количество писем с ответами
  502:   \item[\prog{answers}] ссылка на массив из ответов
  503:   \item[\prog{score}] общий итог
  504:   \item[\prog{rating}] общий рейтинг
  505:   \end{description}
  506: \end{description}
  507: 
  508: Сведения о вопросах хранятся в массиве \prog{\%answers}. Его
  509: элементы---ссылки на анонимные хэши. Ключи в хэшах---тексты ответов,
  510: а элементы---опять таки ссылки на хэши следующего содержания:
  511: \begin{description}
  512: \item[\prog{score}] \prog{+}, \prog{-} или \prog{?}
  513: \item[\prog{teams}] хэш команд, давших этот ответ
  514: \end{description}
  515: 
  516: 
  517: 
  518: \section{Благодарности}
  519: 
  520: Я благодарен Якову Зайдельману, Льву Горенштейну, Алексу Покрасу и
  521: Дмитрию Рубинштейну за помощь в разработке этой программы.  Версия~3
  522: программы (поддержка незачетных вопросов и промежуточного формата
  523: таблицы) была написана Львом Горенштейном.
  524: 
  525: \end{document}
  526: 
  527: %%% Local Variables: 
  528: %%% mode: latex
  529: %%% TeX-master: t
  530: %%% End: 
  531: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>