Guest User

Скипт для обработки vote.txt / linux.org.ru

a guest
Oct 13th, 2013
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 6.74 KB | None | 0 0
  1. %Требуется SWI-Prolog. Проверено на версии 6.4.1.
  2. %Написал proud_anon с linux.org.ru
  3. %См. https://www.linux.org.ru/forum/linux-org-ru/9627248?cid=9689847
  4.  
  5. %ТИПА ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС
  6. %readvotes(+FilePath): прочитать vote.txt, assert'нуть voteopt/2 и vote/1
  7. readvotes(FilePath) :- readfile_votes(FilePath).
  8.  
  9. %vote(-ListOfChosenOptions): readvotes добавит в базу результат каждый голос в виде факта vote(СПИСОК_ID_ВЫБРАННЫХ_ВАРИАНТОВ)
  10. :- dynamic vote/1.
  11.  
  12. %show_options: вывести список всех опций
  13. show_all_options :-
  14.     get_total_count(TotalCount),
  15.     get_total_count_votes(TCV),
  16.     write('ФОРМАТ: Вариант [ID варианта]: число выбравших (процент от общего числа голосовавших)'), nl, nl,
  17.     rec_show_option(1), nl,
  18.     write('Всего проголосовавших: '), write(TotalCount), nl,
  19.     write('Всего голосов: '), write(TCV).
  20.  
  21. %Вспомогательный предикат
  22. rec_show_option(OptionID) :-
  23.     show_option(OptionID) -> nl, ONext is OptionID + 1, rec_show_option(ONext) ; true.
  24.  
  25. %show_option(+OptionID): вывести информацию о варианте по его числовому ID
  26. show_option(OptionID) :-
  27.     get_vote_representation(OptionID, OptionAtom, NumVotes),
  28.     get_total_count(TC),
  29.     gpc(NumVotes, TC, Percent),
  30.     format('~a [~d]: ~d (~2f%)', [OptionAtom, OptionID, NumVotes, Percent]).
  31.  
  32. %explain_vote(+ChosenOptions, -Atoms): список числовых ID выбранных вариантов превратить в список человеческих названий
  33. explain_vote(ChosenOptions, Atoms) :-
  34.     maplist(voteopt, ChosenOptions, Atoms).
  35.  
  36. %count(+Options, -Count): посчитать количество голосов с ровно такой комбинацией выборов
  37. count(Options, Count) :-
  38.     findall(X, (vote(X), X = Options), List),
  39.     length(List, Count).
  40.  
  41. %find(+Options, -Vote): найти голос, где есть по крайней мере выбранные варианты
  42. find(Options, Vote) :-
  43.     (is_list(Options) -> Opt = Options ; Opt = [Options]),
  44.     vote(Vote),
  45.     subset(Opt, Vote).
  46.  
  47. %find_count(+Options, -NumVotes): посчитать количество голосов, где есть по крайней мере выбранные варианты
  48. find_count(Options, NumVotes) :-
  49.     findall(X, find(Options, X), ListOfVotes),
  50.     length(ListOfVotes, NumVotes).
  51.  
  52. %correlation(+OptionID): вывести данные о корреляции указанного варианта с другими
  53. correlation(OptionID) :-
  54.     get_vote_representation(OptionID, OptionAtom, NumVotes),
  55.     get_total_count(TC),
  56.     gpc(NumVotes, TC, P),
  57.     format('Всего выбравших "~a" [~d]: ~d (~2f%)', [OptionAtom, OptionID, NumVotes, P]),
  58.     nl,
  59.     write('Из них выбрали также:'), nl,
  60.     rec_xcount(OptionID, NumVotes, 1).
  61.  
  62. %Вспомогательный предикат
  63. rec_xcount(_, _, CorelOpt) :- \+ voteopt(CorelOpt, _), !.
  64. rec_xcount(MainOpt, ChoosersNum, CorelOpt) :-
  65.     voteopt(CorelOpt, OptAtom),
  66.     get_total_count(TC),
  67.     (MainOpt = CorelOpt ->
  68.         (count([MainOpt], Num),
  69.         gpc(Num, TC, PAll),
  70.         gpc(Num, ChoosersNum, PChoosers),
  71.         format('* Никаких других вариантов: ~d\n\t~2f% выбравших исходный вариант\n\t~2f% всех голосовавших', [Num, PChoosers, PAll]))
  72.         ; (find_count([MainOpt, CorelOpt], Num),
  73.         find_count(CorelOpt, NumCC),
  74.         gpc(Num, TC, PAll),
  75.         gpc(Num, ChoosersNum, PChoosers),
  76.         gpc(Num, NumCC, PCC),
  77.         format('* "~a" [~d]: ~d\n\t~2f% выбравших исходный вариант\n\t~2f% всех выбравших этот вариант\n\t~2f% всех голосовавших', [OptAtom, CorelOpt, Num, PChoosers, PCC, PAll]))
  78.     ),
  79.     nl,
  80.     NextOpt is CorelOpt + 1, !,
  81.     rec_xcount(MainOpt, ChoosersNum, NextOpt).
  82.    
  83. %Во всех более сложных случаях придётся непосредственно вызывать vote(-СПИСОК_ВЫБРАННЫХ_ВАРИАНТОВ)
  84. %и с ним работать
  85.  
  86. %ГРАММАТИКА ДЛЯ vote.txt
  87. :- dynamic voteopt/2.
  88. voteopt(_ID, _Atom) :- fail. %ID = число, Atom = расшифровка
  89.  
  90. whitespace --> (" " ; "\t"), !, optwhitespace.
  91. optwhitespace --> whitespace ; [].
  92.  
  93. strvalue(Value) --> "\\\\", !, strvalue(V2), append("\\", V2, Value).
  94. strvalue(Value) --> "\\\\\"", !, strvalue(V2), append("\\\"", V2, Value).
  95. strvalue([]) --> "\"", !.
  96. strvalue([C|Rem]) --> [C], strvalue(Rem).
  97.  
  98. fullstr(Value) --> "\"", strvalue(Value). %strvalue заканчивается на кавычке
  99.  
  100. strarray([Value|OtherVals]) --> fullstr(Value), optwhitespace, ("," , optwhitespace, strarray(OtherVals) ; [], {OtherVals = []}).
  101. %Используется предположение, что отправить результат голосования без единого варианта невозможно
  102.  
  103. linevote(Options) --> "{", optwhitespace, strarray(Options), optwhitespace, "}".
  104.  
  105. registeropts([]) :- !.
  106. registeropts([AllChoices|Rem]) :-
  107.     (member(C, AllChoices), atom_codes(CA, C),
  108.     (voteopt(_, CA) -> true ; (voteopt(LastNum ,_) -> true ; LastNum = 0), NewNum is LastNum + 1, asserta(voteopt(NewNum, CA))),
  109.     fail) ; !,
  110.     registeropts(Rem).
  111.    
  112. registervotes([]) :- !.
  113. registervotes([Vote|Rem]) :-
  114.     (maplist(atom_codes, VoteAtoms, Vote),
  115.     maplist(voteopt, VoteNums, VoteAtoms) -> true ; throw('Internal error: unregistered options or atom_codes failed')),
  116.     assertz(vote(VoteNums)), !, registervotes(Rem).
  117.  
  118. lines(Opts) --> optwhitespace, linevote(O1), optwhitespace, "\n", (lines(O2) ; [], {O2 = []}), {append([O1], O2, Opts)}.
  119. lines([], "\n", []). %На случай пустого перевода строки в конце файла.
  120.  
  121. start --> (lines(Opts) ; throw('Failed to parse the file')), !, {registeropts(Opts), registervotes(Opts)}.
  122.  
  123. %ДРУГИЕ ПРЕДИКАТЫ "ВНУТРЕННЕГО ПОЛЬЗОВАНИЯ"
  124. readfile_votes(FilePath) :- phrase_from_file(start, FilePath).
  125.  
  126. get_vote_representation(OptionID, OptionAtom, NumVotes) :-
  127.     voteopt(OptionID, OptionAtom),
  128.     (findall(X, (vote(X), memberchk(OptionID, X)), ListVotes) -> length(ListVotes, NumVotes) ; NumVotes = 0), !.
  129.    
  130. get_total_count(Count) :-
  131.     findall(X, vote(X), ListVotes),
  132.     length(ListVotes, Count).
  133.    
  134. gpc(Count, TotalCount, Percent) :-
  135.     Percent is (Count rdiv TotalCount) * 100.
  136.    
  137. get_total_count_votes(Count) :- %Это то, что на ЛОРе называется "Всего голосов"
  138.     findall(X, vote(X), ListVotes),
  139.     maplist(length, ListVotes, ListLens),
  140.     sum_list(ListLens, Count).
Advertisement
Add Comment
Please, Sign In to add comment