d'Hondt方式の議席割り当て
という訳でPythonでd'Hondt方式の議席割り当てプログラムを書いてみた.実は最初はSchemeで書いたのだが,vectorの破壊的更新が多いのできれいに書けなかった.まぁPython版もイディオムをよく知らないPythonの練習がてらなので慣れてる人から見ればイマイチかもしれないが... これでも上のハマリのせいもあって40分以上かかったのだ.PythonはDuckTypingの弊害で,専用の構文がある程/リテラルで書ける程よく使うクラスのメソッドの解説がどこにあるんだかライブラリ・リファレンスを見てもよく分からない.まぁそのためにチュートリアルがあるんだろうけど.
なおd'Hondtさんについては↓を参照のこと.
- http://en.wikipedia.org/wiki/Victor_d'Hondt Victor d'Hondt - Wikipedia, the free encyclopedia
実行例*1:
[nodakai@sprawl python]$ ./dhondt.py 10 c 1500 c++ 700 java 300 lisp 200 [['c', 6], ['c++', 3], ['java', 1], ['lisp', 0]]
#! /usr/bin/python import sys DEBUG = False def party_votes_pairs_new (argv): res = [] i = 0 while i < len(argv): res.append([argv[i], int(argv[i+1])]) i += 2 return res if DEBUG: test_args = ["c", "1200", "c++", "1800", "java", "1700", "lisp", "300", "ocaml", "400"] print party_votes_pairs_new(test_args) def max_with_index(lst): tmp_max = lst[0] tmp_max_idx = 0 for i in xrange(len(lst)): if (lst[i] > tmp_max): tmp_max = lst[i] tmp_max_idx = i return [tmp_max, tmp_max_idx] def devide_correnponders(party_votes_pairs, denoms): devided = [] for i in xrange(len(party_votes_pairs)): devided.insert(i, float(party_votes_pairs[i][1])/denoms[i]) return devided def calculate_by_dHondt (party_votes_pairs, tot_seats): if DEBUG: print party_votes_pairs res = [] for i in xrange(len(party_votes_pairs)): res.insert(i, [party_votes_pairs[i][0], 0]) if DEBUG: print res denoms = [] for i in xrange(len(party_votes_pairs)): denoms.insert(i, 1) if DEBUG: print denoms for occu in xrange(tot_seats): the_max, max_idx = max_with_index(devide_correnponders(party_votes_pairs, denoms)) if DEBUG: print the_max, max_idx res[max_idx][1] += 1 denoms[max_idx] += 1 return res try: print calculate_by_dHondt(party_votes_pairs_new(sys.argv[2:]), int(sys.argv[1])) except: print 'Usage: dhondt.py total_seats (party_name its_votes)+'