From a0709e4506b66a024f0a92b6b06a09e583aaffe9 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Mon, 4 Jan 2021 20:46:38 +1100 Subject: [PATCH] Add test case for ERS97 --- tests/data/ers97.csv | 15 ++++++++ tests/data/ers97.ods | Bin 0 -> 14323 bytes tests/test_ers97.py | 86 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 tests/data/ers97.csv create mode 100644 tests/data/ers97.ods create mode 100644 tests/test_ers97.py diff --git a/tests/data/ers97.csv b/tests/data/ers97.csv new file mode 100644 index 0000000..0b2c321 --- /dev/null +++ b/tests/data/ers97.csv @@ -0,0 +1,15 @@ +Stage:,1,,2,,3,,4,,5,,6,,7,,8, +Comment:,First preferences,,Surplus of Smith,,Exclusion of Monk,,Exclusion of Monk,,"Exclusion of Glazier, Wright",,"Exclusion of Glazier, Wright",,Surplus of Carpenter,,Exclusion of Abbot, +Smith,134,PEL,107.58,EL,107.58,EL,107.58,EL,107.58,EL,107.58,EL,107.58,EL,107.58,EL +Carpenter,81,,88.35,,88.35,,88.35,,122.35,PEL,122.35,PEL,107.58,EL,107.58,EL +Wright,27,,32.25,,32.25,,32.25,,5.25,EXCLUDING,0,EX,0,EX,0,EX +Glazier,24,,30.51,,30.51,,30.51,,6.51,EXCLUDING,0,EX,0,EX,0,EX +Duke,105,,106.68,,108.68,PEL,108.68,PEL,108.68,PEL,108.68,PEL,108.68,PEL,108.68,PEL +Prince,91,,91,,91,,91,,102,,104.31,,104.31,PEL,104.31,PEL +Baron,64,,64,,64,,64.21,,67.21,,68.26,,70.26,,82.26, +Abbot,59,,59.84,,64.84,,64.84,,65.84,,67.1,,68.1,,2.1,EXCLUDING +Vicar,55,,55,,69,,69.21,,69.21,,71.31,,71.31,,113.31,PEL +Monk,23,,23.42,,0.42,EXCLUDING,0,EX,0,EX,0,EX,0,EX,0,EX +Freeman,90,,93.78,,95.78,,95.78,,95.78,,96.62,,101.62,,101.62,PEL +Non-transferable,0,,0.59,,0.59,,0.59,,2.59,,6.79,,13.56,,25.56, +Votes required,,,,,,,,,,,105.87,,104.13,,96.41, diff --git a/tests/data/ers97.ods b/tests/data/ers97.ods new file mode 100644 index 0000000000000000000000000000000000000000..cda95761da9ec1930f51da858d95a741313749b6 GIT binary patch literal 14323 zcmd73Wpo`$vMnsx7L&zH7BjPCF*7qW%Q{Dl7FuXAGcz+Yqs7e3%+izReto-V?(}@` z{(Es&t;#y9VrOJ#WmHy1Y&pq~pHM(RAVENKq=^;$tvG^dK|nx$AMbyGSesiL16}Nl z_3iAe%nkK{=C(F;jy6WLw)y~b0IjW^v5k?fp@X%t4UiUKXK$=;1TZr;2Fm>t<~z)P z3&wj%(ALJp+|toQwf#?a{<|7~_lcdpjj`4LvPL_5TT^>u0N{V$MgUMB=`7TBLWd1gL@0T_z!|wuMKl$mbLtrcZB`i7>5&*Ce0l;|zpU z6?7^w8&Z%AiJ8?NP;oZXHs&sIF3#6c;V0o6~HzCI;JA6AlT57bakSv+a(>F}4Y1qACwO%7}2eBj5>H;VjIkg4VB7Xbr3* zi2TkM1|>D*2lT~hl9B9Xio25M=*&FX?AL3Z^3CGbJEsaCpI`j}o42F0-db_0<-6t{ zYvy`t=;|=ld$C3oqnE;XDtp+>Qc&=lL zVv{6JD8Afk9?n)08OB|&p^x;FF5#$bc3_XUB;LXHPVMCQpjU)3yM~wv$$=zc6FRgC zuid40!MRfMqU=7X+v|0m-+o&3C$m$YkaXy_pz>SH(j801?9-kT)<(kA+)9Y}G^eIi z2CYjBL@-l;-K4Q7HOaFu>IORa1aORvU|w5w>NJk@V_9~h7XvI~*^qF2efX#Ku;jS` zbP|WWcTtnv^T^Fsr_OXYIIh*txkUCPM$vwUMx1CDECg_tKem2TJ*UZ{oOIYR-FYQOk*tNDw`i#aDFTd07_-C4H&7HmpW%*Wr;b?<->^ z{D6!uCv3O6ZLfVdh}dK<>)%vyQT>){7H`;sMIw9^VB$*2rg0#OG07m~!P*)<+|OjG z-avnkH@7Z2SkwD>=l{p?hJK$e0HBMNG2r)zuV@_EF0p=oYisY4^Va`Js#rHgdy53I zlD*{3im{0Dq&9&*YR%Y$Tv= zhbG-3$JoHBOxQk9KHs=?a7NUkYi~9Z7x=8x18dEgGAuU$5!@>VwPzr2M~#9gk!{$0 z1?KDXLl~Zk8V!j??K^<3$!v&vq$V!hFJZ7)kH)wXM6Y=zyuO-Yi=x2;;#!UTqV-c+ zGCG$IPY}!0xoq}6*m{GWmg^}->_~5bVmBI*H^poK6g{S_#HbluBhF!{ewi!b>95SH zU=|^2DikED;9>~__)7YE!kYOn~|7q0(K=>aK!ECguC)cQ13-TSW?)_qAQ(OoPmrdPGRfUb((RO(~~1+ElKLEBN9= zi?Z+T+!9-J)b_#z%4AEeXDB-bxRcVB7RN6>5S0Mc5-G@|x6KISsLBDt-)zNV~4Fay;i? zLyi&qEG-mfuqOjWel+AGQ*cr<l>`C?R&A%v@1Dudfz=vTJ*; z*C*$Rv|1^+uO+EEoRI7#9UsvJzP2$iSb%!Dn8%aXE6jW`m~0I4;mM0^9u~84RWI5$ zh(e-3xi`r|OZ|#93guaU`)S1mq{;uSOU`!C%}>-AKKALV;_Elntb_u^ytuRK0WDHQ zsnAakB`8wkFzT5LCpu*s)Hz(2Xwkq@jpN|S1|)wv@6G2&_OP#UgsK!ea`&HS*+rs# z-R~N3kDs10CC%cBc4lXu1JLi|NU(4iS3;-aSZs zHr=)O#K39rS(l0Qs{Es4y)L{Dp(kQ3D9Jum%&u=$_g6%`Nd|2I1}~)^YAWSRXxRK! zLg<0sLX_HB{f0;td^l}3y#INtpFL5y@`e{98h*}FqJvl%k&%VF7=_5>a6HY+bwaMQ zFI&`^!nRUILm%6xn1|=>jAv-sG!m@v@7@H{O^0~M5nhDj2rJ^JzL(M*w-9@w>1{+9 zyn#KO40F*0F3YQrr~*S%doD)oO`1HiuyGq55a1AtgpKPF?DDkSb=-~>4%`;(^YCuJ zoIhCooL~D&WmT;+Z;~HC!#Zatx~f0v^=Nl!v+i`5zc8T^c6i36cSb(Ga_GWH4h8+< z-A~n3)r;DwT>*$VI zOe_>H^MMN&W*zH=7qHyms;M4j@`}UDRGR#ahHnFFM40)w@W5Mhtow?^>&0&Xh!mxn`pugZ+UcWTzdGGJ6h^A#`cs! zCAk!6eQpmSPIM17ULk(Jq|&JLC9J_gKu}2k)1n0C{Uv2+YXkhf{(pZRQ-Zp_ybqHaCq%v(8`VAj)*87ph{a(}XdZEjzF-U*h@m*?vzgh7Ln z&PA+H>Ux8pmg!~RQtCjBY>EVv?GODS7OEH}#}L< zVmPcp8^8OD2{T=N?bW)FQSeu6jl^|mpneO?$zq-9Xi0>a!LlguVXmsrf;KvpC1ujg z=-?L;r!luWsw*GgBt#>5(-8U37(Aq(n7+{9F!>^%R=U(#J*_f|tVyzXv~Z7};+LBB zWRO2tLyG_Mj;nRPoyY&lJ(SeeYu?vDJ*i&-ZVH2EsfMA(oEKbDfitCkr$bMsWdI@N zTWrzu0;`FhL2n!dE8>PUWkEzpCTT?l4Rckcp)Cz=<=|gBYa9v&!C7YtMhrh|up=ln zX^-kWJbjr_Nb*x}Gv?e+!lyR30vkXb{tN$Uub$E)WlfEU3K3he&J>b=ncw>12CKBZ zA|QmNoxb1`RH4V&tL8y3Q-^R0zcuyMnzkbjp#Q{=_j;OHpp) z5atn&efajAqA)fM=U>=?5Vl6zCR}5sK315od^q`Km2z?F{RCG)L=F<;|@u zLC(gdA*XUh`OrXOk}wBt1|FTRiS_mH*4aIb+L&gW`?Hxa`)`0j(8Wc5#{NMa1qwUL zvk{rLGAlow0G**bgICI#u%MF>lZ2SH zsFp-mj@wq;@ru@#^fLhk8zW=3h|U&KYLqZ_y^!*!9e$2bA++c~AKA$yiA(}6W+XHL zNd~sP@@B9@6jk~I2Pf|hZ=Yhn1BDo3c?%p`Wqo7t+b%OSadL;* zT&6L!M9*0brxW;Kh&-B=`W!QycoNKw!$fJ_<0CW3YRxJ2@;hUOb7ZtY?C>vi^aQgJ zK(9&(48tZ$ko#V-I~tLcq7Rw)uSGkqz+{T~<`})Bh?!MM2fzh8D*q`e7&dMqn-cJ9 z_0oYC{RbJ3^+}kFaHpR?!p}xY@G^Q7fW*$I@~NRxSIZ9vX0}hUL$xuddzGW+F##e{ zq|5=zJS3G9lI)@f?ZRO#x~ED{6*^aLGkA(=RZ(pGRWp+mI=x6ac9z(}`f>cs2!%gP z%r|Zv<;i_!;EOr&(D7LC6?iVO4GT?3+j#1&%FlH;lrU0EV#J^qstuc00igmYi~91y zeKhtHv$PgNvT+AgLFm&F2$;+0QQaMmTsvEn;f!Xwu|{l8NFQeIhbU>wORSs87!vzJ z2S$-_$sHMnD=iJiIM}TbE-~ku$!~207u?8ibp#jgP91E)y|BZjt6z=Yh}qI-@HhG$|)C&A3i$oes0=zq#I|Qt|<=ixNV`|hL7AV zY$U+hq}wo&#TmaOc4f%MxV{RT?rBE&Zf%3HLCzh215Z$-7SF#fM~8)?zt5uu%I@aZ zVItn8p&{0zNCFFcSqsHNIc?c-_j<1Fb zoHY8wq=*jz{7<*$K7XE<$Yx-jl~e4F__y0nW)NGkWR~Ai>8{rYYE4W%#BiY z5C$cQGs#}5*-&}w1X#k=r8j{R~zfq6eR+twR@dtt*+?i zI4?5iv4L-)oJG!u#j1&`h-Jl^y!^ZGitNOI)A;Z=?rZSSfI4h?Q)TC8bcPIH&Qq!+ zt#TPB@LAUZx;BM(yB5?mZr}SYzH+fXTBEUaS>-f2Xd#^=7pifhauAZOC_6jwCWpyn z9A|y?bz2+3B!8II$yByGYIk<4s#|D6B zm{kGvTz}ETKy|}QdVddR8{flq!aZ5E5|I7n?8_!|Nxmg5W3=@e&So1HQ6MXjwiulP zcX`(i-nszZ8D*bv%|m5iu7Z?p31Zn~t2J}2{*G>0keBLL^N(WZfZoH@Ds5v5=6#8m z!_r4a9r*|S+A#cd3fo;?Sw$V|x6{+n|M~_`>sF=9d*4!NaQaWno8Mbj0AnD~+{W}D zU*RVjYk)=e&z|k=U$&gO%Hz;v1p+5_*TXF_q<-nF`L%kJR?QL(Vm!{JTWv`lE^-)9 z?{WfUgRBphZVspFn;BK{9ltiu`$V8T)Xub7siSvjUz6+VYTkt`^|>8&uh&y)l@`F% z1={R?RE2|*I3T?q#pIG1JNSp}N5kXkY9qV+8P_SP@^le0)qYM#=i#2p?zeG) zsakM#oT@o|E!^u|XVZj7r`<{U4+{W0Hk_Cf+PR9wt0v^BK&>#=#~*AJ{~_QZ}tXl%60zgbNVL zkH{(HKD^bE&!1!qz93z%`A^su^Z%5eI2%CKm+2^Ygy9*W>j3v>ohTF&_#E7nHvw2R zMWlq4gL`fF)4hNTD9h3mo7nR!m+VrEWJ_#kIZ^@VqC<`it{k&FnmL2L0gn}E@5_A( z*r#KbxQJ4|W(D^kpdQI44Zo$bxx`c#q%NcLQI%#I1J7Oq8$G&3iUi%5O7J?9cM;&bUs+ZxG24j4gdHuc}`hiNg__>>!ueE7xV)C=me0SVx>y zqi5EBrmPh5_VC=ZH{TIfmW*fmVY4gy!&*4Q72GG%*WpJt+0Zx4SPC;HuCF4vgo5$| z$1>$h2Q4Qv6(!(4jHC)~c#rPklNdkpmk5YNkZ>mj3_(1;oC)M=irU@2A|(O|(pM}Q zqUb$KEFsY55HxUjFVxs14}e{y$zp-gdfx$GP`AaE1HYrFwJR=KVph{b6b>q{s?}(q z&d?(0E^DPgp7}}sv?-)^XeT{4*eg~b^T$6e0NyqsAr2he*~h&u8jocb)8P^D<9gXd zuR?+aEnFvkOp$#>s=0px^-ZM(m}S^F3>xz7A_)qLL$TSK6m{EyGdZQ4oRK)wEf&c8 zS*Qe66XRuD=vUZrNb2iXXfSJ5j{u!e>8J|mz04|zkz8$U$jJA{eXN?N=nsPC~ z`M)r263K7FV%LmmY`7n|2lpf&c?4@j!%<(-E3tnWfy0!~CFW#EO^_ghU+6MGew36U ze~NwlZ?~`OkBLQ~j5f2`TRB@Z zLZ)AM@!F`kl3GM$J_JZPDG#DOe~c&U(k>w2%N>=!${$}It-=R^ef`IlA2bGwAIm2Y z5CMWe+|3^W7f-6q3hno($nWEKa74+>!P>w^-`om72mGT*YiDB`Bqt*Z2aWZ6R}fBI zOi1DVJo1b8_!hNG-{UehDlF~vWV?&~oLy}S>0)3)G{i4D`(gVLIhWVt11;<7P#zcmsMEfU4 zha@C~B_zcA1?2?A<@`*jj7`psNvciBNDs*@h{?*1&MJ;ADo@GGNzN`#Dk@DXs7bBJ zPOPlU3JE9*kI#t@&Pk4~hzqJnj4sOwE6hr&El6suNY2mC&n>PkuP836ZmccIZLBJ; zudh$3?#e6f%d6?jYwpf&94M;oEUg?VZR##>94T*}t*-5N??p>G~o|~KN8C@S<*qmA3npwLT**sd>+Fw4nSh;=NnjhX;p1W9{-di8u z+g!ff9KPC{f4ExR+uPsTx!OLu+&Z~GJh?bHy+69Vy*%E(yFR>nmz#&1ho^_ztEY#X z*VotIbK&g`=xE^#0)mPyF2t|oym*r81;n0-?bpsQ{vLN-V=f8r|7u`C~ZO$i+rctQvM7RaEeg%_~6sNuHyDhgf58E`VbpuXH zTE?VP%dddwsvBOD6@@wDkJW1T%Z=l4W;Q1iK6JXTJFBv~XZ2d`+r<~yl$xT8rk#2b zt_HVe+~!n@SwV_(G*Rt0XNV>nzlQTylr?RtbYi7O0)#Elj=)8}zDfk;0rH%mw$>J% zR^*a5f>j;eYfELIiw;XBMhsS9*NEevM#C-3l6hBdA79=X=jnuRk}$~Ie(HX7j&k4dV-&!RmQM%I8iq)2O>^zr>SD4hO7j*MyAi8Y-ORlJui3wL~Xg zL_;p4=4KM2CF=u}VPla*0M@FE7UM31iMrj-yC$!pbEztTumKtS&#(jtiGrorrM;lf zZ+rzy)EuckGJqQxkY3Hl!1nd#;CA47c6(CwNnH^Hy5C+9zW!GdCE{|=&ffIWQ>wJ} zUd!}+s@|W@PNZKSnLDDIBB^@sTuMdmd^Uz2^G-E}-7k<=N$Tz%Y)_s{+?@Jp-0GOy zW$p6DbM;r65+wWf1O#do1l?HTFcT&*S=-7ct z2>1ah&Mpc~e!6y-!Pji9fN<-!GdA7%H--R)xC_z&zAei znUAt6e!P%t8Xa}vN-tAiOpIiamYeK7 zUnI+px+v!dY4>6`pq^){@-Fv3jZ0i%b<~b)vZ7*n)FXJ5D*HAU<6QM12+U=bSraMW z7M1bDN%tNtn!i#CRS$_R9gf1vKG;H~ew2Ea2!B!AWIRRofP1k^JQ+hxrP_=?Zh1Bh z=y2GINSy*$zLk+qtCw$L4+Hr6YcjB2Gdg*p=xMIyVw3Cr=yQ z1W_Q@3O2og26yHH@BVh2WLO^92!I&sOwwsNRhi+((0Cs zShKo&hO^!lL->AccAW~QsiOLr#vJ{+BE#Al>OMQj?R`jGydbU8vWnapFw-kzHEg# zln9{TXq5f>)c!zN;>KdiTXQKNFUf_EB^U3@18S*DH8CK~R3TNhBoa9EBC=U%2KRVP zqAET6L9+8kQj2-PJ1BV7KdY-bv!Md&%U!n#^3q4DbXnrDpLuFo<|CobH>{~a$=Jvc z^|5C2MyH+mmh0aQMYUK8Sv24pDkq-H)Gd>v(5{|ovSR8*$gE<1u?8K2d(>PiZ^O)u z7o4^18O0YPFBw7aGY=%vK8OKo?Q3w{ByhMs@tkiK&iT64mJQ;uhZ6OFi(zTpmeG{> zh!C}IW!jA8ltE`NbT`05Jsf&wigCt8!`)l9$7n+fW#b)W2o*lu(-^gNw+mUSjY7mM zFDr0$Iw1xp4d-<-iKe}$>)0^JiK2Pm;wdr}t!={Td(lUdWQ}VqH4f4s4Y!q?oM0AY z;>8p?`{MA~lGn>uin(^AMrCfZt}y5+zCbfvKWF0!CS>2}84m@I5*d50Apgju^7ZF_ z(WMAOqBfzrVWEwmiAR&RU99du7zuC?_JvK#2s< z|Kg^Hx{<6YLFDsBc0h8Cecvmxz_45|aTs0?!HKP5x@N-GH$P;p>@-0e4>6fGI&rfi zyh$PA(YL~JO2Gbho7^zDdd#ZXVr7CZ{eUYSbFXq!(pVs3b|x$=IDOTXHTXz4>>KQP zdpIYZFSq=I0$peRAcjjFO&lz{i6mFO8&h+^1x@Ok=IBl1iuXjzu095%#|@2?>lmMh)dbG}eTzzhxzX!* zu1GTm?lR!zWm9!F2l>uQX5A-p=ZpVxUdsw^RhWcE7KT1NkQnVPM^>Sy#ZXSAB@Q0>8kP;wghq&@`!TPOKeeTc9J$b{- zX?c21l6vK&pI|^&5dtT@hQ*@AVQ&NOoRd0VFoAWo{R@I%*x&ln5R>JefwSIgJ)rJ zsJc5dnIf-`Mg-PYK`dWv!X*Sxc1g#MpKZC<(m9qAS|llie_dhnAcS4WeR{N^xwA&8 zrw~=`=uD3_KlUwZ>1nQil_k2z;4L5k^&3awDu?!C5%!BmN|KpR0P2+22PEuuoiWbnWrsS{bvr9K~{FR zi6WlrfeevRWC(Sllo?8#)OAiEi*&4+N?QO>|KlgTwa>QlC#-1WB{88QqYg|QTfh9; zFdR?P6~aW^8^;8I9I!t@jdxs>5cYWt#UMDxCQwexz&vHc2)$~C9I#36wh%@im#tB! zie>pSs*`68mByDBe^H-y>4w&UEPvfK$7hv~HZ|LHU|C;y0ke1%3!%20H=8vHj)4_z z*Bld^va7&Hm;T1VjpMU3Y$`JgN$$rvP53%|_42qMy}|SED|3*jTmsv7g`)bnX;RjwX<< z8|C!1A!}1aO%vwVnze6jzMeR)(VpILeyfuFw?WHp{PB(^;l;Z*m?Aih(?yM}G{4=I z94Nan24L44qT2%49iPs)Z6*_Xx-1V;Ps(=*LACLT9ak3`C(@6#mkBMmV7zDXFSNWu zb!6Y22Az*CsZqVQOR$Fk-<9ij&{hu>DvgzQhPgs zt9V`0@_uH82owcul7>@GErT^m2>CKajU_d(nIE2d`ikh1*P)CkTI!AJXLrH9hZu}) zx}&p~rq6itd#|j>JLDN>qq z;7iyL9b_YZ=zrA4cN*%7hR3d?ZRJ)~$k!>xTQ;+@KmTZTC{uP7?epPC$0aed2A7@e zD_LFP%ul;|2ct~+@R~Ad`~{^fm-!Jp4Ys|d2J9~C_yxERWpQ!UN5jbYzNr$y`cwKQ zT(iPMGT?<5puLHa324^_Ouy%8v$QX;*v z;-z=upkd2JHp&z-!{k&hL*tsqjh7!Hdve^ynh8jcE*3oX`wY#}#G z3WP8>o*KQ=lIlmES`Z>|i_4DrUH70q3j-T5I-mHXxK3WKI{su_Y-u!TWeU#*{0#o7 zIYE4PBqC`U-$(PW9UuhdCN3myrFdn^8Fe6{r|D-|t!%dnQ*f<)=#?~gYrPe?j%2yd zA&drfI92w2%pytjqlr9qeTAZzj^V<(^F<0PDA#rbG*pb_RUa%Q{83m#7%!pnmHE(6 zuA?q&QoTX;3GwV!&!Bp0VA>Vx+*lcH-<0iH~WGZ7sK!sxhQm;l&8AOyEAYf6{tS?2eTqi{Yuas*duqH}t_ z6F-P8mNeQ7w`*xQWi5f zxnLm71`~!u#S;PHk1QbjJ-vvxtHn)QGvW3^PS8b_){9^>AL*ir`X~Z?#qKID-m`TrLx*GZ+oXi$0(pL6Dl42Xze zS3r@M;(Sc+7^&KXhra>Z20A09DNB+$Z1S$fzlGA*z-n6zsgZNe%Qm^6AU{7(`_XQ6?mCh^p*!%L9RIi3XH;FAE zXtqiyoxIRBGN!}&Et&$8b|-Uk;kqEPH!*NbLpqR1I!~O(TC`p^hOLphyc%&-P$pba zZFcQ6$4xqrqz|i#u?39jPW8Tay2jffAYa?A_Um zwzlYT>FgBS)I7B5i@Cb$m=fy)dvOo0mih&B)6p6mLBrYNeYBSkIesPGr}U{FPBAOM zIKzev%c7OT20`hcNlItUvyzJ(C=#vC&G9a?$*UFz?TJSp-N?h8+ZU$=j;U;g=eV?S z>a2!!rwL77pN-nq)O4)k^p^j`a9P4i4RGnW8SoK)xXQ(>RqsDu!VY(d`ADPEJ}A5~ zve-Ks4&OZbT0n*1wA;B^g%E3|US9JgGQb+r3ZTf0_F%a5x0p_tQgCod5b}boMZlS&>4e@c5 zgP7_NG_IZ_cbnEa0Z~s7EZzg_ZUy3)+?kTTgyzg9Qi6HofzT|1tFdNj)Hq{aFTAlu zh87XCLKdvy`?585waj%QRp++@SM+#Wxu(YY%%bL&Dnx?iB8A%sKQ}55rDJ=za2v(i z4G;Aup)0$Ag2@;h+a$VrX>+Vn_FFtJ(vcb-hh?ooA?Biac8(> zhOI{IoNH6#YiMoF+#MCYJpNu*iwWT=L(OpUSQ0EO93K~o9=K7xAPpDjM#7q6YlK|k zx}aGeKGe45r6WrPZ15ttq>awBS=;N|@YH7SGH?&1mbMx^PM;?PiwpxeS6R9-^y%ijx@N&KLZH0=!@ z+j|=#CUo{uK|*r5M5U@9z}oG@Lj$_uBI<)?he1XZ6!Fm^3jyKw+*p_taQ_Sh+{4Aw z{d>;SAW@q7mDW+)Q%)Pm4rQH z`cC53a@CYqmsCP|x(|Rjss?&o5-y6+jOEN~oo9RNuY_87BhHetWzI{;7qPHUeqtej zDy<+kpi=qD-A36>Jk#?9V*$`PWpx6vZ?l0Uk{fL;%isva^g>#;l8oEk-6J=>n#IH> zo@JV}3BYV$Hy^V{fjdv*9FvKb)RAKDK__7L3z+zf^*;F_;W7#TU%1$9b$LbzuIv_0 z?7DoXe1L$63(E+V3F!I!ebzbZ`(4t)O8hk9G9q;UoxT5_>Qx#oZPQKgS>%qxzqgJt z=OjiCx6Gx89GaC3MYin?=DWk_#71EoTfrMo*`k41ZBf-L}3J@y^>cFJ42JeiyRGQrf}EJF3y=$hxLnAeO(0Ag=ud!FRH>{4wfTldeDK z$cprQjMi*#gZY~w8Ck>yW^I;&2b7PZw^<;~P7YgN9f7GIgL!k2jVk>tzxL491F2pW zz(EdZme6qIVEMtU*n$(nECIT6!4U;XblUwGG+j3}|1a{If+F z{|4uunLK}w^v@P8{u`vfGJF0W=Qp?KPeJ<_ZaUui7A6DR%@*>|x2 z_8srcpFbYrKQ#YJi1Jf dd}90?FD)kt_MXEF0)qJdGk$kE&P>0r{tu$EV^;tG literal 0 HcmV?d00001 diff --git a/tests/test_ers97.py b/tests/test_ers97.py new file mode 100644 index 0000000..d167035 --- /dev/null +++ b/tests/test_ers97.py @@ -0,0 +1,86 @@ +# pyRCV2: Preferential vote counting +# Copyright © 2020–2021 Lee Yingtong Li (RunasSudo) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from pytest_steps import test_steps + +import pyRCV2.blt +import pyRCV2.numbers +from pyRCV2.method.base_stv import EGSTVCounter +from pyRCV2.model import CandidateState, CountCompleted + +import csv + +# Read model CSV + +with open('tests/data/ers97.csv', 'r', newline='') as f: + reader = csv.reader(f) + data = [x for x in reader] + +candidates = [data[i][0] for i in range(2, len(data) - 2)] + +@test_steps(*['Stage {}'.format(data[0][i]) for i in range(1, len(data[0]), 2)]) +def test_aec_tas19(): + """Compare count of ers97.blt with model result computed by hand""" + + pyRCV2.numbers.set_numclass(pyRCV2.numbers.Fixed) + pyRCV2.numbers.set_dps(5) + + with open('tests/data/ers97.blt', 'r') as f: + election = pyRCV2.blt.readBLT(f.read()) + + assert len(election.candidates) == len(candidates) + + counter = EGSTVCounter(election, { + 'quota': 'droop_exact', + 'quota_mode': 'ers97', + 'bulk_exclude': True, + 'defer_surpluses': True, + 'round_quota': 2, + 'round_votes': 2, + 'round_tvs': 2, + 'round_weights': 2, + 'papers': 'transferable', + 'exclusion': 'by_value', + }) + result = counter.reset() + assert result.quota == pyRCV2.numbers.Num('107.58') + + for i in range(1, len(data[0]), 2): + stage = int(data[0][i]) + + while len(counter.step_results) < stage: + result = counter.step() + + comment = data[1][i] + assert result.comment == comment, 'Failed to verify comment' + + for j, cand in enumerate(candidates): + votes = pyRCV2.numbers.Num(data[j + 2][i]) + cc = next(cc for c, cc in result.candidates.items() if c.name == cand) + assert cc.votes == votes, 'Failed to verify candidate "{}" votes, got {} expected {}'.format(cand, cc.votes.pp(0), votes.pp(0)) + + state = data[j + 2][i + 1] if len(data[j + 2]) > (i + 1) else '' + accept = {'': CandidateState.HOPEFUL, 'PEL': CandidateState.PROVISIONALLY_ELECTED, 'EL': CandidateState.ELECTED, 'EX': CandidateState.EXCLUDED, 'EXCLUDING': CandidateState.EXCLUDING} + assert cc.state == accept[state], 'Failed to verify candidate "{}" state'.format(cand) + + nontransferable = pyRCV2.numbers.Num(data[len(candidates) + 2][i]) + assert (result.exhausted.votes + result.loss_fraction.votes) == nontransferable, 'Failed to verify non-transferable votes, got {} expected {}'.format((result.exhausted.votes + result.loss_fraction.votes).pp(2), nontransferable.pp(2)) + + if data[len(candidates) + 3][i]: + votes_required = pyRCV2.numbers.Num(data[len(candidates) + 3][i]) + assert result.vote_required_election.pp(2) == votes_required.pp(2), 'Failed to verify votes required for election, got {} expected {}'.format(result.vote_required_election.pp(2), votes_required.pp(2)) + + yield 'Stage {}'.format(stage)