From f329d30a385de589f18646d1a8acfbf55cb47df7 Mon Sep 17 00:00:00 2001 From: Miguel Date: Wed, 31 Jul 2024 16:54:44 +0200 Subject: [PATCH] Creado paso 3.5 --- data/bak/1_hmi_master_translates - copia.xlsx | Bin 0 -> 39909 bytes .../2_master_export2translate - copia.xlsx | Bin ...r_export2translate_translated - copia.xlsx | Bin funciones_comunes/__init__.py | 1 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 334 bytes funciones_comunes/funciones_base.py | 44 +++++++++++ x2_master_export2translate.py | 10 +-- x3.5_integrate_translates.py | 74 ++++++++++++++++++ x3_llm_translate_text.py | 52 ++---------- 9 files changed, 128 insertions(+), 53 deletions(-) create mode 100644 data/bak/1_hmi_master_translates - copia.xlsx rename data/{ => bak}/2_master_export2translate - copia.xlsx (100%) rename data/{ => bak}/3_master_export2translate_translated - copia.xlsx (100%) create mode 100644 funciones_comunes/__init__.py create mode 100644 funciones_comunes/__pycache__/__init__.cpython-310.pyc create mode 100644 funciones_comunes/funciones_base.py create mode 100644 x3.5_integrate_translates.py diff --git a/data/bak/1_hmi_master_translates - copia.xlsx b/data/bak/1_hmi_master_translates - copia.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7c3e8633aa4e99dbf69ff03130a0c1b80180c99b GIT binary patch literal 39909 zcmZ5|c_5Ts`|vErU@&9fnGr&TR+44LQe+!ZcuFWrB_vzcF?LF#LdyPF%i3b!3y+FI z$i5_o?2L7M_dVnJz3=<|(da(s+Rk;Z^_+W#XaHy8g+L%Iz&}mM#`zqaDHH;UWr9F> zfRW4EF3#=_&h9qm4_qDYTPt|qb$au(-MC2!qf6D>(VjeVey|kJa`F$kg5Ol5hl@&QZ&|n{n{iqN?C*&fnh2YQH{6 zYF`+Z6;OM64Iz8BsXe;Eo)3C_e%&(ah3v3?WM$Y{J1$A@LUY{7sEw0G4(2}D+1MiA z8j-x#FyixRbGuE@s^9DL(%qtwm1f>1)OHsvYj*=FfWS#aF^EvpK?r zlpfd{=-JyPJW#wG&a@ZqLe2f75m)Zced`y*M4azB%%PY$?GxXfF1Y>p9_x<|THDUo zDahi1tbSjXvisQn&gp4Q_uDpvp{s|il+PIyYseJ<(AZ4*W>pnHD7R5+x8o* z#Q)g=qMvaC1<<@93<5y`e{I|xobD?sfS+&TzMO|2#gG=r3z(_lFYn0_Ck70-e0cKE zN-|}db22<}rXO5fFuaG}t&SdzPjaahx>1v~n>8%^D=0X~;bL%xZ9hl)@x|&u%fX<3 z$PHu7LF}TkP1zN-e`$UTxe(>1+5DPK+8$n`SKX^RkfJsfbs%)P%WYZqSCXpOx0t>s zS9{jp7;6f3iXQFxDx`Pj1JgTAoyw3ech6YC?`*V{>vp%pI|w>#HdT<(Boxv!yy+kkEAEQHd6`+Sd_ zIr8_@)`}3V!n<2gt-mhIyq9`AkVV^$3d!aS=?pfxc6RP_@X#-c@AOA;9*>4Yxl!Cq zK0HppFC$V1K7NSKn;qSk1mN zcGOh)bwBxn;U62p2lwu+q5oGy{*(#l3QY(ka2g5`WM~M~&3#7)2lxAm^gl;IB|UmI zR4Co@?BxQ-h8WB6Wwp&zIijecqMfacpwf=lh$LE9ODcJKUZ~$?!Rh+}a~*T@^;fx; zuMTw#S7qdvj<;`ZrP4Y&H2s%ciWW3?Hs%vF{gY^m%fAGQ>io9nt0V$9XH#o;Z1z@c zXk9zY(P)Vg+Vapq>hSLJR*vG{!fd$W-c0h|hD0rGyNVjPz1TE6+oHJ6Qs=kPm7wXj zvoR}Cw?%3Cpjl1ZS#OdU-rd@2zf>DYrTzXOK@F_ko3)S#@ZZ~7uNt9!1EhFnb9Ku? zvu<}OK`~Hb?D2x;&4*qifqN4liUI?uf9hyETkS0)$On5{T?3DOX%Yb&OTB2DfR!~b zP3J#d600A#dl&Xre`)4up7qgRX)mhX-1;!Jx82fP7g)Ztpr}#1+rH<$JF_s>9+XqM~db-Sy9w3VDas`A~vc9X#RI{%gB zHH*FXmjkx<4h=i%Hb!+u?L3Yu@}veD;zo>dHZ;5RDfC~1cRGs)PaRGOw9Fd|=C?TV zZq03^YNpsKV^3F3492f#r^!k*S<}qXz@zrh03g2NVQfY-J>Vsh{~pBL-B^W}Cy8 zP%&T5@le(upZ|2WUg8+lxGx!fxZ8ihcTdmafZiN7x7J>xo=B}(cq0{busA7gEA9+c zA+>jV_yV^NoLboD>$w?23Ojyw>TttyPjFw-h`oDp=h#j_3k9f6dbQXDN+4{1W@5mX;S|7}rmE?0LUq<;a3>~r&i?H5&WOi@T zH}D^e$95h5@k>7WtqTbXxq~(y3#OZt<2xu|>_z_KJ0#_9QeD;Hwt0mQ$DY=R3g5X} zuM9U29@=h=oVV`9jr{Cb0ij++>Q(d6A5k^AqkI>~3WU42qwmqKIe#sTX&m{HtQF9F z4oTVl=s!gbFb9TGXZ8iD$-OcZqS>MR__hk)_V6~b!iP2R`M+vNck_7BsIi(GW>&IL zWALn?gV!^UA-`Du74_^=ZT0*y^DFnuy>fikQvaFX2lVPG*fw7;WB~dXTz!>O>T+@U z2+iSQCC`aom$l&!@~=fpTtM8pJN(ZJYt0;PMHZ%SSUjp+Yxh~Wyhc%f=3g*=GH$2T zbU|^xs+L*^k{`afq(BTD+FkJ(*|wTVmPB8y{yLtiNL)~yV(*`S_1bzUwY;~;8=R&;heYX>}GFmkUKl~NA;P{84|48i3lgy=l)LP2J%y+)$ z?pT=Io^yPB`^0LQ{m$$E5dJM26Xs*`>D$km%y$I`Jv`rr#e9kp$feqgz8N|57eM*u zx!GyQIqx7JlX;;pHJNL4pmQfxx2%o@{8-q1ZKIx7ma3lr?OVqn+wD4PS%62@*MJ}2 zI{JRW*XA#oZr7xODC=c0y^iA(xn3XQelCc;Y06add{9;(UeNV;w0O;7L-zv_eGcR2#ySH$2 zf}$6^J7@YR$ocuB0p1y^^Se%00Gw2g>WQbv4^oESRK)n6 z6R|K6o^uQqebn(Xm+B;Xcks;5a-Z+E=X@D%_vKU16XvS^`q|?enMg{F;6X8Jz$t89 zeZZ;Cj*W-n09|1fFGeGKyAr-~F#^f$>o5VR36T2=yL4=^1HOiQ8T>t3jRewhQ% zFp9Wc5^hv26Mx6F=(-EfdZp^Or{w}yp9fmD9Mjj7wH6S~e4Re&K5@?u%PdYu^`secRW| zza?yQ2niqs{nya*D;$}_1xqU)3wKZ#UeDdRBd&3O_1$eXk0hx>stNX1rc=>t0GaFg zzP9n6x+~wS4^jLY#LYVk3?^$5TW3*!|K$Libd5v$;iB(I0h{}&B}a@ z;PUA@wetpSl@~8Vs=Sh81`IfY18?1Bc<|N=eR*lh31t7HNBaaS|B7c#``WukK-5&I zP@>x!Yh&NFF%c8mz2v9Ac#nwxG=%ILNtV1eSQkP09A_@y%S(d1cxiuKKf&Mu08u^) zLOe7)wwqPA$QMW?xO`=`o=+w3jfe2=_OjZ7&v!Q@9?r?o_HvOkHKz}_Lm)Rc_@G#3 z(tu`4DpPH86cf!d(gyw)qT!6(qUTg3}t)t`Ni3Lm0dcWF!c|w>t0F zc@!!*Yavf6hSYMPa6=_Op#pkd8*)IowuSRg*C% zAE`R&J3+w0;t7S--pdILnfdIDfl-k()IgiIV{}n6nFch?d;I4mK0e z->U{ZWrW-$aXZ*KfR#6|d8c)NtdO514vK>y7z4YP_&zang1v(V!l1r8EXn4kogu0VeU-$?ZwRzN_-7fs$#kMMc9TS?96+sta3&;xKC>-%Vr zeW)WEs)D2V9MkbvAs-dO9N;p*osFn`eHFpS9)46t`?{2td^5`#p>$`PZjJje=M|~H zh5>))qAc_Bs~Oe{;u`p_h2)OBHnD4HVtUBMZ3ki>wngxPlXeFs=&&$8^r&$dbB|u@ zWtP{3%Gb6Cw5=vo+es=!A*3H`eW{p?T;x$Y8!;J563J?3yR-=5oHYs?(u=TRsbPSR zYCQ!)!f{kvm3WqEk;2YrXN@|lhzdIlfc|$az9}+}`ljdc@ zjb)Ps7a;+#PpnAcBw(4PWIi=gD(RjUuj3s9`3__7l%ay{^Cdg zh<%D>SB%4KVy=a(+MDHv0S@ZH!l&g^iZgHWm(o!V*}5cv7$(I;s`a{v&^9k zspKkXg$Ib|F3_C29GdRg*DIB}(gAjdJgb=}TJd)F4S*nNwcAxk5;;CTfi|{k-D7aP zY$6hI03Q4VG0x!lKIjztIcBBI|uh*BwrLI2gB z5a|G%^aL@=K;P+rhze~)ABMCL(A{0GBEI%bF7~5}rHdj-8yx+Hp=@CTLkC0vlt2Kb zmC3vHs|*@(0y;sex3Pz+9D|E*@#vu5p2_%c5KcjJTjj1c=FwIL5LCQW=%Y5&s6G+9 zC}0JNF(if0u`dzvJW2`?icT03d`-%vV>}&laP;aH$;G*|R|A`h14l?Qwtlf!7qJ=< zeqn0rD0x9=<)= z{Y~H~b|6-C@JZ0!@)$IKy5eQLC+@W80eF?GkVIeb;W-#Z?)0ex@MKpp2~Jl#o?|7f zF*U6u@hdGY$|bE!(T)T+M{VY}qpBLBb!2{fEtF_wY>+5Gs--9vp418zi0=3(S{FOp z0b{m@!LLx%1@7-?IcXZqYnsiEg#NsLv_&y%xvY8X_{S~l8}!L(4TIa7X17Olzk`$Z zl(LZJVFyf!G$nKkZ%{PJ1sBYBE7sR@7n+{N6j+X(Sx|Gnj zQ!w90_L6Ht+)GxHYe|x8T7O+9lo_0qF-^r`Ql(8(LVyQlzxjq1KCTKH> z2Ly=h;LbazKGP+yP+Uid&+7mN;_^D4<_Y{r0gS3bDcR6JOwaGRp?|hvP4T+9(%>m_ zzdhx+&UhK{=|Bm6mqQ*~=l(2XmWty}l{QP2GYeedd)l$X_K-^pXp6Ho%(7`yJh`cx ztmOiIL0spvX=&lTc{NJ}KvY1S^WE(?kO0-fsD3HRai;MyDGHkI*#aRde$UnXv(;+m z-r*5Vf94X6QZ%$hH4IWT%u=qVBwc859XN9%KBof{-VvA6@iZqPCmWz6{=QL=@BaowP5LZjl#1g>l{N~bha(lN{a9JZjHyZgl5oHMuj4vH zW%j@5s8tE>n-U%x4z|E8Ma1X5}LA1aQ?!OQE1lw=S`*AAcd z>hAhdcGm`UMdp8>o9NFP|M%PlKD)YzF&}*T@(g8WYU$Lk!6EUA{>j1P&D~{_gJ>W7 zsER6ox3b8Jn|gUSBf;gQ6kQMUw>o#~D3x7q?eI~M4crre`r`9nP?M~F#0J;owHrM5 zJ7O<%aNj?t-o~>5|)*gsgg{D)<{S`Zot8D+yx*XD&TP^_-a=N^0jlK}SeMooY7 z;PI^PvgScklVv6iAh!s*|Nn@dJ&nK$C&3lcfp#F>BZ4^KnQ4e&03soRzRwf43Fsm- z-|OU9w~jdSP3wU(K=MF^VEmrPs!{aEx#(ezpG9u-u$)hK{NzD0TUhkcO`ft2One7- z**SIndPyKRUOdk8wgdCDgZnKo0y_Z6Qd^<5pc4o29NBy0zZzaChp(k!qCZKQ4n zb_RP4(1!QenkS>1=jclqsj>-r>i6X7F5$73oNvOtBQg#)SZNz6hsQo~tLDJo47?TK zDO1G6E7C=+mInmmo4w|?j&NJnbz9Fp*k%J%MAXr@iD~{pX?{=A)G2aRy!Vb0wqS$} zNrF$endj`Sk4(Q%OheI3zW`5AH$N=HVuNkHD#h~H=b!nKyGIFB*y%M%f)@bVAr;+L zA`p=-&{jfUhB7A{w<;;O&Pc+xSn^e=rT|8!M=^CqOZAzW#KoZGi<5n_hC)vIIv82QxTH>&k~cIm;PL?$9dpsmpNRhaTurnVKywp9l4a%|#N zsq(ASAK|6e9Kec-%M$H2R*!!jnpjtgo(sSNj%w0upf5p`)C{?K@Q2@ys@m?UZ zR=}r(UOym8D zTw9f$>_lZaZ^Unb$OVAP6=8EF(Nwd~$xyaQYV_pxesBu*4t%n)$FR+Nu{1?3q$p?_ z%A72&crNczpftFp;+>yp0plehqv{c0ak4ukRA0@N2Dw6H(og{u>EtquB$Cu+8)X=% z!^lYjm-`qa%4&>qMv+i}ijDs~T7h~HnJ$AUw_W_uX~B}+jSRVcNus=V{6t{ihZMr} zWl6lecHH1owF2{LSv)&0ffIa6RtS@og)s5r*oY?F<$%k^v>*QeMmPumXXG)c$dZE) zSQG}4dysXo1uQNEc_C2U2y(D^C1@~HjRZy^0|;fVhhWRk0!9OVW7IP0C}(? zWC}vc!g$kCm>xug!(Ni0Y;60qv1q!(%dp__fF{?ZTD6HmL*b=@S!ob1B9k0mUGDoL zz3^et!*gW;0G-;vjx+fmB@&>HX)NYM7I{o=5L=k`Ty#1o8xgLX3-6A%MH3L7hdQs7 z2g3#lPsFxNP5x0=;{_r=8s<$5xx!e$6-;rk?K5qimcXQUP=B{>bYj} zKvRa`wRDIpF~m}qNora#)^o}$`3kT0VO|Jl6lUKD_Mpzh5DUD&3qBO~lE6iTt|hNu0u;MTIwnh& zOAF{7p6MR;mQZ5W#r{j=H@q>8C4S@wetT>HSEbx))O9|A0=fn7eJBnle7X7 z{A$kFLQS4lejOV>AP+a+Xdy>_I!r!`RzQRz)#dNjEtJ>a25i(E&v$#25mir-nDg<7 zXKAqhRKQz&)xA%46A<}nY#y%kaBV4qM_x<|VeGD2XQjAe+QP8 z#^y$3Jw1wOr+fc>7{DN&7^y!h%^2_n2i_7{|8hMP(4)l47fY5m)RLa8KO%oISkxTL zoR395i-mv4y})5ggtFvn@rthIGVzvE*Du0(%^|RS2oPbxP+12-6A`k&RBN0ZP_E8zO|s913iH>6jrg$p6L#jtfL6Yc3h! z0LF6~lOCQgiyqG_hotfeZ1Py>MKDYOz2!WUQ!JT{F(2MrQuE)Fnj@Q!?bzg%pcfPO zfp?tJ$ZSMBUoK-)?`e`?z^3LN?EfQ|Yy0!!(O^FFdRV?KFj8f0c5)DpP)K7_CPs=B zqa?ya=oZS%&?Xh;lm?t3upTO&6=pt^i$|C@u*usY)~CJ^;e1+q7juKocav&PpCIBx z4FmaP_t^>Pty&OZ^3pVi;3ax^7l;4{fORLE(}P_DKC6z6hbXtKXmS^<#WqkYq}eVv>5#M<+Mdq9TX?sMHW60XyFQF~q(BzIJTrQJe* zKms^<*n2R)ebR25&1zHL4k+`$@b&;JXCr+ZC?Ysk$ZXjI!gVil{X?_-p5>}j^iO?8 z$tODB*}0vu&X=)#F#{;w`jr#`rQGb0ak9Z3wvl!M5XIKWY&YCKl*>5V;1q16oge$i z2l!pLiw!S|%VAVj?Ci^n7nfHVl~qcumU!*?6!A4F5l&{lzCWG?`rQ_K%@#lxm|}mf zF^zny2_a)UJj~4np45jcRlQ!g&wiqiI#d6z7Utn}k zeIioh1yU4Klga~9d>g;v{~=WBt8t0vMG?lQi2KDkb!+9&tffbRg#4QG^5SduRHxT6 zYgchSSEbitd`gp#U5fW9iv6o7&IjDNhvrImt6L_A4>kWNm>f1W@wEAL``RDA3o{q5 z{Q<0c>DtM>HMYDJ`89X&S5uSTM*_F}CLkF0BJRTga23-{@&q4w%!oXZn=?La)NSZmO;D=VcNJZ8 zA3F8qQ=J!yxne=4;a+!_hlP&t9u49WJL?>WI;Y-mgi2-&P-byfW(~+pi5mD`nPl%3 zZ0{LwuT04+Kk_Cy(pfp;s&b?=Xagd}6-ypZC#2biHayj`UKFxTzfJMb~+qaxC-AoXm_fVCI)fl2$!~S3TlaPXY9)bEkMZ zoMQ`}xjQuI#oP{}vB#*fA2jM3ymzJk#!tWs?+LJ+Q)aaQYv?K1*l(G!TSZ-qpUz+h z2c<;)8J#aOBsn=GlTnF|keu$vJFPNupa|x!GxsBqxRXo9H;#-iMj782fpHeUTA_bp zi=I#JiRqnH);DHYNFh_hj7-CAkjFEuz>t&$u+lfKdG)oiWl8oP!M5)4_V0Rcc~4x% z_&UcWpH-i^R0TL_$sM;Y4!3VcZe4(LJ0-AXYx+F$BDhxS7Ynat4g9&#u-Z~|Pf_oZ zvi{Y~6!#`;`NVaWQ{U#8zfokqId#W7R~R6=#G7Q2hp?B2q>}yVXL(|iGB4@RFB!|U z6qG7R)+u8wGdkGTBi{BDMgN0ZHhG5s>Wj!5$^iMu8^AXD=D8hjn`LgBk!icr9q$w+ zYOeIA?Zuo&@SJ=6+)0YQrx7RMoxgID7CnL&-QyS62#?Q>-T82=+i;_j0IGe9ev)^l zEpgQ&c-1|A6$F^MQ&npJy_e&Am(llLz@2}n0`C0xL7qBiOsX??-C6av_df^-G>?)v za&txo3M|U$j+ptP5_G~1Q|!!LzYow=_%$iSGnmOUJ_Iy@yA{d$j>>wL%KDCg6Aw^; zO9IW#a#8!@Wc#;3h`Q^s0nM#Ddb-t7xy=<&oW*TGaca(5!yHx z41ky_eN43}=E{0#Hh5W)8jSUdm-5b(DxX6cflE8fLYSA)Up%Yt+Ar{eOaJY1@H0wk(}W2#7&Y7jxxNK?*(D8?-M3jhiba9Y-7WQVcSLsGJgrm`G6S)I)E zald~GdFmCPxWTYm5(ehN%?%t*6#gP0x`sPm2tEi-^o|$YWK0KQcwD%T0|6#`+FVI& zX3(&+nn0}9?*x`QkYU!~u4r;c=Jqi5{IJyR7@zNtz5!wIx1Y?zVXVQh)Wc!fI|>6` z7aE!l+U}qmCyg4X0VS%b1ABS!iOi#6?A>9hM*(#68*)u9_X#e45MRDU=L?($oN|e~ zq&Xer^CD*5S*DNdUa~mqJZEc!b2vVz(-DYyIpk&t2B99o0OiZml!_-w4-*7eh6AB}pfI zgHQOxp8!s5hHWtBN<#&_$!%rIt(nSgWdJV@WKkL5 z60ws#$&>vezxp=?IRLlmh`0e;;DG%xf-Pi?hz5CcIrbhf!qyT-YxJ?Trq~p9$=v$O zB>m6IddgAJLW{j3AQDU3)N?`Iu}teNDjKMWgK2`=`JSE2z$C-w2j5G1iU zAXq6Nz8Dw)4tys3F&|yxelgNwH9Bs~C~jxJ8z#io>37zdcG`Ge_XAtW+2E`|0q!&| zR;;WDpCR?ds53E$Qx-2^p2j1ORT2TrbaZ$}wHRh?$>=VrQ@v2>X|k}p7RThzV79r6 z91;F>_?^yBU3w1}=n^PK3{l9XSG?Q4)LFcwJ5GpRdI9G-NX~RrE4}Qd4ezQFS*(@9 zj0JP-WgP_H=P6@F=Im*R zfqRe~{RSg>Hrm-Sn)9uWz)t|BD0dl744iN!8MrqbA(||67Nn79-uuonmrp|s-JuGM z5)#g2n}Kq@M=$Up0%D{{h5C;SqbJd!07O^`y;6rW*=L~Kf_zF9A+uq5)Afe#cJf4% zbq<>$JfB!%gaT3bU~c1MmpRtNi23o#Atf%c*f0e{;1Ux&v{QhbaK}mR_W;nB=_oYF zvU}JPRnKni7!fS~%9iEB69;7_9pv+L6#Ko-Odiy?!N(oN7%|H*g~QE+$Hs?s?$>EF zX}Q}9RTg7_^F?(VVuRB>^`>J4=Lu~AVQ|GGndF&Ml9aIUY0`1`F`ViWru5k%K0^T; zaH#$aFvPg&SxFv~RvqQE_GbMq{bm6;OW8r&hAX^f$T|^Nuj+0m&5(5u-c8ULRA%g) z+_xb2X|3~&otsC#)D|F)r=2@!-01MTa!g9qmeX1VxZnjV#BGS%w3a>t@GCMxTj1<_PGtBqT#kWUFYHq5lF7YU+^mAx_g9c7Fnxv&netZqM=AXI&4*a*Ez-br} z82a*to?(WOJK6#y*qT(4=Og-Yh^*=&+8PoCHX-PGF=$xoG)dEa>>xvUDtsdyrOr@v zxkMV;x^G{+U5MYbmhr#q=+hQ(W{3xLBI1=q9)@_E(B;n1B*tOJYcwfbp_z%IKhnPg z9;*C6Hfsx91CdH#OQ?G|Dge6Ur)ZFc40MGdD z1Vj|C4d=v2&d=HcH(+b_Hqk>Iyx)RuO~Z84QdVpFfQUs~9l~>oC59;w0oGSvikT}_ zRTUj4>L9bzQM{my@Eo1vau($T4Gn;>8QKMf<3#Fd3&;R$7v{5J68cJpba)~_hL%2~yh9Z5O$>{-#vgER0D}c^FqD`MkM2a=U_d=Y>4hlB z!YSK1M}81QRt7?af{(dlxhm7xk?N{X*ng;Uv~@ytrnQcx)oMbP6b>&wo@C!2VW@SO zSyW3PX1|x$03!>4NgT1Mt2%ict4$9}q%GRk+QbL&`Y-?@=?-NCE#P#BJss7;=;n#+ zVzMC$ynq~C&r&7$`(6cCjtQ!|vRJDycT<@rk$Q^Ez@<11DWxS42VGN#p59hChWA>s zw+!PvtR?V#pS`9nS7kB49_+Yxp;4U(2fTmaj@!;Ac*TMzaaGo{=jPB5uVsX7%+`-vZ!eZr0t&#;nTRnM%iD_qC00g0|XQ8Akj)pH*8-G_`do%vONOf zwPX3GzVf{naOmz;2bF5XJf-99)=)VhTwx@J3=1_bkO-{Ad@_B1sl&<;9YNT!w3Ilt zCmG}!6^b1(3@ZB{)D;dqUl^!&K>P)N7f7yBh&y;$OI!Vu8tCE&$A{w5;FN*hwON}~ z>Y7Nm9VB0g$>U#_&nEx7;_q%HW3M^uQ|XEXnOl3fM-kO_Z}L? zBhh)rK@cF22M_?7O8;x55Y_UJ33kMAXl^5>8@l#%ay=e(MfRHD50FcU2Oem5cY$_S z4PzOKD+c%+8Wm9jdaHRARyJLHB$!+ap zd$|isLrZrgcj4Td+LF7BC+=-HjH=DO&3J-s!eMLLuub6UmwW{Grn6?K9rq@jdrg}g z7-Ma{h^c9)uMzQ1G^CLXcVi7TD84W^4!nz!YX>$={})=X2d)1rv-Tji7qZF*r}AD) zyh0;g*^RwI2Rx*=pyb-Ut<<&yZQH`N`GMwtBlhaG(Ojxs=_b5%O}lh6H%EQ}Lr;Ur zWY^tTR{+tkLSz+mu~0Pho^x5KzcJ*v|B70o&Vwt4G_whi1jpQ4FH85K?JhK7_1cyM8fp8Od;InJn+ zCW5YP$6nb1-VOR=(lj}a+@Fe_9}pS%zbSv;>t|x`NW?``RXJRo5N@;DZVO;h9<;n54W4ek%#+QrSmV zSlIx=%sq{W40L2^CSaz+*Gehy(rN8dN^mJxeJ;$bF3&o$EM~UWb>Es<{nd%i;C^Vww0|@ zNZNqjw(fN7EbtiWkf^iSmY`+av2xt-c6N|O$gxC_wv1i z=Fyjkm6hPum*Ca!jn)Lio;c#kGVTcgv~jKRZAI@8w2#dMOaAuRG)SJU`tv2cEeqZH6y25uSae#dW?@SeaZxF66`Hq<%L9lqt%{If zRi^z)6|2yaWn9H7p~Ag}CHqQcyEHo9Kmv0}BF;eKsX=eM?LU84-CYlB`x_nc4Bhs( z#Ht{#fmhXQG!GpJJdC+mgJ}U0x0QrUq6XGdLn<+5D}{6=>Ut0&I4m+7t@j)qna$W+ z8J3D=T*E4%!QJk!ywR}*;HT5tW%pP<_mZ~977Q<>=^Pdv$z@h!4RR)@BIAWtV(s{E0c(4CXuhe zknw{lZ&@yHg;CJFz`AQlKV^88C6E309Q%FOy-9A}`aJ*k8uu&@_lz0ns>G2`*K%AQ zBDiPGxc|g+|B0DSl=-HCE76etrXlxD!8eM2M0y{e<$r$C|H7p8aO^r*Tn)pLsB%dg z`bpmX=99pSM7CNhJX%X;S}XBdE2ZRZ5QN5*w<(vmrJv_x)#ML0HQ{8--KTxKS$#Ft zE%ei0H8wY@ncIGtJV!Vjc;0D`Q6HFWpdcSf;2ABb{) zk-Ha?OM99NV0U-9DZ0LtnbpL#Yf8^*-pcgvzYxu~lm8?gDwDOF(+P=R|CS)YqQN`L z#IC3mgiLHi{abpg)$^wOdkHWK&0b{6T`;lOzPSVaSvRsFfq|MuzyNn?4lJ?l_t0+Q zHME6gDdMG?hJ`vAhn9c@NR2cLp^0UFy^{z;saiIeQ>k!`z@hTM zYn<3=WTM%!)scK|FRwmldv0xef~koKX2;e*0^-1i693^Urdxtxtn7`vVT>YfiC~M# zR$|XxsIz$}2#`2%lDCP8&5rFOh!6mo4)%Q3?aI!h5+WzcD3d41^*F;ZLE=bY-F+*# zydi`mn*{X9#1V<2-5{aI@b9*4d5o(q713B`Gd*^CuLz#7kGpzgv#5$3zkyaacdHfEr zd8qF>K@u{>D6>&|QQ0qJ-E;cR@x>-45FJ#hw+R2?WZ!>B7=?Wrnx{2XZW>O>Yb$su z&gKaFG)%ferwXLKzhUPjjDj@`@dDXtXmF<=Whw$5iez%PW7`G_I2+ME@I@yitWqh| zA1H-=glWo-hL}!(;C^32#w!>S_Sb=8a<*gJV5~zBOGKF!@2`Uf`O6Zf4yyO94YQ9W z}KOSX}#z3Ne`as7z{L>}Xzh$QI5gAo5Hi-9Z9 z6m7Wqfo;t_XHWs-{B7>O~>#}FmXH9PH>AV z+^oVZELp|$L_br2vP*W9B7|x+kmtvp}S3miHt4AAZT#rGaB0{8_!J4{abs5Y9 zgnFsNcEX@o9|iaie|WZY%)ALEZ^zmL(!CO3*Wi{u?lwheA2Lk_KB z2>YhEFIzxD!^Ahj0y%ES{4h>{I8t|H`?Z)6$_apuXIg-?%%q5$d=Z=LFU+UOT6NS5V#j^jAf}o-QEybO27U zR>~>{Xt~7dz5uVeZeQgVrSllM5n~hKq1YA*7Q`(s%D`K$?-QD91wPge(W=_BDg{DH z6M)aZD~Ak_&spy(vREs!-lfA9={qR0TvP-;&pWi!-hrNRpBzS9i!)!(Fn?cdNn(3m z13Q{GhsdKy=Q#nEVV~3n1dGqo8k2HD|Q@dH-@LU99U{R1JY&|{k09D*ys zlWTF4pirfa$69v=`C{9g6iw6jj$ zS&Q2NE^YFF7X$a$49UI(Enj`IuPOQR5g^Oe7#!zXKydw$=5hg(bx29Q1VU!A2AfqQ zHTei|us$GB`byloHjKLV)8N`Ln7+Ay^sW3tX1WHOTO&37XzLZ1T|=o?h76?!n^z-6 zsgb4pfxL2v8$^-&4B`eE+2{*_-B&+`vHqi{_3RY&?@0jPsd=v~H;=&0Nz2VMQphNl zTqD&~Bb)Ii=fPo1PoZY}asi#<1mIKmZD>aZ*`Zh8FwB?03M~(7ZEbDuev%xv$0}|1+T@ zp|hfWsEQ2Mu8(}}HQm!))6V>?HyfUNzh)`4bRPTNRp(LG+86APjl>U;4?Q1{n*fog`+{qh_mQjU z$YE`KMvLbPE$4eOQ_p&pC90r2zg*WSB#{KN*<@P_4RMXu0e> zRiv@AxV5#^;i6f)J2h)FLR(v_tM%XO1-=fy_|c?jWFc^UIehnA^&aq@@SW{F+QxkE z2(6dKzqdR;(c-1Kw;i~<2z;r%mzqkuv)5M_NS&Xk+iS6?Y8e@+*&A^2uiXs%->>^$ z_&mK}0Q^eFLEr}w(Es_m|Gz(l@aTz=Ns|(L*n-|pc&pbB^j*H>AI9SbhFYZNzOU)` zdL3_Fkd_nM6VEY24yyDQUDsTmJ#5i(w#4MEvG6PHW067W3XfuaQk%A?#wfyxD_2m3 z4?l_4b~fafS6i-s64!WmS_$Tup#8_cDnioYN1v+}V!E+Bk{5kI8xR43U zE?=Q)`S6}L)PEtq$LrKP?0x}pH2Nln?`C|_bJo}1IXhvOL}uKJ++So{O|x5Hj;z@h zVv7^=x`68X9cw)E)+Y1(jruLzi2m3edHbcEE514vMgE*Choj+YTe=eS%4f5Y_g!!% z)0tXVx@b=aLbI9+b&p{_mBbaq4TdP4$nLT_hP>o)e(1sekNMq-8)&}$c>OH>2 z4!5cYfw(+@Lcrfl0e*<$zN4L+gT0x%+b!pt_raf7_~L&j{y@vUQLnR$noliof3C(h zmFyD6F5k+lha`$c9EY^1JjwSUfccK5n*QuuND;mbd*%`g4PEGS)mHL~+#=o|5suiYea z;&Lx-{GDc9cJ)0?!HtQo%e|aF10sPQM!F?u#LJs(=Y}dh$8>vZ*S6Xf{f|doL-@CR zdvoXJJ++F83Zb=*>L(&K{D##>-@arTYkf49IyQ6T1gp9i=GB9%YQoO6U#WYWy~^hb zHEXlC8r(%kD%TSN*DP%6va_%6ZJQMp25v>~?W`5q`0ge@+1pZ{=-u_s?Ae~Wv9qPD zyoB7%R30v`xwv!mrL#LaO4C_(OOtlLNu*LBzozEy-JgnYM_;&{<@td2g+@nJFAi3% zSKeL^p1w9%#5`BMG_=6EW2PBH+bW7aU@_fzYW$GRX4LJC;$3HNN?wZQverp>_%r3I zAf5;wZnQsbH;(_WVvT8LLWKIRn)aWYvb%>dad3Fci z6J^#$D8}cnP2`Cv-oJF_4fD$tZ&iX?w3pWw-rQNfc{%Fm@G0MyhApt6(B3Y*XJgue zt|?b>@6SIC=@cLT!0~TvzfIo2A{+#B`p-<`sp=mBryi^K+|%}&{8)cBQSpPi81=fX zTn68#=^h{CSKx%$Lc+h#M8a`BV;4O%R`J1A@xI?eLq<)b(2ZudFekH}g33RS)U$qz zXJo|9G-u3LYD{~oMR7&im%XPIPp%G;`r5j$M_S0ypeHoeR(` z|BllN%;5YWWOezsU>ohnfUm{rhZAF)&Cz3dKbuh#hlW&)JZlO>Gk6A}Vdl1@y{B7i z!+Co-{1cw@`d;^M|FDazKKM*JS+omI_DU|rdzdPeTix#e4 zRaE`@J;Apj=u+hvD&}3xo!Ze@gON2vONsS{L(veqNwKyzW*|`c{=#tB!t$>xD#sU} zU45_n$#N^>h*InM1gD^TKkhZ~3p&rVzpEFVt+hn4fBDffdy+ch{EnKeY!h%xQ?Njj zmJFLxU4Fcqo>LvqqsV-V_5H9!e(f36b@<=U9tBb0?js9m_{qhdR*vn(8;^%%nF)~j zq(JfNPfVlO>fg0H-=WpvM+e4+W}$x8P2G>7RQs)#$9zg~@rMCw>|6f!t0p@oTeNO5 zH0-3i-C6BDl>wwmxF*f`qj$?_Yk5)a&IP3;Lnwj2KQbKU%ICDys%=>OzRg{*Vxq6< zqUo9B9Vg{KM=1RANb9~c60Bd8%?tCM?_7-jU7d9%IHDM#megSh@rF?BA)ZOIk=%SS2o=o=CjqBtT$AYmbPH+~?}S zMkG84D}U$`V0HTqYhj@#>#i&_8Tt0jeE4pj1doyDjz(;)FZI%es1xU|dQ)aRd^6?z zmKF?$2!gp&n3OPAxl7sXzW49Eo3Q^_{k}cvp({c)<*$D-uR@pK6zE(XsW?CPs6c1< z3VQjT63n?-_Y1Y&#OlXIqPV-Lw;i$0fc@)VH;^h84HGXnw7*21Npij|qLTg0vxEHM zq_M_N`Bt-kY7q7Vnqpfi4%HW#+tfeYX)%7TkG8~(UJ?;gX^`vu+3C67-dSj@VDL#k z?t9OwPka7Bo_7t)-SwkZrs02HHa`p4@y9_zm?i+F%~WV`ec!8(f@tet^~Iok~Lu zA3o!;{*L$!_u)K8eiVBn7qv%eo7S!mJU^pO>&3xjJ+r8xsUL@SmLGaWyUEIi#^q^t zf@np9-O>Y_L)>wfCuIhcgQqo6TOj!&yGD}mve+8_xj*ni;sioCnJ%&_%bMh7$Z}_H zWo*X7aR{H^Jq0mlWrQi4+u0%H-s!2o`VMBXYL)%cpEygRS7ODJ!4Zj4%!b)s~F z^U&?Xk;Ln{4#f3t+i{GQLXiat&%&^LfZhH<+d)&)fS7U8|jw5=0eN zU(&nk()YZ9@2)cM6oEYA_3Ng~J2UqL)f{`_=>@!A=Rm~ZK8M<6KrWSfwB zM#%7=`;i5FI+_k$^zfgBhKa(shUB|qe$NWV#&}A8fLSGE^>nMb9cAa z-D|3PZNIkLRE;;)VQu%Yy<3A{9H-f9E54m`yYNlUcX1XUMd-puF-vXK`TaLdaOKsJ z8~4u!!KvB{2FFwG`;~zDDh9@MBLK#9f-zPDXUZACXC>)h49gkf} zfJ%GP=ZVNfV)kT|D9HxbT}e%rbWNQL^^oZBEo}vz2~-rIMk*rnOe5pr$N9UogYg{k z7wDi}HLJoqZ?rh$k+xcRY}1}h&em=yptb!wP1Pg@(?S5U3UAVoCkQL9F5~zL88U7n1b(5;lK@P zQtluN(H}8)bU3uleYMrCHFleC@fo3gFejz(S??W|EGgTF&K4!0I&}kvn9EImpI@QG zbq`2n5PN#Rns=3V%?=rBQls|Thpi2ehU}mcLzlF{&i8|fKm#%W#$aRxN!X5tz>6m^ z{`lO(Luyo5!BF796WH@a{N`7y)9m)z?AH(wp9^b9<6i77Qbdfe^DAILj6#I~Yyq)o z@Y*?zmtVps9wTK6VKJ6?n5Bn0aJJSvRs_;8A1RuyeNondu53vrS_shQMg*zC_`ieS|d z0;IaJ=M6UCBry$gSsw>p{IU+Li7XoOufY9wnLv`{hS~MU{4|#IYmMn}*t+<1iTQWj za-%+Q@Pfp$RdebGyS4pZ)0UQpFIMaV>}}}=p$zoh**t6z8AhIicp$s&p(qEE4Ej-s z03_=HM;@#8yCQ%yK?U;h=9$X+V4dA#z?!1TPJ-x1KSVW-PDEpA-UdO_OLW#UOa!eF z2vZhrTL(DGziK);9jmN@+yd$VRc9PP-5vH(HKP?daKV=_UA-}5N+gfdG zBCu>+BGAqrye@a8rsiEg#*c+|onq2H0%(ngUO5CA)%r2Wkn({;7$^1^4XU5HfR!eo zv!$uiDV{dWnkd7TT`&zX0frZYlRg`6W-UPwKWCmpI!Ek^IZQ-~D zBl+S5BQ!5bV_{5~&d~+;z6(^V5kwMV6FLSmEiz&ea&2Wmqhnl}pogfND0b<0|8$yI zFm1|L0K;H%39aT4r7jZ?6>YW3_6k~nE}Zzs z(?~U#a9Qux<#di&Bm0JG!<6W9m4jJK{6Z&VSluZ2o|HlMLfE=M_MK_e_P5&(dy^Vl zO6v>0r~l}*8vkWR7XIt^;NRbSgRiMdFZRtV^uSvP!4mZ{q_XnVPK$ zbuH<1;djyt`{$k#4u==@L!*t;HgSF!J=EKYW`2HZeD`z=FJGj*b0ATSiOYC@B!T~L zOE)T$O@p z7a8xz#9>tIVA6DVYtDAF+ah(GY5+Y^e+K^%(X+eSbUFvSM3Bt2X#zRgY4&=xUKg13 zx!?}Gf-MVdeCCB?{^sZ7tyt?px9#wkM2nKMJAJEta*|d3-D>lr&AN>9Jx)#*?!pIo zv!?)&+EmV#vNVsewWg%;vdye>&YQ2au{7C!2`KXl+y=^X5|C&z$mBa_V1<0zHz<(6 zOTGA*U~222S@HSc3G2fl{oycqx_H~zL%k&Gm`+dqsc`XUAkLAfgW5(O%4I&{4?0rcS|TR>G)9*5g6j1sFu=eSb;{dJ@ZTvUZcL1jM}lIFL=6+fz(amV_j* zLuKW7ZP}7+*7(FDK=4{kn!3$;3GbCa<&u&JTQ9;1yPv{sx5`Gny|K5qQL8DXc6RWu zTmam$2=2-6s?oLf5w{lAScdiL;s=fx!OSJyHkSTU81fS0AY&7BW^J&Tsap0-IM4(_ zq(7Rn4}&eFCze{Q2e37!V79SL^IGG9k1-VN8n^bho6W{NX~ZyAU0?%-QW|=L#p%@Q zz`t&&z1Dtfuia}4h-B4mDxi^PL)JN{=T0UbCqHQiyQL%x66KNF43#Ba=FNi)rS|4I z!c7WS2&ulY7Zl>dH;PO@BkUD?+Sx<5j30d32Pq#Jy{!=Wc;FjmFEfjH)o63=i>ZJj z(eK)k7=3WbBIh5C3OJI<={2nbQ?j%YT*E}oT~jvpf(n@lXs@^@PXUTzj}(w2iaweH-0TOiqjP|q z3ZoWtM`5XujXj}6NY?-3M!^{*o80xC>_1TN%xK(RzI{$}4*5nNIn!Mi`rfp@Eew!C zBj-ZdjXL=q$qM4x7COV5PD!J>@zuQ&PGb$j&~;eLFobDct4UcJ^-3<4TDezKzSVq2 zb))N_yrvG}cF$Q^_KTMGBEDhlQmRR7I=U>B?39v)*b^DJEJVkhasem{kVarzf#ggx zX|pra+?7Cy1XLHA((|<63RaEE24S(ZB+WqKV;(8Chbn-qO9ojC-jKm8#%gM8GUYt| zoTrr{2#qTv)lFg=k!-sxo@5~?A&%byXziaEM*hIzB>@D^w>t@XIAb$(p zt|i(HDRKg#FpbBU3(O#HxTl;;p>!;2cs-a{J^}`!AQy6ysK;cGd*q0If(0D4);jdK z0GkC((-in)tN&9@L@I4W(}1XzDrAPT90pS@Z-f?CORMB>tD8i8NzEkQhJ0_HGJv?^ zs;&>5yHC^P^bxh{Z*o+3bAERT-z&knS-4n^fg(86UIOPe(Mc+V>EAWHS-HIl;j&?U zXt%)_7OkTdpvj9c^jr-8vo#;0VU0Cnr7Ao`X!l3HngO8diJw~f6$DG`Tgblxbs3uV zk2XhKxG1=dW0ZjPY-^2}Wl_eh(zYS3o^!C(a&}nN(9viUm|+GV3|wu+qQWHTtOMsS z7){_jkefcb{3mWm^z9}8sXa7SQF#!_*bS|CzF=o`IYD$KL|IvWs0+X#kcl8V{y+!B za)7ZfXzuoaMq!d$lRJRTb05!O5Ctb3wXJry)@^1pT&r8EchKv# znCzAB-r7Π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 literal 0 HcmV?d00001 diff --git a/data/2_master_export2translate - copia.xlsx b/data/bak/2_master_export2translate - copia.xlsx similarity index 100% rename from data/2_master_export2translate - copia.xlsx rename to data/bak/2_master_export2translate - copia.xlsx diff --git a/data/3_master_export2translate_translated - copia.xlsx b/data/bak/3_master_export2translate_translated - copia.xlsx similarity index 100% rename from data/3_master_export2translate_translated - copia.xlsx rename to data/bak/3_master_export2translate_translated - copia.xlsx diff --git a/funciones_comunes/__init__.py b/funciones_comunes/__init__.py new file mode 100644 index 0000000..67d9a2e --- /dev/null +++ b/funciones_comunes/__init__.py @@ -0,0 +1 @@ +from funciones_comunes import * \ No newline at end of file diff --git a/funciones_comunes/__pycache__/__init__.cpython-310.pyc b/funciones_comunes/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f669ef4accceed0550c823b05428b5fa7f7385b GIT binary patch literal 334 zcmYk0&q~8U5Qmd(laxR`diI*b`T!zQrD@Hf8j|)Rfe^Brx{&OK{c~uZ#TU>=3V8BV zAE75_ErPS`H_XS6VZ?kMI#A!qNAn5&%MSl5fMEe&T>^+hT!P4iOo>PQH~+;ULGDDe z2#rC^_bpSegGV`DKY$5SA+^~Xs_5YL8mC(u%lnF-V+zN)HJMS0RebQI!PyRszmk;K zu&I%Fm07W-va<<7@iLD5qYJkjk;TMfYT;S + texto_transformado = re.sub(r'\[\[digits\]\]', '<>', texto) + # Sustituir cualquier <...> por <#> + texto_transformado = re.sub(r'<.*?>', '<#>', texto_transformado) + return texto_transformado + + +def save_dataframe_with_retries(df, output_path, max_retries=5, retry_delay=5): + """ + Guarda un DataFrame en un archivo Excel, reintentando si el archivo está en uso. + + :param df: El DataFrame a guardar. + :param output_path: La ruta del archivo donde se guardará el DataFrame. + :param max_retries: El número máximo de reintentos en caso de error. + :param retry_delay: El tiempo de espera (en segundos) entre cada reintento. + """ + retries = 0 + while retries < max_retries: + try: + df.to_excel(output_path, index=False) + print("Archivo guardado exitosamente.") + return + except PermissionError as e: + print(f"Error de permiso: {e}. Reintentando en {retry_delay} segundos...") + retries += 1 + time.sleep(retry_delay) + + print(f"No se pudo guardar el archivo después de {max_retries} intentos.") \ No newline at end of file diff --git a/x2_master_export2translate.py b/x2_master_export2translate.py index 0e2f9a7..e67f709 100644 --- a/x2_master_export2translate.py +++ b/x2_master_export2translate.py @@ -2,13 +2,7 @@ import pandas as pd import os import re from manejoArchivos import select_file - -def transformar_texto(texto): - # Sustituir [[digits]] por <> - texto_transformado = re.sub(r'\[\[digits\]\]', '<>', texto) - # Sustituir cualquier <...> por <#> - texto_transformado = re.sub(r'<.*?>', '<#>', texto_transformado) - return texto_transformado +import funciones_comunes def exportar_para_traduccion(archivo_maestro): if not os.path.exists(archivo_maestro): @@ -25,7 +19,7 @@ def exportar_para_traduccion(archivo_maestro): # Transformar las demás columnas for columna in df_maestro.columns[1:]: - df_export[columna] = df_maestro[columna].apply(lambda x: transformar_texto(str(x)) if pd.notnull(x) else x) + df_export[columna] = df_maestro[columna].apply(lambda x: funciones_comunes.transformar_texto(str(x)) if pd.notnull(x) else x) # Guardar el archivo exportado ruta_export = os.path.join(os.path.dirname(archivo_maestro), '.\\data\\2_master_export2translate.xlsx') diff --git a/x3.5_integrate_translates.py b/x3.5_integrate_translates.py new file mode 100644 index 0000000..87ee2a6 --- /dev/null +++ b/x3.5_integrate_translates.py @@ -0,0 +1,74 @@ +import funciones_comunes + +import pandas as pd +import os +import re +import logging +from manejoArchivos import select_file + +def configurar_logger(ruta_log): + os.makedirs(".\\data", exist_ok=True) + logger = logging.getLogger('.\\data\\importacion_logger') + logger.setLevel(logging.INFO) + fh = logging.FileHandler(ruta_log, encoding='utf-8') + fh.setLevel(logging.INFO) + formatter = logging.Formatter('%(asctime)s - %(message)s') + fh.setFormatter(formatter) + logger.addHandler(fh) + return logger + +def revertir_transformaciones(texto, digitos, secciones): + # Revertir <> a [[digits]] + for digito in digitos: + texto = texto.replace('<>', digito, 1) + # Revertir <#> a <...> usando las secciones originales + for seccion in secciones: + texto = texto.replace('<#>', f'<{seccion}>', 1) + return texto + +def importar_traduccion(archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo): + if not os.path.exists(archivo_maestro): + print("El archivo maestro no existe.") + return + + target_col = f"{target_lang_code} Translated" + affinity_col = f"{target_lang_code} Affinity" + + df_maestro = pd.read_excel(archivo_maestro) + df_traduccion = pd.read_excel(archivo_traduccion) + + # Configurar el logger + directorio = os.path.dirname(archivo_maestro) + nombre_log = os.path.join(directorio, 'importacion_traduccion.log') + logger = configurar_logger(nombre_log) + + # Iterar sobre las filas del archivo de traducción para actualizar el maestro + for index, fila in df_traduccion.iterrows(): + clave = fila[df_maestro.columns[0]] + if clave in df_maestro[df_maestro.columns[0]].values: + # Comprobar afinidad y valores no nulos/vacíos + if fila[affinity_col] >= nivel_afinidad_minimo and pd.notnull(fila[target_col]) and fila[target_col] != "": + valor_traducido = fila[target_col] + valor_original = df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, target_col].values[0] + + if pd.notnull(valor_original) and str(valor_original) != str(valor_traducido): + df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, target_col] = valor_traducido + logger.info(f'Fila {index}, Columna {target_col}: "{valor_original}" actualizado a "{valor_traducido}"') + + # Guardar el archivo maestro actualizado + funciones_comunes.save_dataframe_with_retries(df_maestro,output_path=archivo_maestro) + print(f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}. Detalles de los cambios en {nombre_log}") + + +if __name__ == "__main__": + archivo_maestro = ".\\data\\1_hmi_master_translates.xlsx" + archivo_traduccion = ".\\data\\3_master_export2translate_translated.xlsx" + + nivel_afinidad_minimo = float(input("Introduce el nivel minimo de afinidad para importar: ")) + funciones_comunes.mostrar_idiomas() + seleccion_idioma = int(input("Introduce el número del idioma de destino: ")) + if seleccion_idioma not in funciones_comunes.IDIOMAS: + print("Selección inválida.") + else: + target_lang, target_lang_code = funciones_comunes.IDIOMAS[seleccion_idioma] + importar_traduccion(archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo ) diff --git a/x3_llm_translate_text.py b/x3_llm_translate_text.py index cf0b659..8d55e0b 100644 --- a/x3_llm_translate_text.py +++ b/x3_llm_translate_text.py @@ -5,7 +5,6 @@ import re import logging from openai_api_key import openai_api_key from google_api_key import google_api_key -from x2_master_export2translate import transformar_texto import ollama import json from google.cloud import translate_v2 as translate @@ -13,42 +12,11 @@ from google.oauth2 import service_account import html from tqdm import tqdm import time +import funciones_comunes openai_client = OpenAI(api_key=openai_api_key()) GOOGLE_APPLICATION_CREDENTIALS = "translate-431108-020c17463fbb.json" -# Diccionario de idiomas -IDIOMAS = { - 1: ("English", "en-GB"), - 2: ("Portuguese", "pt-PT"), - 3: ("Spanish", "es-ES"), - 4: ("Russian", "ru-RU"), - 5: ("French", "fr-FR"), - 6: ("German", "de-DE"), -} - -def save_dataframe_with_retries(df, output_path, max_retries=5, retry_delay=5): - """ - Guarda un DataFrame en un archivo Excel, reintentando si el archivo está en uso. - - :param df: El DataFrame a guardar. - :param output_path: La ruta del archivo donde se guardará el DataFrame. - :param max_retries: El número máximo de reintentos en caso de error. - :param retry_delay: El tiempo de espera (en segundos) entre cada reintento. - """ - retries = 0 - while retries < max_retries: - try: - df.to_excel(output_path, index=False) - print("Archivo guardado exitosamente.") - return - except PermissionError as e: - print(f"Error de permiso: {e}. Reintentando en {retry_delay} segundos...") - retries += 1 - time.sleep(retry_delay) - - print(f"No se pudo guardar el archivo después de {max_retries} intentos.") - def configurar_logger(): logger = logging.getLogger("translate_logger") @@ -87,12 +55,6 @@ def google_translate(text, target_language): logger = configurar_logger() -def mostrar_idiomas(): - print("Selecciona el idioma de destino:") - for numero, (nombre, _) in IDIOMAS.items(): - print(f"{numero}: {nombre}") - - def read_system_prompt(): try: with open(".\\data\\system_prompt.txt", "r", encoding="utf-8") as file: @@ -169,7 +131,7 @@ def affinity_batch_openai(texts_dict): "Evaluate the semantic similarity between the following table of pairs of texts in json format on a scale from 0 to 1. " "Return the similarity scores for every row in JSON format as a list of numbers, without any additional text or formatting." ) - original_list = [transformar_texto(key) for key in texts_dict.keys()] + original_list = [funciones_comunes.transformar_texto(key) for key in texts_dict.keys()] re_translated_list = list(texts_dict.values()) request_payload = json.dumps( @@ -243,7 +205,7 @@ def main(file_path, target_lang_code, target_lang, traducir_todo, batch_size=10) if source_translated_col in df.columns else "" ) - processed_text = transformar_texto(source_text) + processed_text = funciones_comunes.transformar_texto(source_text) if traducir_todo: if texto_requiere_traduccion(processed_text): @@ -353,7 +315,7 @@ def main(file_path, target_lang_code, target_lang, traducir_todo, batch_size=10) output_path = os.path.join( os.path.dirname(file_path), "3_master_export2translate_translated.xlsx" ) - save_dataframe_with_retries(df,output_path=output_path) + funciones_comunes.save_dataframe_with_retries(df,output_path=output_path) logger.info(f"Archivo traducido guardado en: {output_path}") print(f"Archivo traducido guardado en: {output_path}") @@ -362,12 +324,12 @@ if __name__ == "__main__": batch_size = 20 translate_file = ".\\data\\2_master_export2translate.xlsx" - mostrar_idiomas() + funciones_comunes.mostrar_idiomas() seleccion_idioma = int(input("Introduce el número del idioma de destino: ")) - if seleccion_idioma not in IDIOMAS: + if seleccion_idioma not in funciones_comunes.IDIOMAS: print("Selección inválida.") else: - target_lang, target_lang_code = IDIOMAS[seleccion_idioma] + target_lang, target_lang_code = funciones_comunes.IDIOMAS[seleccion_idioma] traducir_todo = ( input("¿Desea traducir todas las celdas (s/n)? ").strip().lower() == "s" )