From 5d5620561271f8ea69f3a6c04bbd7d2ed13bb8a6 Mon Sep 17 00:00:00 2001 From: Christian Schulzendorff Date: Mon, 23 Jun 2025 21:56:54 +0200 Subject: [PATCH] single x and y --- site_builder/.gitignore | 1 + site_builder/__pycache__/main.cpython-313.pyc | Bin 6654 -> 0 bytes ..._find_extrema.cpython-313-pytest-8.4.0.pyc | Bin 3806 -> 0 bytes ...d_geo_extrema.cpython-313-pytest-8.4.0.pyc | Bin 3754 -> 0 bytes .../test_main.cpython-313-pytest-8.4.0.pyc | Bin 912 -> 0 bytes .../__pycache__/test_main.cpython-313.pyc | Bin 4523 -> 0 bytes ...ain_unittests.cpython-313-pytest-8.4.0.pyc | Bin 5641 -> 0 bytes ...d_csv_to_dict.cpython-313-pytest-8.4.0.pyc | Bin 6375 -> 0 bytes ...translate_pos.cpython-313-pytest-8.4.0.pyc | Bin 5713 -> 0 bytes .../__pycache__/fields.cpython-313.pyc | Bin 0 -> 319 bytes site_builder/constants/fields.py | 9 ++ site_builder/main.py | 122 +++++++++++++++--- site_builder/test_find_geo_extrema.py | 12 +- site_builder/test_read_csv_to_dict.py | 6 +- 14 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 site_builder/.gitignore delete mode 100644 site_builder/__pycache__/main.cpython-313.pyc delete mode 100644 site_builder/__pycache__/test_find_extrema.cpython-313-pytest-8.4.0.pyc delete mode 100644 site_builder/__pycache__/test_find_geo_extrema.cpython-313-pytest-8.4.0.pyc delete mode 100644 site_builder/__pycache__/test_main.cpython-313-pytest-8.4.0.pyc delete mode 100644 site_builder/__pycache__/test_main.cpython-313.pyc delete mode 100644 site_builder/__pycache__/test_main_unittests.cpython-313-pytest-8.4.0.pyc delete mode 100644 site_builder/__pycache__/test_read_csv_to_dict.cpython-313-pytest-8.4.0.pyc delete mode 100644 site_builder/__pycache__/test_translate_pos.cpython-313-pytest-8.4.0.pyc create mode 100644 site_builder/constants/__pycache__/fields.cpython-313.pyc create mode 100644 site_builder/constants/fields.py diff --git a/site_builder/.gitignore b/site_builder/.gitignore new file mode 100644 index 0000000..225fc6f --- /dev/null +++ b/site_builder/.gitignore @@ -0,0 +1 @@ +/__pycache__ diff --git a/site_builder/__pycache__/main.cpython-313.pyc b/site_builder/__pycache__/main.cpython-313.pyc deleted file mode 100644 index 18fe0b894cccb09d6e213bb9f59213fa76afa6e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6654 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 U3zb!N$L~4*r=#$!Sj%w!ACq2Z%>V!Z diff --git a/site_builder/__pycache__/test_find_extrema.cpython-313-pytest-8.4.0.pyc b/site_builder/__pycache__/test_find_extrema.cpython-313-pytest-8.4.0.pyc deleted file mode 100644 index 311d4cf2f744be81624a30d6a71911299a52f5cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3806 zcmd5<%WoS+7@ygf-)Wmx^l8h4z6><(BWWolQBWyrixfnbNR@)L+S(Jx>OQR5b!j+R zfCLw$ULv)q2Tn-7ap2Er4{0f_rUwulB5tAP)Dzz~Yj2!VS~ax7tRXFe`bk+7Sg-warVu8%}? z$V0TGQw3Nib7Z!^wcBxC>1H5qQ-L|r1FZP`{;G^I?q4G%eMYE`U)vA`&bb}_9bBko zQX_3T(*_W#8`J`9EsCk~T)=oxt}OC;P`>Ot4y!S*++bdnIpv@pGV4;a?o=5shb#!K zg}PU@*wv6T*B)&wiR6T1yO*l=l-S#_!^)xsL5xl~e#LfzDab^P379LuC|cx)9UVxC z(4pg%E6a2TLPe$}?z*LJRGJ8x>&*~)?OpR|(?`l@Oxhfdwo-jWkmz#%pa zS#JG)*xqGQhRywm0xA+!iJC+mQ1{4u>^d925OEb5ftO*t`|^0yG(6?v@Z0AI@lRlw zXw`>=%;VZhn>Bj5^%P$0#GE=t&E&=5F=f2l*G$dh+DV(0BHPi&`etudbR1gORKkUfo0E6ubz-roGz(+CyZ13 z_6FGQ^V78jX>r43ZvlhVRc!bJ#i39ft3N{Hh%5Mt-`a$ui#ql{}AtUEB1r zGCA3%pA8>4+*mqV3W}4HMa&*A1;XGgXgZ-tva1bN30bwR2o-uE9Dh7y2OuV)>^%m( zp>nL9=C~jt+pioVJ>6K6dSY|2%>uD-EY2Fd;=2u-Gm(X6sXJlagGnPf5xcBl(Qi6c z+108!{w3S7Jlka=Wd-&E!x6;LyE2Bl@15n`=VH6H;B(gwL9`lDerp*cYqZ|`YbzNVzMm`H$rY}LcXRt&??2dbpmpv+X4^_8e_!kV?r8b1PsXJv zb8kc4%7#+Z<7X{@?PBZ&J^D&<^<6Fh3?0k%>ll4Oy;3%*SE|%2ZG&Fv16PKZ*DKvL z1|C(cJTIi8u@~r-VJ2d|N}8zw>s5M&gRB!!k6n;Nup4s{3YaS*#N^_yVeufsAq0Fb zejMN*blUfCbn98q&2I}xS9^j>TO{J9nLdcioi`+w!Su==|{HpMI;kvd$ g^M5J|J>5}>Qdq;>qjZKA9_>reLT86T3-ZAI8&`FZ)Bpeg diff --git a/site_builder/__pycache__/test_find_geo_extrema.cpython-313-pytest-8.4.0.pyc b/site_builder/__pycache__/test_find_geo_extrema.cpython-313-pytest-8.4.0.pyc deleted file mode 100644 index 4cb9a9634675b24f2593cbb6145cf1a504ec6d64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3754 zcmd5<&2Jk;6rb5If2V0$k$%}SfwnP%xTHx-p{YVeQCg%RvP6m$q}A4*I9B(=nq8NM zQv^tGLFy$^i+bRMOHK(3o9GPkdy| z4fYNc)klb_nCcm7YKO>V$IVlweu(h2X@Jg{3DDUZEhT?P|Llh)DiU@x^qT>z&`t;z zI{YD9(yoG9BlBdg*9&bZi%L`y$lFw4PK*F4{(FB_<{0;{k&-?uRL8Gv%L3=z2mdxM z)EcRg7M*Q@5~>^20`wNe`SN_gcu=k^^LkLe;yVtjF|XWUUX?lJpdK>oaWYb#3^Tc7v@So%~Tdwb9d5TR(pKp7w^E zumS=VOtdL&JO8~dY_spGu`*BlwD;NM?qF;Gc%^V1}p1nX4cHj zYbU6*^u@j1$LZODp>Esb5}s1;X3;Gfkd>zbdOYq)bh<=qE!*M;j|ANblmS?+6q^!VRVmN{rcw6RC_q_|8`&{g^mVEBoArM!?u{}EkPsGNQ1Py~bpK2rEjFR3!3GlB4a~R#0~v4Ttg5&>bl&xCLsJ z{F=;*p5Io+$QrBf{5ePlhVJJ^?&LhY77zrGMhL606QZoaGKpTcF?UM{20$XUuRIZKtCrETLZz3=Ss{G6qm zM&GlF+2@&!t!GR#EGSxGb1XUTfTlALf^!7dK}j@isft8U@_&sWql2Jl#17ddcBsS-+!cDxd$sRx z>GNX;F0*~lDn`Msv7?!Kj2*yHpRtpi<!+#GD<~G6=j(0VLTJV*`$Cg4RIE*L3 zvG2b)UP?KU#BT~b)A_5AqBv+pw}7$e;DwWUjI)n9e0+#h+$0j6HvS667*R-cu}Cb{ zuZ2y{f~A1uQnZaj-Q7%yjBOeU|TAs^k+goC!ggWkj$1r pl;jtMPYXA+b(;S}QRtbrN|eGD)*hxawD9mqf)?8Q4O)ljQ5WZ(SO=xKgEm8_BNd;0p5EpP#2{j0$G7zK=SdoxASZ?x~S~#|K&lRK- z0|RU<{0ROH0wmB|7?{|QvN3V**-pK2vhTjTclX`Bv*)X;%Rut<;NWzR>@Ve%ViaJ0 zi@-we88-lzCd@W}tCGV}QK(Iwv`O#0!E%FT_W87H+ zh)vJ(YD06EY0o-RchOSeYLu}HOI@v!tF)Z<)@L!jX?p_p(xJ`%8tuN#&NpuFq_exW zXtnz-1zlU%hBPUrlzYAw2*EMaXFXe}V9&0}LRcBAs zXag-JvgZtGWZ{fXF%-_rB#QWi$4<)QF^?P(X52qM3!^bdM_*wYgmEXG$*sam{V@jd zg!?Im35MAWH;G$)M=>Dv27aupf3}(*T&>>kf47?X^Tleub94CZ0)ADgi<||Zj5)D^ zU6&0tP8P;OURGOJc-Q@W$(?*Jw5Sg9S2PhVcoCBIB8KW;(4&3=yr%F5DcRVcCgZb+ aKg65l>RYT6_+v80egeFOIWV@R3;qGS%+l}x diff --git a/site_builder/__pycache__/test_main.cpython-313.pyc b/site_builder/__pycache__/test_main.cpython-313.pyc deleted file mode 100644 index 29d034f65ae0f5d5f3eea6ee41ea8355a0697cef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4523 zcmdT|&2JmW6`%bgm()_GtjMBd*+04@J`+auX~S0+dVNTYiY7sMS z%W)ysci4`HIOeB@p3&0QP0cQ8nS9z#*JnBpuHM+5hRPafM_a*8jtWVBm{1Wdq*77@ z=}Jl<-ANZnIq3%JNy^ll^Mt&t@0wxR3D{}Yx_Pbi7HspK8#JaH`f(c`{_srOGa%p{ z!A|qUzgNs22pb>&D%h*KPH(~sl*@V703SR*iti?4%VLea`uII6Pq zk(6anE0SKKc`Nd(QlVhv3^P(T%#2ZpSb5vf7AyHe#-I@!PNWs}ycsUvX7a^?UR=!R zGc0uAq+!djQ|0i*LMg2mtQn}(rutw<3vF2;_v~$Wg4s+&jZ7$%a?GQZXg;Swb)9FT zWfZdX2rj{csVeP(2a_D#Z19jx0fxjH1hGQCmHRh`PW&nGSzuNCsP}LEKUo$3Ak$tL zYkNtk+_{7>R9Y^9biD*_{}SMJ^0k*95*#~eA84R{6oAWivt`@R>06~+CL2Czd1K5u zEUsT6-+=M`gLh{>ndxpdLf*03glj~rO>P0YYNeayKrKEgB*mokhQJe(Pw|NcMH|cD znc}AEpi&9UK*V;GeOke|+%X7EQvgcC&r}_(Dmh6O@aCLyLulwX#Ry5de!+osgXB#q zMG^>*j`H5+eN78^c}_{-Tk0r5l4@!P(vwkgmW7R*}KQzI&)=Ds@U0c)9VQPQpR8|AemtsOg7APDU&yIA&H5oyDB-#tCFLg380<{ zpuavItxC=wRms@|hpJ3~ZPq;upjIqr^96$)jq61ta}Am$s?*z7uur;0fzwRN7An>f z6HS;w5lE~@x4;qDmp`cJ1;&>w=AuTibkkUOQS>3qoi3TSVcJZvi)GlPSk}tAy@b=O zO2LLBESHV6ZDcIOrs|X$Wsf_KqtokZi@KFhvvb|(0Dh+X^p`-jbq~Y}*%CS5*)4&1 z{5vw~J@&*m_LXn!FPYD${`&e?zT}rTez~a}xij~>xsP*?l#})PNAsJ5!*`cISzf)m z>n6R|xGk^jQJ)T+zQ6SKKxFmGKm60oKfNUhf!@`tTQc$WJyAv;DkJxP@?wPOLf#f?a@}I0iP5%`n&>c{a)WPDQvfP9Dccwa=O9E{XuY5` zMiNb0HhM7rrkeVmL&n)A8K0wZ-@+C$N^v?2+g_o^LDCTrA({RZ>&SijDvC2G5ajeM zigPH?+lNF4+H@Q{q9`UnI1virTSKqf9lby*`?luLEc&7l-d}^ZSr&*D^3*qQD0W-% zDmi$S#a6s-D*gsQ?IejY36H8ygrgIxia|tGoAKoU+G_!0qAKF_ zs)*C+DBLg&qId;G1jGTa96SWq%Qn?DtE{IDi%q^TvRhU;9J&Kru8_Yg;hKkb{QwUw zwIZGcX1*MJbMbwc{SsLU7G8xaQH=5ZREuv19Iyp+Ic>5a9puM*#fp zu6o}&H=H_8RI-2xrc+v>*BKNRnz>a1)7Xv@B&}=zYnJtHg9wM_Vdon&{+B(Qd6+9+ z?FXt%dL}0!4?CP8-j;X}g5&H51*X)Jo`jya0Pf!FdZA)mrnE$B;o?A~cny~~!$n7= zc%?g|@{rn53aOEnEzzQGv*{OQRp-iC*xgzKfy_Gn!mx9l{MXX#kVqAw-GQnU(0ywvpVG1&W3oG9hSg1b?w|UbRI^*`49{LGq5Fa9QO@5;{1C4MMihT sIgV5B$xi~Ihk?)z!PeGwo`}k7^=n~hQ&fKY&WG>(`dvVXIP4hvAAwGK&j0`b diff --git a/site_builder/__pycache__/test_main_unittests.cpython-313-pytest-8.4.0.pyc b/site_builder/__pycache__/test_main_unittests.cpython-313-pytest-8.4.0.pyc deleted file mode 100644 index 999de3c709fa3962bb61a0a2689969e9ba19c251..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5641 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 diff --git a/site_builder/__pycache__/test_translate_pos.cpython-313-pytest-8.4.0.pyc b/site_builder/__pycache__/test_translate_pos.cpython-313-pytest-8.4.0.pyc deleted file mode 100644 index 28bf5e3eeeb7109cb9eb40781d2b364da12a78fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5713 zcmeHL%}*Og6rWv>KNmtnqL7c0TBJ0w+5jdt#u%t0HEoniL}E*omP*#fUW}FXt~G0t z&?*vYEA`SV5{-Ju(cC!lXT+sIwLP>_D^=XmaLcLh&3@T{8k9s;BQe_f?R#(Dn|Yqu z{ds10J3C_p%0uzP`HV=&AE>y6I>IgkVVTH87Ct6S;CJyxz!c-;24%sx-4bFU-V$cv zFGACAxSja-J|c^9AS=l9EJ-_N7L|i%35&@gKuHb*cE}OH&a#k*?x5GyCkep{D+_gF z!BmTa-yaEr9Dur80$3(9WV*H0ah!!;WfxhHMHm?)pv0f=AK;mK{$-K~PFVrXD7R&S zW1fJzi_^7C%4AiTS_QBIRkLhjYutK&aK==bIar)$6?5>8p=oMa)dy>;UQ)F|vr<Tb*`q=i}MA@Vqjb|ii&1Vf?zj> zVK5WZSR!jDci~Q~AUNK=`|k-ejAIdmD1eUCz( zs#4KmnWUtB5<+p|%u4`E0~R5`E0`T$`=4Nam&vTxFzv0kXCgX0xjL-AEZgt;ErE#vH=s~cl zGoi8Tgc$cQF)SYmrFRLLb$ke!4%zlrglC%0gj0eXy!B~Hbo-M-vp8S8O!N24)$Dtp z_x$I;P2_`Yy^qX9-M-wr3LH8i z=vW1)BGdp>3N<(()b0Y)#HRjo`*4KM@;mq_tqRY?iHTL=OV)p>wwN4Fn6a;1DLxTL z(X)Zzn1&MOKpUyV9$Z4#RKk3Z$Bekbs4FBPCJ}oOpRhYkrV}Q^-?tjE0=2~8<&&$<*7n6J*qNM;fyH)mF3yeq4-Ehj6MuPt)^Q)2JEM#a#t zF=jC9L}AWgRi$1~@7FX%SL)ER8nYxE!Ol3@s$6MR(ydCSRms{ZIvph2v{ajR#n$X3 zk|S-}sEO+w_X=lX>(u@~hC)@j&&I(Q{mmx868Tf=+Ln5oQtx9rwo(Lmlm=+@1FUre zJeGP_ijDpaDFw>9$e}5XZByskK$n!K+QKFs``))TeGM9*L)!@=SBjqaDD8=jeotKM z_C#+Kh+7wJ^B&xyW3P_*;T1cO_~{E1e~=S@sEzo;uL1FgTL|lj_~EVb3y`%>{1K1% zqjKy&BYtU$oq~i|55j2#+|aNy2ndM?~sy z#Kr|*WS;1a0KZQg@hH1q1HBLLJv57;vXUzj>VoI1j7)Dd|Ns3USj9q_)8>4Rz0 zr;eyc9Whz@�rr-7~(OxA%-ov-$EImJn&;|Iyw}8A!v&bQit?6sfz&Qk4AQCym5s^b2vEhV* z1D<6Zt2YXm*9F_W2e)XJb4cQt6~Rw^c!Xu}d5KtO3ihFQz&HL*QPeMeDe0Toq^DDF|^!_c1LUuPm#Pd&3dKwXh+|!sSj3SKh J0@!D@e*j@au%G|{ diff --git a/site_builder/constants/__pycache__/fields.cpython-313.pyc b/site_builder/constants/__pycache__/fields.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa25e32f5fb8ff5a3813d2200f122549114e5e01 GIT binary patch literal 319 zcmXxeF;2rU6b4{Bwquv7Fd%Ng(gAz{KmuB%psKBKkYGa4m^P|Os^@lK3y0tk+$i#d z#FPyw7r>_QhR@G_`k&nPdOOJ1^+mc^`tvJX{tN##?V)epkwSnJ2CO286ak_rP{n|$ z7-GeN&qcq}gh&&DO%xyj8eoAqz&+!>a8WXF^ePz*9T`o=p7YePG)etKcQ90!H_0?j z{D4j;>h9P357hcFa;NgvYOr#)fZWPuX^fuhLaua?X(MgE)(=mc++-T$tSs#Mu~=LA zoNJTW90d*t~h7~@YCS5eJHMeCSXWQ*ujtlr(Ly4wL4Zxr@@ F;s@4SQcVB= literal 0 HcmV?d00001 diff --git a/site_builder/constants/fields.py b/site_builder/constants/fields.py new file mode 100644 index 0000000..582abc7 --- /dev/null +++ b/site_builder/constants/fields.py @@ -0,0 +1,9 @@ +# Field position for data items +ID = 0 +FILE = 1 +LON = 2 +LAT = 3 +TITLE = 4 +DESCRIPTION = 5 +POSX = 6 +POSY = 7 \ No newline at end of file diff --git a/site_builder/main.py b/site_builder/main.py index 4a58d27..4b1f515 100644 --- a/site_builder/main.py +++ b/site_builder/main.py @@ -2,15 +2,19 @@ import argparse import csv import os.path as path import re +import constants.fields as F importdir = 'images' datafile = path.join(importdir, 'gps.csv') args = None -# Imported data with appended attributes as list of lists -# Items: +# Based on imported CSV and added with attributes: +# data with appended attributes as list of lists. +# Items ---> See constants/fields.py <--- +# - ID # - Image file name -# - lon, lat +# - lon +# - lat # - title, description # - x, y: Default tile position data = None @@ -47,8 +51,15 @@ def exit_with_error(message): def read_csv_to_dict(csv_file): """ - Reads a CSV file and returns a list of dictionaries, one per row. - Assumes the first row contains headers. + Reads a tab-separated CSV file and returns a list of dictionaries, one per row + in the full data item size. Placeholder for unfilled fields is None. + Fields: + 0: ID (integer), ascending starting with '1' <-- not in CSV + 1: image file name (string) + 2: latitude and longitude (floats), separated by space. + 3. title (string) + 4. description (string) + The items must be sorted chronologically. Assumes the first row contains headers. In error case, returns None """ global message @@ -57,6 +68,7 @@ def read_csv_to_dict(csv_file): reader = csv.reader(f, skipinitialspace=False, delimiter='\t') log(f"Read lines from {csv_file}") + id = 0 for row in reader: logvv(f"Processing row: {row}") @@ -74,9 +86,21 @@ def read_csv_to_dict(csv_file): if len(geo) != 2: message = f'Invalid loc/lon: {row[1]}' - values = [ row[0], float(geo[0]), float(geo[1]), row[2], row[3] ] + id += 1 + # Order and size must match constants.fields + # values = [id, row[0], float(geo[0]), float(geo[1]), row[2], row[3] ] + values = [] + values.insert(F.ID, id) + values.insert(F.FILE, row[0]) + values.insert(F.LON, float(geo[0])) + values.insert(F.LAT, float(geo[1])) + values.insert(F.TITLE, row[2]) + values.insert(F.DESCRIPTION, row[3]) + values.insert(F.POSX, None) + values.insert(F.POSY, None) data.append(values) - logvv(f"Read row : {values}") + + logvv(f"Processed item : {values}") if len(data) == 0: message = f'Empty file: {csv_file}' @@ -117,18 +141,18 @@ def find_geo_extrema(data): if len(data) == 0: return None - lonmin = lonmax = data[0][1] - latmin = latmax = data[0][2] + lonmin = lonmax = data[0][F.LON] + latmin = latmax = data[0][F.LAT] for entry in data[1:]: - if entry[1] < lonmin: - lonmin = entry[1] - if entry[1] > lonmax: - lonmax = entry[1] - if entry[2] < latmin: - latmin = entry[2] - if entry[2] > latmax: - latmax = entry[2] + if entry[F.LON] < lonmin: + lonmin = entry[F.LON] + if entry[F.LON] > lonmax: + lonmax = entry[F.LON] + if entry[F.LAT] < latmin: + latmin = entry[F.LAT] + if entry[F.LAT] > latmax: + latmax = entry[F.LAT] return (lonmin, lonmax, latmin, latmax) @@ -138,6 +162,7 @@ def translate_pos(min, max, pos, size): return round((pos - min) / (max - min) * size) + def append_tile_pos(data, geo_extrema, matrixdims): """ Adds two columns with x and y position (integer) of the tile in the canvas @@ -157,10 +182,73 @@ def append_tile_pos(data, geo_extrema, matrixdims): return ret + +def create_playbook(data): + """ + Returns list of dict [delta1, delta2, ...] with changes (in both direections) for every single tour. + The snapshot holds the complete canvas for the actual step. The playbook contains exclusively + changed values (delta). + Rules to process: + - Loop over all n data items: start with the first (oldest) item (0) + - Copy previous snapshot (to find changes in a later step) + - Run recursively over the the snapshot items: Find an existing item at the position + of the actual image and change its position by the displacement rule. + - Place the image of the actual item (a) at its default position in the snapshot + - Create a item for the following image (a+1) and hide it (for scrolling backwards). + - Store all changes betweeen snapshot and previous snapshot in a new delta (a) and append it + to the return dict. + In error case, None will be returned. + """ + + snapshot = prev_snapshot = [] + ret = [] + + for a in data: + prev_snapshot = snapshot + + (x, y) = (a[F.POSX], a[F.POSY]) + + snapshot = shifting_snapshot_items(x,y, snapshot) + + return ret + +def shifting_snapshot_items(x, y, snapshot): + """ + Recursive change item chain starting with item at position x,y. + Returns updated snapshot + """ + + goon = True + (actx, acty) = (x, y) + ret = snapshot + + while goon: + goon = False + for i, item in enumerate(ret): + if (item[F.POSX], item[F.POSY]) == (actx, acty): + # ret[i][F.POSX], ret[i][F.POSY] = + goon = True + + + + return ret + +def shifting(tup, matrixdims): + """Strategy to shift. Above and on the horizontal middle line, the position + will be shifted to the top. Positions below the horizontal middle line, + the position will be shifted in bottom direction. + Returns the offset as (x, y) tuple, not the new position itself. + """ + + + + + def calculate_orig_pos(): global data geo_extrema = find_geo_extrema(data) data = append_tile_pos(data, geo_extrema, matrixdims) + playbook = create_playbook(data) def main(): diff --git a/site_builder/test_find_geo_extrema.py b/site_builder/test_find_geo_extrema.py index 3596b64..6b0a09c 100644 --- a/site_builder/test_find_geo_extrema.py +++ b/site_builder/test_find_geo_extrema.py @@ -10,11 +10,11 @@ def patch_log(monkeypatch): def test_find_geo_extrama_simpple(): data = [ - ['dummy', 50.1, 8.1 ], - ['dummy', 50.2, 8.2 ], - ['dummy', 50.3, 8.4 ], - ['dummy', 49.3, 8.4 ], - ['dummy', 49.3, 7.4 ] + [0, 'dummy', 50.1, 8.1 ], + [1, 'dummy', 50.2, 8.2 ], + [2, 'dummy', 50.3, 8.4 ], + [3, 'dummy', 49.3, 8.4 ], + [4, 'dummy', 49.3, 7.4 ] ] result = main.find_geo_extrema(data) @@ -24,7 +24,7 @@ def test_find_geo_extrama_simpple(): def test_find_geo_extrama_single(): data = [ - ['dummy', 50.1, 8.1 ] + [0, 'dummy', 50.1, 8.1 ] ] result = main.find_geo_extrema(data) diff --git a/site_builder/test_read_csv_to_dict.py b/site_builder/test_read_csv_to_dict.py index a3732d5..85a3579 100644 --- a/site_builder/test_read_csv_to_dict.py +++ b/site_builder/test_read_csv_to_dict.py @@ -18,8 +18,8 @@ def test_read_csv_to_dict_basic(tmp_path): result = main.read_csv_to_dict(str(file_path)) expected = [ - ['img1', 12.34, 56.78, 'foo', 'bar'], - ['img2', 90.12, 34.56, 'baz', 'qux'], + [1, 'img1', 12.34, 56.78, 'foo', 'bar', None, None], + [2, 'img2', 90.12, 34.56, 'baz', 'qux', None, None], ] assert result == expected @@ -39,7 +39,7 @@ def test_read_csv_to_dict_extra_spaces(tmp_path): file_path.write_text(content, encoding="utf-8") result = main.read_csv_to_dict(str(file_path)) - expected = [['img3', 3.23, 4.56, 'foo', 'bar']] + expected = [[1, 'img3', 3.23, 4.56, 'foo', 'bar', None, None]] assert result == expected