From 930b8685cff84cfe37adc25294f49a1b6d4e9566 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 27 Dec 2025 09:34:00 -0800 Subject: [PATCH] more fixes --- rust/pspp/src/spv/read/legacy_xml.rs | 33 ++++++++++--------- rust/pspp/src/spv/read/tests.rs | 7 ++++ rust/pspp/src/spv/testdata/legacy13.expected | 13 ++++++++ rust/pspp/src/spv/testdata/legacy13.spv | Bin 0 -> 5611 bytes rust/pspp/src/spv/testdata/legacy14.expected | 13 ++++++++ rust/pspp/src/spv/testdata/legacy14.spv | Bin 0 -> 3462 bytes rust/pspp/src/spv/testdata/legacy15.expected | 10 ++++++ rust/pspp/src/spv/testdata/legacy15.spv | Bin 0 -> 5306 bytes 8 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 rust/pspp/src/spv/testdata/legacy13.expected create mode 100644 rust/pspp/src/spv/testdata/legacy13.spv create mode 100644 rust/pspp/src/spv/testdata/legacy14.expected create mode 100644 rust/pspp/src/spv/testdata/legacy14.spv create mode 100644 rust/pspp/src/spv/testdata/legacy15.expected create mode 100644 rust/pspp/src/spv/testdata/legacy15.spv diff --git a/rust/pspp/src/spv/read/legacy_xml.rs b/rust/pspp/src/spv/read/legacy_xml.rs index c7fda83c11..99510240a2 100644 --- a/rust/pspp/src/spv/read/legacy_xml.rs +++ b/rust/pspp/src/spv/read/legacy_xml.rs @@ -453,28 +453,29 @@ impl Visualization { } // Make leaf categories. - let mut coordinate_to_index = HashMap::new(); - let mut cats = Vec::::new(); + let mut map = BTreeMap::new(); for (index, value) in variables[0].values.iter().enumerate() { - if let Some(coordinate) = value.category() - && !coordinate_to_index.contains_key(&coordinate) - { - coordinate_to_index.insert(coordinate, CategoryLocator::new_leaf(cats.len())); - cats.push(CatBuilder { - category: Category::from(Leaf::new( - variables[0].new_name(value, footnotes), - )), - index, - leaves: cats.len()..cats.len() + 1, - location: CategoryLocator::new_leaf(cats.len()), - }); + if let Some(coordinate) = value.category() { + map.entry(coordinate).or_insert(index); } } + let mut coordinate_to_index = BTreeMap::new(); + let mut cats = Vec::::new(); + for (coordinate, index) in map { + let value = &variables[0].values[index]; + coordinate_to_index.insert(coordinate, CategoryLocator::new_leaf(cats.len())); + cats.push(CatBuilder { + category: Category::from(Leaf::new(variables[0].new_name(value, footnotes))), + index, + leaves: cats.len()..cats.len() + 1, + location: CategoryLocator::new_leaf(cats.len()), + }); + } *variables[0].coordinate_to_index.borrow_mut() = coordinate_to_index; // Now group them, in one pass per grouping variable, innermost first. for variable in &variables[1..] { - let mut coordinate_to_index = HashMap::new(); + let mut coordinate_to_index = BTreeMap::new(); let mut next_cats = Vec::with_capacity(cats.len()); let mut start = 0; for end in 1..=cats.len() { @@ -1020,7 +1021,7 @@ struct Series { values: Vec, map: Map, affixes: Vec, - coordinate_to_index: RefCell>, + coordinate_to_index: RefCell>, dimension_index: Cell>, } diff --git a/rust/pspp/src/spv/read/tests.rs b/rust/pspp/src/spv/read/tests.rs index e9cc08ec64..d7cb877056 100644 --- a/rust/pspp/src/spv/read/tests.rs +++ b/rust/pspp/src/spv/read/tests.rs @@ -95,6 +95,13 @@ fn legacy14() { test_raw_spvfile("legacy14"); } +/// Checks that categories are ordered correctly when the first row has some +/// missing cells (in this case, "Beta" lacks a value in the first row). +#[test] +fn legacy15() { + test_raw_spvfile("legacy15"); +} + fn test_raw_spvfile(name: &str) { let input_filename = Path::new("src/spv/testdata") .join(name) diff --git a/rust/pspp/src/spv/testdata/legacy13.expected b/rust/pspp/src/spv/testdata/legacy13.expected new file mode 100644 index 0000000000..7e6092373b --- /dev/null +++ b/rust/pspp/src/spv/testdata/legacy13.expected @@ -0,0 +1,13 @@ + Chi-Square Tests +╭────────────────────────────┬────────┬──┬─────────────────────┬────────────────────┬────────────────────╮ +│ │ Value │df│Asymp. Sig. (2-sided)│Exact Sig. (2-sided)│Exact Sig. (1-sided)│ +├────────────────────────────┼────────┼──┼─────────────────────┼────────────────────┼────────────────────┤ +│Pearson Chi-Square │9.479[a]│ 1│ .002│ │ │ +│Continuity Correction[b] │ 7.898│ 1│ .005│ │ │ +│Likelihood Ratio │ 9.731│ 1│ .002│ │ │ +│Fisher's Exact Test │ │ │ │ .003│ .002│ +│Linear-by-Linear Association│ 9.321│ 1│ .002│ │ │ +│N of Valid Cases[b] │ 60│ │ │ │ │ +╰────────────────────────────┴────────┴──┴─────────────────────┴────────────────────┴────────────────────╯ +a. 0 cells (.0%) have expected count less than 5. The minimum expected count is 10.27. +b. Computed only for a 2x2 table diff --git a/rust/pspp/src/spv/testdata/legacy13.spv b/rust/pspp/src/spv/testdata/legacy13.spv new file mode 100644 index 0000000000000000000000000000000000000000..a76403f2a4c0e93b7641bbe6b78096e40111c9c7 GIT binary patch literal 5611 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

DV$+XLJ_|f zz!G*U+1Un(%X*6>)DbSxuiL|~Q~q>W1R1qf5YeJ@6t*g%Z=SH5z$_9tZ|0fbd_+G$ zxmy;nFZFq_{j;`ZOUp{8g@KZHx|CX4y9Z6l#xrBFwBVo$MG!Sc(3*dmU(yJ=dr=!*k6zXSZkAp+= zt6z4apAb~$)yC>B?aOzpSN$aXaFeog6owNZp83pgtXs+0%voY9*T)LG><6o<9tumB z7He795^#{yVPU^@7>Sb<^3--jfn(#~HaZ9oDCFcpO6(Xy!)3Hevei@a_9Io1mo^L z#X>@+MfrDW-@Uf{W0XYv+WaXj|4sIX_IvjCH<|pi;@^|A-zy^B*D8r%x&Qq)6@M4G z`)dCpL;L-G|4!Ne_kDzbJ=s%Sz+ZL#9`0Xi{IARZ4)=GJ|Lf&N@csh#e>DI9r{(YZ g{#WFTd*uJ5_Wuqa?Y>(80MPEgt$Sj3iGQ8`2g>fw#Q*>R literal 0 HcmV?d00001 diff --git a/rust/pspp/src/spv/testdata/legacy14.expected b/rust/pspp/src/spv/testdata/legacy14.expected new file mode 100644 index 0000000000..7494300d2e --- /dev/null +++ b/rust/pspp/src/spv/testdata/legacy14.expected @@ -0,0 +1,13 @@ + Frequencies + Frequency│Percent│Valid Percent│Cumulative Percent +──────────────────────────┼───────┼─────────────┼────────────────── +Valid Variable A 44│ 55.0│ 55.0│ 55.0 + ╶────────────────────┼───────┼─────────────┼────────────────── + Variable B 13│ 16.3│ 16.3│ 71.3 + ╶────────────────────┼───────┼─────────────┼────────────────── + Variable C 15│ 18.8│ 18.8│ 90.0 + ╶────────────────────┼───────┼─────────────┼────────────────── + Variable D 8│ 10.0│ 10.0│ 100.0 + ╶────────────────────┼───────┼─────────────┼────────────────── + Total 80│ 100.0│ 100.0│ +──────────────────────────┴───────┴─────────────┴────────────────── diff --git a/rust/pspp/src/spv/testdata/legacy14.spv b/rust/pspp/src/spv/testdata/legacy14.spv new file mode 100644 index 0000000000000000000000000000000000000000..023c1925c0d20a61aa77cf2011501d2d8bb7f694 GIT binary patch literal 3462 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 EAH$`Wi2wiq literal 0 HcmV?d00001 diff --git a/rust/pspp/src/spv/testdata/legacy15.expected b/rust/pspp/src/spv/testdata/legacy15.expected new file mode 100644 index 0000000000..ed45243119 --- /dev/null +++ b/rust/pspp/src/spv/testdata/legacy15.expected @@ -0,0 +1,10 @@ + Coefficients[a] +╭────────────┬────────────────────────────┬─────────────────────────┬──────┬────╮ +│ │ Unstandardized Coefficients│Standardized Coefficients│ │ │ +│ ├────────────┬───────────────┼─────────────────────────┤ │ │ +│Model │ B │ Std. Error │ Beta │ t │Sig.│ +├────────────┼────────────┼───────────────┼─────────────────────────┼──────┼────┤ +│1 (Constant)│ 59.146│ 18.854│ │ 3.137│.016│ +│ Variable A│ -.664│ .585│ -.395│-1.136│.293│ +╰────────────┴────────────┴───────────────┴─────────────────────────┴──────┴────╯ +a. Dependent Variable: A diff --git a/rust/pspp/src/spv/testdata/legacy15.spv b/rust/pspp/src/spv/testdata/legacy15.spv new file mode 100644 index 0000000000000000000000000000000000000000..63e0e66bbb8f288a5a6a6fee5449a05c83884f6c GIT binary patch literal 5306 zcma)=by$?!+Qvt^rMnws=opZOAti@SX@-y*kQ5{YM35Z13_wW%Ng2AOlo|yjWM~)! z#F09<_xJ6+zq8Ld-&yaq;{E4-)_UIey6)e440W+_r~v=~0bsf$&)N##nz`%x?Jhn5 zAOv6ri2l*+B_%~=q$Nb9B(7%(2^m?Cl(;?2!O_b_-2vtx>I#uBiBi z6?ag^O~rYtXDcgSl8ocAH-r{I%F2D(ui025OMJnnBG=lz3&t%Edn&^cVw}rNdmi_jM_3o zWfBYvc-f zvL`CCjrJ#r?Izs8(rsY%y)TS3p02HacHkIZRs&YdX6AA0tPTVoI^}#91AhjRiR#eL zNR8}sndG;loZ1HVZ=!MGw@4hv?h2${V$*Ow(8X3!QVsM@#ad!r-6VnMEKV7AhChc^ za)F%-S+%2Lqu+O?O!5_D+Gw40;vk%NkiatbeVaRk6x}lX=Zkzf5KnfFPcL!sAK;J- zQ4pxXl(n@Yaa+}xpU3XFeuX9IIKl0eBbDT$d7@2%V>^JI9i!PVRYwq}re!nhoL7uD zkf)OB6d-k9r=}y$e2e{j#TlT!TedTJlaJuOm*WLD>%N^L7+49CHvPKEka}ROENx6 zt|VV*8kk;`aRW&LPE;=&HxJNj_nx%bFp5zuQmX_k!`J?`Pg+uDb--(76&Bzp=&@oO ztwM{?^yY;1W|+rhh3Vj&dz1h0q#bXZ_)uW`!fb%V&jLn)Oiu`efRK-aWzN=Oyfi8(^D!O6@^LV5}8`Uo2X&L9w(q z`eJ@;i1{uoNv(;kdr%PLb;v?=grWFU&pF2s-%e4ro1Qh1!?qh>CluE>9A2+>j@v+x zyo`eRwd*tJuBAIHv;8Qj`K-7nsvZ4HG7jB+mPV#IatJ( zHZ{|=0YgPMehblaietp9c!Yl$Xo(SYwBp?P;+{lM;E|>=+2r{-*C5{tnaw+H!dr#1 z`OaD>;>M`J%3%*ib8~Coc3@(4OJCk-j3onOXO;XeBcKZ(^cx}jnb%EtGD_bIRw#d4>5Ogt(PB)U|So9Jg^_b)Ol!i zdop{l;?jl@2n7LolpczVT|U`34w(_7!I!1#sf<8w@diA)gL*O^tS_R$LT`ZtatsEtKCBd9L)1wnJaR{JbHD z+-`4FUk2$o>Ys|2-v8&6+Pv+78BtWUVHdV z!M(3oE-77vYB;ehR_x`TLhNUX7@}{aa0_~1k3f!2%Aph|@|fO+iOtD3qRaYbF`7(5 z@Mo}?{?E>E+~J^vuWX7VWPKynu9zO9c(P$3*gv2mKGyhE1h;phdGGPhIXP z&Fy#;KZd(4DO`;Dwts9Wmwv<)_6EPyAC#`9V^pb{Ro%L)HzRFzQxLsvn%wq9=Nq|q z=|U-3S8svTEJRraSM@Fin6lydz zIGh`5I>pGV+f2#Znr2-kytxDR<+=+ePP?3OZ#j0e>M-^mKmO$UfO77`T~?ry{)5RH z4n1-{_DsHUoS19}T?l5!M}$fhOuBBB zsT`%9&q`Tq;S|2tKClHTAWo~WA#);4;7^%)GmgXww?F?BODQ3-IU}^?if%@No??hE z3Iga3nze{R3pGmZgpCzsh}1Wf{LU5HPnTDZI+*l)5?x+ScR>sY`%aV!s&CKXKWm|!!Tfj2{R(BRO-gPKhH5ZFAo%5C~q71BzJ z36Cs6ggfI(9sb(tn1`6d#jI=NVs&B5)?T9M%%X8OXz3P9D+H!^aCnhgF(mv1| zb$^2pDz!EqYa#OGZYw-o^0gmf+D{67KC^3(DzmUL!L$!SC7V0+6zw3UK(_Cw_30wZ zs>HtYgD4l14lmJmBWz1o;3agCl2350tk08iDwb3D8hypy-he>Z=4_R|5{%HS{J<+s zntw-O&<$79vr-S-r(_(>7ObS(-8bFhN&5;_pUBv7gUM58Dj*AS!Y2e`Tk_B zGm1SZ)!m>Y@oLK>*dfy>8G1ei2~FADDWlQwwU47-3KnQHH@=O-2RJyF(pt&uFn)57 zCqK?pBmcg3`pP>3gNpn`s@G_G-IlL;{

d420LDss}bv0cz`Oi2R14PS>#htN#;< z{weY6N`TLo1Ejo`_|>WZDxs&MudM-wm{3rBx@bdDxZwL+YfkE%NDZu;#UH*jW zu4|ZXd0dx!j0*r@F#-UL*ZMwzFyBC!8Pw&zi~k?D579sHIr|!&bN-IcGnU>ypQXt! zi|jevyA(~~LL2>l-gK7rcX1bHE0XWci&AH*>#FmovkP>7ojcG%rZa!eXOeM;i=?I8 z&u)*OSTwqGwJ2Ub&a4XtF}3WOEz9Nf%X0{^w8RyK*q$z;cdLpWoSn%kB&2*Ls=*Vd zE7dP!jjMAu5FzLd9FaPkt8a~c^FZ&=BNJBdY#r|UkyLpUtaGcN0?X)If@G}y*2eHu zB>x6sSym}XQR1O-Rh_W9OV#nzfKIJ@a#BjlAQf1z7rR1|v^q{xHq!9z;$d1I>B4}P z$WxgC-Htcbg2qT7ZPM(skE`M*z3lF1k>T`ut0WskTz8;-j#^^y`FpRk*^?FY{N;TQ zc(fJ@5usn_ zZ{?yKELql!HT`5~inr3bW5}u$j`zU{Ev{z5Fi*23z_gh#DBb4MGljvktz9It*3D|^ zl^EQDP&>$-o46ZoBJ2?ivgA!}2_P|b*eZ$kp1?N(LymQddEcG{-UO?r&??aqm9%#K z6la|rI=|`=McDW%vy%Jv5qSwmo@Qsb^iv80v-J$$5{{Rt#w17wLhW2fwiYQ@1->X{ zL*b=MsYlD@y!D;cN=9vHPagzf(EOj!)NB$bBavMItMO$OaAitY4d1%scmF5 z>xtKB5Mm+uOE2?nrOy3=`!Po)5fLee@>Zzs)#3UeXJ>zA zk8m^g4?h-R@T2)mh>%`(Q?>fHevwHfHpP2wNk%4M$+uOxaO}}C$!HGeXRqw;#g^dk z?LTs;z#}TDt92SKjdzbWjmZ_jTcD_(D|o{FW6oxC#tmVZOrk|5;A{1D_q3kaHZF_V zWUeQOfMa9wRZmxnxk)eIgP|mHB#;Y`HYaXzt?{4ModJY zG8T0%Krqr#c%!s~VT2HOR-YU~RnqGP6p0^sOE`%TnT@bpZ7d-$Zem`#(=WnXLf^fm zKF_@o?6%sNTv;6wfK06_*K6jeZy2!34Q&@&$NRCPH;l1Ho`rp=4N~o}GVEb7{IqCm z^67S6>|jqlU9@6q>sNFoE-DULPY2jUmr=bVbEemyO3Mrp7SCTB`KTiorOGzGzNy(; zpNQ$-OwV|kYhWN6k|%fPga(FYOCC^3f9H$Yb^X#D-=96ewJM1*^RPj{I(D7OBKiu5 z>_XT=wnE;~VW(d0$d0T!%63*gHXYrQc+9 zIHLv5+!6Thf&AzFa)LKAJm#ubGr1>%Jjq)5&fb9;%WY~9nlD@@3^e=@u3JXK;^XK@ z*~XV3@iAyLZumM>xOl^z3MuW(hcnP$uF9sqLr>?jSoEY7*#c1$`-sLv0LpE`zZ5DZ zXXMvuq^=GJUUXdls7(-xX4@STzBBCzEL6mmZ~H#6b`GzQcQ~H)6zR(*Rnx#>!8g$r z=!Ax8JJvfGg((#0+AF;9lr?Nd;vP!G4`-iS8nF&&R%yq*GyHwp?VapIIJk-!NxvRs z#9l}mv%RrXG@4yItKyjp3D|3tMt*l}kyV`i$im;u*`wo=1&v4xWJe9?ge02UT9Quu zy!?43+uINcFx0()#fts!idXc1c;AbMzm|V`$$wMI!u`FJ^*3kyGveP1LBB`5aUJW$ zL*DD@zlr#}uU$v`7bT(J&-d@l{D03!4%kzfBnJG|+OOsQrLF(k{O@vqH}=17o{Hoz ua{tHX|Npf7-O~T69B{4tpA7z5|Cho4E$z5?zdj-E^|N)I*!Ev60{929v`mEn literal 0 HcmV?d00001 -- 2.30.2