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