From df3ae0b3411bb69854d6c0e5bb68c84360e93357 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Wed, 11 Dec 2019 18:11:59 -0800 Subject: [PATCH 01/12] More shrunken images for better size. --- readme_resources/python-for-dotnet-course.png | Bin 64804 -> 57557 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/readme_resources/python-for-dotnet-course.png b/readme_resources/python-for-dotnet-course.png index 0eaf0f8085545318c37e40344d329388d28e4361..7aaf816b082b2e940984b06b6aa6d801fc7138f7 100644 GIT binary patch literal 57557 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 literal 64804 zcmeFY0030PS7aFsWW-0#ZA3T# zKo3xsd#~%8bJXFN@_NW`gVOA^--o$b^j7LsnJp>IP*fKz3AMzF;ig|uA{)P>#{9t> zUt4cG?@5vR)8p(+k-XWZ!)xEqi+SglMq^@}s&&fRB+N04@>p-)6Wj**pnO`{t7x4Z zkNf(}R6+Gk!A4Kd=YzfwfwXW>kpR=y1LJ1w-R9$lsyGjQB(PBHEeTd6(9I>(C>QDf zHfvqqqRITfKNbFt(!vV;za8-lNdW)bZ<7|t20;A#e|io`f=n6M#_y_@9yg zYuys4ApJk{AX+C3DaZx?+gg$R|0g2B`v16e)3zZpD$xmY?!jd;_by<9@w?l$)EX6( zF65I7s^0+#AU!x*p^>DakfnfDIP|ka94wf0sxe76yINuNTjnQ5&?JUh2*pU`{h8;h z>A-`QbFhBz_yI^THQ~#rW~ri2C|P9yCAJch9PATJwp|IqKF=XEKpYaU`Ps{(bIxQ5 zNm%MDKqwyz3Gt6NEkTJOMnkx)5?dsRH(*ttHT902IXG zm}tg6LwKs~N&J{fq7qi$&;Yh6e@@+vu{vGZ0rV2_{?6|}Ds145yba?uZEWalBwr^r z>`>U!zs1YW<<~IF0JuRmU%LTQT^9h*QiPdS+S>0ss0g1>dPu6XcCaiVV^_P2(jq ztIJ~i^Z&7Z{)5$dH}}sE>(=P9r6hYC#2tJ~sgo5CHiL;E4|&LxR!RHuHOmTErPzB_ z3KXZUy6$IXC~MiYtNL}nmno5a8YlI+n)(u5s>eF6PU*xd!_E;r*~>w+z*nF%s7+K zcRkg>q{`3fN`63`BZ4l1z`9UX0PbP`>R&%x<}_EWo3+zF0Q!^Gw&K{2Q_ zSjtal_fg)t_ZWpZI#@CX69!iIZMPvb#3~rfo)_mmT_0;sHR?}Shy%Vz88-@(QL!aigB254|Gr04lcvgUH(tmmI2m=9Q%0Vg850TGUV~KjSsb`(4Xr)00WM}~myZwG%O{K`r z@a%YKXj6G3E0^{E4m!(Tm09yR6l=!u1WO-@4OntpEx57a&Vr>>T$ge&w*1(I;ZF}d zAus)1Oeq%FC=A+MT_q%poNiNID)+xql|IzEIQPmCYw(HNmxvXUxLb6Ie>0=DWo()D z!9S6CXz~G}O3~XeWY;F`i&sXFe3MgQKsG{R*cKfCG1&RDv6WE45w`*YJYgG7B>Ul< z-97B!SDu8}te2UZdez z^H|iZLXi|H6Kp1SFQ?|pxde-Be}(y0aiFEwMH3sp1G%2GfEwiOstoa0yox_Ptm4Rj zL(;-H@dIH9?Z1WCw~`k?df(pnGf}r47pCKzB>+F^#ZBuiHQx)KKB4xcC^4d9?;HaOG1-_?*M@{~kd&~pqrC$oApZn<6 zhCGuAKHkg|ge`4u#Ivl*H1tX6JKeYL&Px7Oh*ZbhsTlLGcK@kXVo%xNWXGwz zDvNp%lotJ$h82F^3nYVh~HNkKMTnWrX+MUGA&`LR4Fo9DNa8^m)g2E>Uycr{1?AXcy6 z9PvK;SE(f!ee8I1Dt5heU#6)AvG}~EZj#GCA>HHnp%6d}H1u23MbvQ7Kbs#eRHawj zeD=yIH9?S7TG9^>svK;-qchFbM*-HWb?_=rUx(#+?vV3mD-DKfN(g_g7AFP><4-bg zM6jfL(ABay{+reSt1=D9Aw1_BA4>`wnv9#zWeZKny_uPRgLOtmU28A0U{3Rm3teYt zmKH8=o*6fQ*z!%1E)?LZ?Aac8XGZ3slc$5lCz*=Dz}8&7*5P(vmQdVvzm?B*PEv>y zxl0I$-$_5@%hoENdqHf(WP!~8o zTOmuL0!Xyl?q}P%PA_NI2L)Ndj~Y6;fZmJ+dmX4c zeMW3Q{IJV(6eh6_wV_W62(-W5Rv>`@jwEhUN~@cR*nsv*_~X$uGKY@9#%3ME;d%lm|~w5={PP*M2jehE7q=ZHtlQI9_Mu@S_%b;A=< zf(f)#7Ee@l#>A_gjs8%lER~n64tq!p5w6JAXIDP;xa;@4+q{Vm!DA@-nMRfM=U;J3 zQh@34SK%D&sfzY}*id{1%Js4H!`gNvK`KGH7!rfr2ytf+J3%;K57-1gBy6RCZT*SdxKOpkw6mbrAPqzL+ zL7d7z@yZmCEA3LW@g$-73%#leW@4LJJ;&==9oSDsG@xsbWRIxQd!*FgZ@@(AOyIe; zrffDnP)r-h)%p6v@GE49o)&j|hw1+Jb-H9-o) zL|oG}Pd4y-w~;Ml6@YOX_JNQ7N}SO>ZhF=<LKM9?52M`6*qw zOJWwQN3?oe>eYbXP;xU_0yw1td+Oy=ho95m8qxGx_wkDR)P`#;0PyD*eYB7VW{R*X zRll~gPq6L7Ax0n#>)Bs%zCAR2oGQ!}iAqTU5(-zUhlq9C~ zSFFmsCo$BRj5vm<8tegVzP*IHB1)3v>CeOKD<0xr3rlonv!t3sp6g_h*oizXR*Rea z6;^i6Y9@K^Uv0J2Z^w*I8?+7g{8uhNv+H|hIJSavn=B5;XU4ocz7N&Q+m&lkb!LhN zIbB#nz!*hY3O|LdFiCGPzkuJPl7IhQl*BAED6e+8x=TMPx!uB%v=r1q)1k~^vrom0 z%j2b_m#pUheJm0dPe=xC{MgGcrsiO!Ay3G3CW6C4qs&fO@epmR|1QQ9mcrOo??;=s zCfjiyma=F=o!g|$Ykg7TawO)*e0q>(GQXsuVqvbFI3zhg4>{rQVT)f~AE3&KKps9ntbV{woX`o^GT*w{C{q4QP63@1QA1tWLUxn$d})@|#9$(^d?Ned?X>0xa3K^(Ihm&HMf zIasS{Pi;GUHq`Poc`Gy8I5ZU^g{HWdZ>W*Q z%(GsiD=I_{^6&i1;tSE1iZaQDG-(&@u2i3j@twGTC$RXO2OnONL;8wrE(5N0j0E0! zq$yx0y(F{FN3IkTMmAKR)isLyy(V}`*`m~2%t1Gu`0NLBp9@iNmAYC- z`{_~3NRGuornC7+tBkf|$4=yf*6g+kR=pc8W!kR)>#LyHrK3BqKEXovzLylmb*dd z3?(EhkH@U~iXl5&no?Ki;&50<@VSX%zgKL6_^UFsa#xbdNgWz0;gS@pO?>=*I>SFg zhfT7*Gd65S<4on$849-!>?H(rRBDn9zXluO_GHN$cm9R2OnUEMYU|B{L3U>H7?g2T z%5ALCb2na3@RX)6@i*)WomV6Q#Y(rs_PsN~g$OG=lFdxA<~;GsbCs$!9aBrII^S zm9!yV6n9oeX?VrQhEo8U-WlSw&R+ue8|9s!Ya3uksUn&tZbCZ$6_1B)HL zca75lT59_eZGDU&00A-}E*81CtB@$P(lLFouCzL?(u|5C+de4${^Z^bvJalFDUt>M zhB@u!tzJU@0gXGo1zM2_&PX$}DWH`ZkZf%TD_i9DNtB+KRAZA!jB0G2?o;g4+Dp%V z?E0dJ^&3ztWuIWU;`h;%nnKwSTXnNin!UYU4GL!bs*exdqn-E~@lSXCC6>zboU#0p zO2Wk?;Q{ZNn9&D9=b+r<}V62Olv^ZSc!X-IKT8ycgN%|GNreA1-k4{a`4YahZqU0D^h+AvU(O6) z)FnyteiK~FbbfX)F0w8j%%mgu%Xe6B^GDy`*!;k~vGs+^HZ>7XHH;Rk$l^~l!KKW- zkHcA4H#;WUru(WxA&)J`r+M#Q4iaO-KV8O6&+C>YD$#cEpFb^~&})BOpEn#mvdGfN z`~ryLG{EJ2b+RCoVLN|bufbrqj`~3$ zTmLh)@kR3~jkvU^^MV_Mny|vrV(F)ahjZD6UmQidrJ~?1yk;0L>zQeWY8f|_pc`FQ zUzXO-{6h$z_>LGeA(gO!O5zNC|HxJkv`>Brb4r6`1r+9?sj#S&2>N}(v)Xl(=@sN9 z+7RG-TsI~4n_rqwk9`}h+QP-8DcLnQ-)#PT|1o`Dh(Ij@iPog~DF5Z?MrvYA^Sk&! zxC^@3jula)=pW)Ay2C#EXW5#+zW;v6hjfDG74*hJR(}s{9_^Y=V<~DMtZI`F_2oR##99_^|S2T zsFr9FmgW=7cS^KX#ibt>+g$lJQZSGEty0OT1SsYCCJ_|#!Jf%_dm-p3$AwDjGR2Um(xn#qJV^>1{^=~>P%}&dh)x($ zx_ipyO5tTFt+K<`D5z`v(ah14V8jl-#%C)ba1`(Rg&pjFhUyGnM%WxMZg717% z?NWTR*lD{M@jL>w?e$P$w4PE>VE`koRZG-d!NamPe1rZUAOpCAAp*T^CaukUYe+k1-7Bct^9|IJFxTl{25Hh9GN zo&xe+3ylofN+hMJrGlFRy8$oekFBuzTWj)cJXg5G`mK*7<0ZK`$yi@^}n1XDoL75SFJY+3+Rc#JFocuneg?g|*k!&DFQNR#&mEp{F%c)f4$YgneuKJ!)RnuKs;~iC()NHdkNWZ;hK`| zY2!mSmT$i)H%p=pHRGGovYPpR;(ha0&Qq%0={T7~+=JN4xt3mj0d-Ca(CxGSGQOZ& zAZhJ$u;orM)#iX)%44UhxRRe{;+mDu~6#OtwZ&OOY`( z0~_IT6ye7A93zBZqa{$uU|6|d*qWkpo)7|Wt7$y3?%f5O%a1vj-&?BtY*=nQTiFQ- z=+%lE{+y#b?JyE>C$%%{A~u}mmb3~1E8gsq4hs$qp9V&G)1 zQw9N9{c_BvwlS>ap!gR6@WvF5OZRl4oIS zcM%)E)+}5}3Sp5fjT9E}0sz7xU5$s$z`Xm#<7$@kFvQ#elM=W?hm20~-dU{4HPYNS zg9CY@PYaeVadhrjqW@ZAe~3CTmTa#Cxbq^w;H6s3gCt_4PNdkOOFm%g`<`AL;&vBqRocG}f`xM;a7>`E4#t=MEh9D4x3;Ce zUYSm9!Z8vs;W*(IR8G6q?96AQb=K5FscAbtaiY>$6a3ohTwYE6rwJbXx(XtjtW<7`0P;*olpPB#rK zO_}E{6nf%`oY?@)qYQ3WoaVEssf!JSpLW%;l0F_m@zEq-9!_M@r@rx;40Tqh0Mvf| z<%CdoiUWK6sP%kjnxx=`$J%+QINHXq*KV+Y0N>N${y&%cs`syNSLC_gft22~Yp$=` zeYm9h#{_P7J>ET=&4yLSn^2AQb5*d?m@Osxe%>lC_<#o7gKB=hUp;L%nZZ?qG4o)f z0&JG{Yhie1fgWRZCLib+z+Go|=`Y(8xN0JNg<#Hvh|4LdOMW2FltAK0;LvI3gC*x| z8Q~1O9Rybn>yJ}+5r+fCfL~6C>(k1=e`A^9I-Y(r!s&00hJ>pqjxy5=hr?BH0fk3r zsnK3RVM97b`d1xp4`R2*KkVzN=5KLYsw!ga-sJ0$bHj`m?LUI~yQFy_d=`9a55VD| z(l2;99q$r-VrVr7e&wY+7phmJd6xj!EWuARTiNi*eav)4azNGZNL z;<*_`kERx9U22;V%9oU+0>3(tA@}+zPwGq=#)4%0wagd^$)FX&ry`X5u1<<>7C^DZ zhu$K;pH{PBO^E$H1$cHWsTWcckZ`Vc6AwR8Oy_6rtIMJI0$eeY2h0mzh@o~fpDOqeeVFj`J?x(rym&4}su)J33VssbN zKV1)Ji;0102d`KJPVAb^sAmOW4*l1CXA{hGJ!&6+0WcUOhTLM%q_LL9f42T~x8N8& zgXG=Kl}L_>p`>r^_!I};E+jZZ-a-My;Tva-WiS!+2b>_^=Z#5$Hi;pNR?z_C1Q1FK zzrp^?eqnN}&7q!}02hEj&rs+5HS5zyUMQ|WVhppm?VT%{bi3u%hkcIIqX4&CK91Q% zLQTG+%|jIgIo!1x!eDffx75zRX96IZS03>yA!znXNCIKNwen47pDW{s?&*Ra8=)c| zWqC*fc?DV8QWEDh#-fw@>(Y;Y(ZW2~uknIymmfsFRgUM7R5J9kOkQ}(&83+QkGKtsZ6|KkOhz|YI+5qS?+#Ov>F za#>aVlC@raM&dGsMWxJek&W@~l8YiloQMxS3db0Qg=6zC8{*XwsY<0{USlkA_cvT1 zjL8mY=9B)K)DwRG5-2@6ZFHXeqXX|C-ZVmP61mnlYq<6)g}!oAmCs#|r^q?bQ7dPb`!8nN&3QIBOJ z@PkS%qz_|>CK1#ba?wtB%Fgke>O{a6*`@wENm&h}Ft}Sn*yG=(s%}cj{(Xf==ksKb zu4YJkk!t;Cpnc2Dnr%NPA{Z{bUo;G=&T%v-8?s`MzzvY9Fm zOG{}r1pqL((TP(*7#g1zFaZDpASN^eg3?m5i3|iac|}eQe|Z`_Jni(eUQmHt|4qU( zVNLD9VCV*GK_;^J9Z?Xz0~w+h;#ghRVuH=EJcE^=o$ua?P11GUy;|6}o+n~Tdpi}9 znykUb48<9}BFD#hfx?rFQ<7OwFdqZxQ7LrP*8_G$ns^@HhYYop z#}C9k4K=?kHsd|9mQ%iBz~D)e1t4VN#K6fWQIHBl)Ace#?tbqq^~44`L5bgUZbU%Qw#Swm&!A#fvU>c=)c zZe=dzLCZw_7vS(|N611Ps~40pCETUDr{S5&iowOn2!ZIaS2`xh6HYHV`r)wQmRLi4 zd%d_C_l;((MBR>yWP$aHQUddht4(RvP1v|vAgZBjaN~e zzeBG1OA}xxPBb9KH>m3bpI@0e+T-$KtL>SEO3s*0C7YOj`m_ z3GqSg-Jd@*CADf=jHp}adROlvC2mKxjX%zyFp*KpXM1Eq^iwkZYKOTf?anGi*1OVf zfBBXNb`SvoglZb`WGc?)GNDm(cw+ZCF7pA0FLM|7jhAQkt93$sIc5f(E$tZ-yc!$J+f71i!?~Y^FTkJE7Y--uwPPEuYQd@ z$&L>g%y4-49i^y%A}|e2Y+!R&m1pzqugIQYzYfftUv!LRZ||&oX?A%w|J0svbW#sp zh2&0qCi5!19k70g8h7}<3l$D$vdJkt0nAf^M(1y6Zify>S9j_Rw*)biyEE(`q7TE? zO%~^Kh0j*9s!0*KpnTPpHt2So=ZnPcJ0)d&-|6$Hy~k zBw}MCDJ;}nGq@t`|nR2j`xFr1{R2;_FCu!(uD zP;R_c#%Ot2v005t6)7d;gzy!1um&+~2e5vrlpC!f-jRejpx9MwCvy+?|Pvui7lQ^){%?0?auvB|Z6E^BzSCdLHq5jhC&*Ft zbL3fBhZ)cW!Wi`5(o%IgESwvqK|dgMqYA7p1TcJN^?IJsXx7b{8+M#21~n%LSG(pT zD%#}Q_yUbdt@TF%E;YlV!Q9Bwa}y;Mwt*PkjVr&M-QRu8g;c<=0adUx3D_iEl=%0J zz)ylO|FD4MihvpCGA)gV+ugQ!Jq^hpBf<7hhaJpB5DKAC;~_(li-o@UZVmPJPChJJEoFE@Q7^PP0+ATPMTJo%?%=I2qp+S0EA$#h;5Hb*ia#WT$d^!;$H#0>a! zXg<|hA$ro<>6LYQ=@{g*k+^{=bF-83Z=q|>yN=(qJaWGF*?B(`XCfL2O?JXh| zC$}n2>4dkG`!s4okMrf_`q~oYlrU<4FuA&EdFChz|KiXzOgR720#uo z5(X+!5Y{APD*WZ!)sP!Y=3gIv{zWlYQ<33W$uVBl>5I1BIpj*FdPz84@vYkSe=oIr zYBn3<3gbHw1I;5@tmoMU)$pBFZNWS_20ho|rR}~3f>yu)&4&ODJV%JvSTks&8OdtX z-2drfuW4uYd7n#})swRYroupIuT3qVElKV>X|jR^fNc)s288&YeQvjk&OP}%K>=z0 zKnXBc&r(utf5{SKdQ?YW%{+Gt^hPy<4X!CLudr>`X)4TPZ+X`In49)3VJJdqdV z6d#ArBT5W*RT0cdd}Q8Pe8Q<#tzE(89~=PPzu)qb^S_0du-p1MM+dx?*ZG#Mdq6hR zixr>IcV2eX>5;AzG`8z>Fh?d>gssc~vfa=)D2K1DpX958|B6%Ysra23o^a8=2mmN7 z%I!;8rQJ3!#;DUy${t9VpCVb|+f%_8QDA<;_=90Dyr-q?G(D4;;map_9Os|7jk za=mPsn3Y_uqSZvNfS{FvZwqp*OxAz(%nIB@ETFp2z7E=TQe(4tpaBj0H83%FdvxSkhsOn-DOWB7mw&%aUHFB_B6A;n<+zPI zlryR*D@FGm-l^{aiIgd!R0J69EYGVnD_#SezfrW13SN_K+;y3CY@;dUmTNj0c)J^| z$0{mH59w%=CwkDILSlSrzIhR@qWA&Ies}~-J@J$ zD2Lt_>gI_CVEC(ope?~PE&P0BIwRxw=cWmmI=_{wNS>s`XpioT?!pPFaywD}(=T~p3kb!u5p{V!911xu zGJ@MpTjl$0Ix2QuXXuyHzWc>suI34?+hm()FxMb&2Bd!LCp#6&FdF7XqtE7XkLE2T zaEryJH;PA|29_ZK)XvVV8BTxebrZQBj+WTn;(N>&swIb48xeh4x`Lm3WKm|@VAuE# zg1z%2ST31Ye^59CWSkwh^)_nh*!>uOzFcl{Dnf*x(J#PjDG&IP?<-=WhEm4Faq`^H ze@4hu7k>n}dDaaRLUAXQAUZ4poRIxsI^32*WC~5UcRo&*UYcG*cKDSvD?$xJ9;&*~ zH!x~{6w=V!@A!wc2pWtY`{=$nE}`xyffLNDzidtq(5R2U0uY3=F$<1YiKqZ^$3I|W)kLz#g}O?nOhUIOo{nY})aifliL8r%Ez&VX?*m2uu^k_wa@B>x<`*PRaD z*QrczQtaLK4+@T91;!(Mhi5$KEgPClV6|_`+BY|AO->DG9?r3(q4~5DwWm+G9GO4V z@Efk!#e)ViKKU!=4^R}s@hfYux>5lwDaUk_xFEnB*P+n+-vf-$2^&nVx4Y}nm+363 z?e$|UNZ;kizOZn4#P*~w5(3?zzlA^KkNr!~X)-Q6S?!ds{~fQEt$%l?n@3Q07F?C3 zh^RU#Kll6mz5 zS9d^OU`>Y{J8hfI2U>>SJh``IM@pTemzAkh0JZ%;9GUcJ^n~?kC01J{KVYpDZJboR z09rAR9u)V|#=%W0;w3-4nCviT2RjrD2J6TnL3t|iPFCX(V=US_}&)$mT z=gx3tQ#MwWh@@h)@p~u{6KvEd@1A_ma{0cotr|wG%#z*}=pkVlSASMbkBacArf@0n0RW>7756l4Q}75y z{VuArxThAykcMu`wsf}NVG;3@25NSo6d%Vv@fFWy7+hewIvbuq*Vm2Ld)`>uY5Q`s z2WhNrZbjbsy@n`wl_w=?`Hm~l8#Dr$9$e^kGM~{|xUXKuC^?6ovyYCD zf}NZ0JAgv0+p?bp02QN-xtWPxX?pnj&-(Kchj+QG04KeNwA+mf-vB6ghaf5z4?zm< z55`ZyD<+;#mlO(^ya###fXHd;ZXfhb$zV?htNDDRXn(3y^gcNk=5nFa> ze?05)f}Ht~-X2~gJm*z`CnV=@KN$(|MO)`YUf-Xqeb>UuSP3GfOdZhrcl&uu4uzoG zy0F!Q8a#cG=R8q!k`eNx`W-G4}_Xy~&o=fhW}4@jurW%OCE&kn`${i>MI()k-+6{i3{8-pZi@`=f-K@eh#M7jT49-;a3mD>|KK&3zDOD;ZeG$}mfvxQhHP`G+#r-EO4UIl)71;}t%sy#Oo z3px&P48Ri>c9W+8Aa|z=lq4wTEw!HP9X|d(#8`b(Xu436!iLME9)&Aa-?i>gmiZk| zFq4NF<>s*ohkO4B1Mii;<2`~q$38mOsl;Bnf5POT@NH`3&msiC z7NDDF`E=@!P)zzy>eTYJHXqMKeF$maPLX!YWHh~4nl~Io%~vlp{dgECs8zf9o9eb2 z^8r{iC4}E>67I+vPYVbgSv<@vSU;o+Fqf~^8TOdMJsl-d{^y5}14jEI!RMZPAjU$7 zJh4*w6RSGvhU7IsLc$co&)i;YQc_<9DU^?aK^j4HEBWRbv5Q4MIY|#7`{WMaPzWV} zuzFe!f0rZ~akdWpFk){l*}Uos&`|dMGa>zBv$|EV?_urF%f@-+S&#lV`8~z5bAb8p z%-eSJdC6?OD<6t}wrw;YS?`dNl%!a$j_Y6WLayRhyyoRJw3N7`eG!LxpN+Ji1H0Wi z`e4QYo=A9t1h^*R5RvX-Kq!DKZTwq~KPDm)4TYdL zBZqoSlJaT%`=j3JGyG9QLODaBpp`eUHc`Q(|L=RU{wXd#P63k9?_a_i>*gq{>TI zcepnKem;fgf7SdTxri>4X}SLAkLCen)-{%?Tjp)HyGWPc=H-+NTm?m^D*B3)j^Pcg zQMO~Y|5hfh;8C^mweT23}}J-rU6bVuaa| zaRoO2VO{)u(eEzBb|Aw!WdiARf~zI%!`%<#x`v{SyRo;UH#qCQ&N|m`w-5p2a!e;B zDZ0}pCNq1mo-a?}lV<|ezeb)x=!u1~`b4W8Y9a|a`gepOk0C=F`5%|$rUmS(K0j=% z2!ILH*kr6uZIH~>yq;HMyF6a%=G%zVsk3}3Kp3S4oI7>lmwp3CGQkWO7I9i%4$pMf z^Z+c@FT(~I$TeQ8iLoNwcC36Qv#nJrK>w=CPhB*gj@)O<)BXr7*}bh&^)8LeQ&#{J z&*C=Pf~y-|>Qz!vf!chrw3`gqF`7S?^kGh(AW$h>dSXV<+0E=DdOVoMf0U!W^ChYW z#4xNFoEBpRD|c4!D($Z^!9 zuLojzd8!3M=LnI159dtfJo$O3n8XI(|I*Z1FWl`_uSs)8Hb1d)WnPUNArivS z$qVA4d1y9UIqwpZc%~1&gmtlR&ud3iz3vFQ5OBeH=IGN1g>Wg*8N$E)7O-jw9BD+x zVWlYPxl^$5K5V|${t0m6TkSYfxLBtAau#2!(#@a&@g`QPu5qNxM8d> zJ|Op%BJ%2ifLCAjg7~IcN@A6=H6I{V&#{^k&vw#*FaEYOG3kd`g+`1Eb-yilj%`-M9G<8x0{bnoX@rfa_D zubd+c3ClIy%IR9o#Nw)6oucZo_iR&MAD86=t3O0l*|J`S;V}ZHd8F%~Yj?_ew?A1p z%#6TRL4UYX15tiwa6XUT)Pw;Tu0{jUYb+>h-~DMAX!a9!d_-a}9J<06Fw$oP1FR5? z%$R(|S#9rM>#_tN75QdecNO_ktr|w%yW2H!z?Twz_V(9n=m2?&2xesIW%c89Xmr#N zafiC=*Lq!8wzvUb{=2IAUfgcrRi(ReUePT#=!$KQ6N6!z} zAD3RTlQ(%rq3^P~Gjl;HOT=IR6kIJ_e=cU!UGQ7Qa5>Ir3(u5LbhX7h+R}GOSnAc6fFri z8g@FKk@9%CaHY$3p?zo3znNvRD%NSB>-1Omq>>mQO&^MKH9WkB5~2E|{hwPWY+Sym zKHmP-U}Nr2fK1c&7l}|li6*xlD}fUR42BT@EA_o@a8rXQfS09Uzxs9S*;srfw%=KD zyo(<^Y^JBM!U|2~(DxM+rjF5KszKwMGpf$15^5_KI_mFU*Y=P`id?o4aRHo0Do=-jZJf$+lQhAkcF_v_&)ZA=^AzuNBMI5^Z z)Y@svDD>%?8_>!G`!-;fXsv3|IZ}Z&xvUss>ElTqH?jmLb|6<|G%SfeRk9N!lr{p} zpPEvvi%nBntIF^O!{LqbE(TKkSuL4d-*;8e^ga9IJk^ZWmkEi)&>5~O^N$o-tGo6Q zr=W!8-k50U=`DYo0hm&e_&7)v18c3) zAxcu!mH&BK3_5Of)MQKm5YemDT_O<-sxA8kKf!lQ-lt7tFod61OFeFUV(~fay&n0Y zzs>0U$)u^%rhsF6a)*;WW+Lv3BQ}EZ*j9MIGQ8bJtX-saDkXaS!n*K`2e3KnxZE;A zZw0D0pPb`HFo_5hwQNp&F55fz9N+u8e;5G$_ujSZI(bz|;5tKnpB9H6j-&-6_-`3+cMG}qeGFcdpsLLq6Pr> zdsK-DNkfBJqm0cl1r!VfZ(jggk-TUdi1+mSaj*qzF{R_NA3uVK&!w7zZ!g^23FCf| zu%~{A68<9T${Lw;sTlHNWy?C@dog*(cFPhRng1Hm?=I3#m>VDA@3^9&-qrf&!Ygh+ zs1sYzi^LKhB%m+Pm^l^Ktmg^<5FZddJGMX^;vfml$XnIh608?n`iGDjo2r0AavQXDaTq zuaVNX5RT{Rl3IL49RPxIUl^c{Ub7KIl(L-9C7xy>FIO(o9%kQWaR2JJ3NY#WjV%(gyK->A^(mVG4Mo(nlLT6!QI9jUA9haac@wMs42`%0yxZ(`lQ4+G5kRe5X$fLcYxpBU+tL*rP>)@~k*aslS$`%x}|7JCm6Jy?nJXw^?LQGg7ExTyBShH(Ld zoSZ_{yrg$y#9sii+TNex%j?c$*@FEn`^}F%GT8>L>A{vIVpJ{Bb5+T31IUTjU(U|^ z!75CA%aI0K1Bxl{^}39upY{!2yIH6JL~MurQJS{CJBt#Mxb z=I~!(@9$Y^(=NPP>P3*}Tv?{|9Z6j?wawstlUXdiCABe}(ZRTFe``Z)C%Czsr( z&sXVL8HHk>l1}p@O*!wJ&jrWeH-(8PePR0UvIq(R{5wfM=e&|O|4ZrMogKdTLGiY1K9+`m#XJP?3l4Ff zZ?D8S@qj8Y7VUrKLotHfHEpGHP>L}gXCiiJuQ{&a6h%vSg z+UZ!eMYhUrd2BRIR-acOHb(k$$0uCL9DyP8J-Mvh(*}&0N4!UfS?KeG_)abi<|EiC~eqU}6P?3H|Ca-Ij+^pB?73F#tQvcG6 zjo}ny>y6ngZ*Lg7nWFfMy{j7`cN^VY1L3zJH6cTzRi(n!e?J8UEYA5u*psq;8g)8Ik;ElB-U4dS($Pr6-<@{8&L))Xt1vCM}-@+e%dTE#lsv-e& z_g(+x&kOcW_nx}kS9}{IZn^Hk>b~a?snQ@7dklCBEucj|Kmb}?!}IE6QI}K6ATu+E z#{+mtu7&IyDDFBCj{qDJ>mcSOSNZh!r=J?ztS5$>18OLyZGlysz(DW(E#AxC@LBR9 zx-i#at>bE2Itb6K>IOpy#Oq0Pu0lsUTQ#p+wP38LR{EcOtuhO& zY>z(nw{~5$$;%q6i%Zc*!Ex6(gCq<`zQh9Ajk@y(XQBCW!F5#5MW$utvCeAi=jtMc zOyD!4B#;~oIjC>zk1?c}Hot&B85HrQ@V$5xb;WFTJtp9pbm01%k#h91&I#7DGK6Nfy(li*o&Z~OX0+EPw z)(tnls0iLkbNIJk+f}U2%i5CWxO-O`_ulieQ%4C7w|cdeT=4T71!jx zAfUksKz(LEFZ21nf&fr{2Xtx7uqTh)cX(7fK2~^B`;ihy&2ipM0i`I`1LG@==y$3F zkV2ktUIwPJWB*p_w*(gyemjxXf^;rq#_B16sifOaDPD#ULI0U#uPwa@*CC$sx3#}%{w4N5F7lIrN0L+6jYrK!B|6O8nUd^E zJJ2jw(+dIA0<%F*4bkGuA}WTTP9T>3n0U>mVMK0QbK+2LmG z5v3jaet5_K`qS;pEB^qS7Gh<+usVw$JUmoEj+tiv?HYcr&KBBtXPO6I1@HwBTA04{w~0jOBJ-fawQL+6`(!z8Etb3+U`0ulfcDer!P4)XyC`K-Nc0cUA2r4K4cr(6nk zwJolqO_0f49u~NS!zI9jdz*L_M<3Zf_S;ECq9(vaXlxvQvgh5iN-ofEpvZCc zV+vnXv^N`J+786|RRmtG-els5GpiRqkyM1LIge>Co;RauBY)oNfUO=$2_+t%zD;aa zs!1H?HiG97=09n(>LTmxs3o>iSESj&X@is`?LJ?*t5UgW3Fg`0FMMbrGwyqj!s<1@ z%^%^S8eUa|b8~6$$}J(K`tyYK7_UU@z#7ipI&@uJNzZ~!u(#P~ZmLKj!c7S5Qo!2g z13V_%_w6Tedj^0ZYo!_Wr5lm6L{{rkJ!j)$%P|QnH`XK|? z$zLJW2jA^ZR8HlpX@7*hMge?a3Op}+?|2p+W2Ok4b(JKhkBg#W!Dkm8FVhh8AUkdT z=0YtPKeg7>9f&jZgmHJoU>1}|>^4R&yF#7i*LY3p6ws(0SB2u(Wr_JZC70~$Aega? zS@4QgsTng#{@ZvN<_D%H&YKmN=B+0CK^OTIHEYtxjA&j0lA z%sD>&zV~HA;6;6bT^9~H50fkQj7Z9(fp6rQAKw6?S7*G;P-z0Vd0qWu>uYRzB`8F)v8 zBoMBC>t484l+R5XTZ_8PP^(V`a#ANLEu$v*;i0Ub8B>nsY{wU*naVRYA3=Sm*piy` zH?tUm&hed%DN+l0R*Od(T#jFTwEHit%JG~5{2^U^KNYc8;se61?WbeappeJ4tGs8& z@#TdF*e{QwuBgw80YAo@@9Y*3DhJ;Z?&|5LYU*kl&OXxA&)7sQ9TI=kQBaI|GCy|o zMDJ%c6*)c+?1_HZ_@SzJpVE^C?DdqyovZt#8}Hp6uXkwgky2VFQubxMymTdXkS>Ac z_N3zO9!=s69Rdy=LOfucP>pZE$Fm7Q(dlw3c4t(kd5sOAT!EM+5WSYILpt8_XUq?l zl>aCYiU*n{mC{&lx43%149hh#_&pra;1^;@p$9A>m7LZ)eri?)t?HVR2B)$y|8HdS{PqiF zndR9e*HilPR#a#8uW{e;8Rvx?r4%n9zz9Z zBG;ib8ED%qD_~T&BzxakWGzTeB@cL0&moWKZ+B!mZ&|&5YdPcO60`d2^q#sE5_jg= zWx9vBjrO%`V;`Jlht-K@`OJnVO;^ycMZWUmtp3cyv14>;5BGQ##if&n@`$Cmk^+s= zjmKTHL$vy~-n{O&nfLjmK6oDFWApk5Th<}lFh#q0|Az8ej34>kPaVi4{|kLx3q3Xz z-W4Acy(lm%afYlY&3w;bEUH~B7!(d~QmX<2#-jh=RtSL6{B3J|9uI6bXRO;=9|g&Z z1pHug9ME^3?7lf0`n!ScyS|W`*#u(2nlq{+5m}fRcp*Ej-OF7T!o|zGeQs3O?iF+U zITjaysPfLldMZ4mUwHYbbyvjUcU};Ug&<9g$w&AQ5c5c`J})c4U5d4Yh-LE$b0$ao zS4(z0g?%leJHhlQu797XF}JVA^?z1Ge;kWho2IQ%;jJX@ld$g`{O_-oY7wvt}DH+C<>Fav{4FI|PWV%a7;5=zYA1Mpq>iLYvGJDo>bz$sx&dKl0 zoJPhk396Z|fDoG_p$WVoA&1uA>;VvfARqu89Y~s6z~-^qT!e4l{|bSMU*C#Q0DIv! z{iG3rzuQl8LHyDP=HtlO&+l4?9{|sgh6__rMGz#UZLfOOYch*iQYn2s&z}2-^%&!c z(qHwykzr)zV}CI{&X>Zs>eV#A3Cr@OkN8rnhi8wEh>eqE&%~44{Q=BR7MP&1j3%=` z1VqWP!ck&k!4Ul(O0Hi=k&JZhbys(D{0;D>2l=Tn34!LPmB(ATk0~VYmdzIsHoy?` z)8gd`7U_JSaVEkNwTVFMNsHvCi z@CTt}G>9OORnX4)aqHX)n^+^`@f$CGC_5?zGfF-HCyEbru=2`}?| z<4Lk78+`7StO>OEK^A{AKotX^%8gB<2=|l}&eE^2qdWomM^DPJva85b7bK=lxRzK; z4pg3*jS?M^%3C-0?#qIKU@v_Zi$L|@&M)p{0T?PM`>pGV>DlsfUpCCA*ggmThR~7apK5GJLsltU67vy7bi5Bu#K0@@4{h)vpKBl| zkOYQFI^IFfUil%a$S#A|7S3UjZr^bIyQGHpS&Mrn(n6r zoU;9C&>_swv*eHP=L0+vraH%>9Vh^JJ^?wfo_@}$15Sy1lQCz}6&N99sah#>#4Bk@+(%_iHz2f%7d(U-9=9x$o!O;^ppWF&ZP54%7foG1R`-p}25S$cF%c*RAeh6nH{D z)f^;_17I?LFg^a>F*BrFX=^eH+MuqA_U zGo^sU`Sf``gMap`@gs_iS)rDO$t;k7 zA<*l3g*;38o7gbqS+%#1wx4eXyAM}>JzXx{^7;=Lv{0t`&MPP}j_$i%=@b=HywD!A z;Z+r3Am7lLob8AJ4c2N2r9(52I2+I|zrfZhDcwkkj&OfJ8LYj@!iAi{u*AI3+Oo!< zv3hANjhmbwesRQPWKFoX5eV7@Q&4`0%F2wyV&Lmx{p|d%x?mkmj4;r#-$H|T_K2W1 z8fPOwJ8Ml;s(+2bQ;iTRDu~?a>#J}jAR-dr3EvF=xr%5r+u8H06SWH2Mvs_J@4GE4 zjoZ(cFgK)M0g9>PX=!o>Yf=yX?1vIJoIY=hjk}R9N%l=4xokv>I1>aO8)E7*w2*$A zZ@CiD?aUH+!43~WBszNa?*y>;rCS;8pQGA1kG%YpX^~cW>9a*3FY5DOCLy@U5+*X` zS5*cg9$U=zCtnk1zug>1Yw4VPCSA1mYM6V0!i5&tqhnA$aq^kn0Y; z3C{V#`}Trrw@_9`5OAn6LPvi)+ihPXW4t2|B(Hw}&=xTS7b)}cBO;CK_!Z-8eSPll zac}C{l(8N1ofYfdVveluMhBSNn&g~?%2IX?B}A!Y0}VI^2<_&tTI)*_EQk|QER~E~ z>FV1){>AFeQ`hFO)u-&!NlgmUe69a_IxcYiW+5>TW_0AMOKAQas*PY4iN$K*7kTB; zS>IUEx8?P&;S)o5@@ERGHgajepFj8eJL4-8ifsw)FqyO*?2pkhY8TG@9ZuR6O{IGT zlP+Nb$bxun(JygwMH1@rc@prZ$^&Kz_ykgFR7ONRaSUTQV>!yla_!dvyalfKR(Ns+ zbW9)UB&b#Wy9u4I7IV&HY`(G}O4G2HnU^E{dsP8%chACt9zSk5eQ`0`kz zYVCKU9G4<1^)4duHQUCKh1a42Y7+i)7nANJhWlf`N29Majw@7|ReiJ;0}IP{)HHoE zYU7XtKD?%w{SKK!JzGZNXc^{S=e7@_UKU0gn2#dVM=Fi{5mTC+nqwL4mVGBaBlWcH z<|y`iTo?Rl7@MUeccm&Qh_3lsb0hKg1r__#1Lr=U_Ro0&Oj}(We)H=N(r3#5X{2p0 zEAg!?VEOP~OyqE}er680wv_nu=m_zKWn5140DRS@6lnVcLI86>=RcFD%E9<^$;v)@ z+Hmy-L1JCK(nKVg0_z}+zUKR>k2EjqRgm$0hADZqTK0$>BR~J|H~_%EJh`r$1eM~$ z_Y|bV)bH)pJxT{Q?xuxxBsXL{=Qc^thSs`Rh`IrmD1WQf)0i#U_fq83gb2wW=!BYW zdNpD!F@FR=D(k%X?rdk+XTp7MGiU2^%OpI?oEp7K)3TW=+jEJndAtO;E*QnNlEg9q z)61is#7DUQu36OB0rstKU*Oa07>3-^lV&3vtb^nn^cn?9Y7D2{UKVqnX|zcC*v?nF zH5=QPJO5_MC15FvtN3X{LrzJ&8U$T z1J`>?+PytmsW#7Y$93@(Z+BX;6xU&r5-A-T^pdPYy3C=)DLqrZCsiA0PtJ4_MFD~| zZ~)V;1~>Y@P&vdNW{G|4icNF*{8L3svp+_sB}V~|?F&k-R9Km@R}?^koKchpu*ywa zf=o516-Y-#HQ^kwuR$HZ-9A*g>>*tiM^d&6Zi8ACHszi*zS{MtV<6;!H%j^l|_*}7jj zEhtk489-|fQ&X!c+%5vL94j#~+PpmbHnX^I5Mq$3aU=h|*PmTxGNRsq_KukKX02ys z=?1AvQlj8jscG~Op2CLOt> zkKCj~fq=@BPlU;s2j%Leg7~C>k!pN$rNTbhfPwH}vH4Z2YApkN`=mTrdKU=Z(V&5I=id=gW`mWaK{em6I-A+8#b zg`gc;pp699@rB=rjf{LkUZ<`;bk;K6k{AH0_sl@|IU=hTey4+#?WEMD!PRiXp>6JQ ztzGa}xf}c;fjwMcE8Q_-sekmE{5gZ{ACIx*Is5!QrIcye)ns=wqZ=L;?4qH?<&p#0 zi;L1@tHV$#68G@&9fB&$Y>J*0i|Pj(!1+8IWG3x5WInn}+3bcR8{4-Vlb2yAQ zVNcAJ;$rtDBr-^eTc|Dc9}SJ}uY0%e&xekEO!-`PgIL09a-!aTKNP?Tr1!{@<#Dyr zF&+TwOKqr2O&68+UanNM)+3RgBI%i8`Nq6b0<;uuQP?Aslo3=~?p19Q=Jg8-{-yem z$yR|SwByuz{xY!`No)=Io%8eyUPif2nBKWo9kpCYs6PAsBbBsj*P*Bo{6R^m_RAz@ z2<-UNKXk~iGQqTUNVc%!TQ#~CzK3SPD|&TV?_9YqbQ&~oG~xQZ9`hzzwkW$pM`tv7 zt~P2fzJM2%-QTVA>X%#Qoc9;zA50bPwYQ$N@h1`Mo>C)a?TLQedTc9XZRdh>&a}<3 zXYD^yy{SdAU55>gSAKcWl?=-BpKA6WcPsa^6I`o!j4gw!0Op2&{)N=)#4EE4)A@0E z=}t1S1x_5A6M zEWUVT4ig%V4Rr)prDu^DFq8d}u^Shf_N#)O)|5+yoR{A%xmmtqB49H@2bmjt2XlU0ukaKXPo5pb zL_|j*AHLb?wp`c3{)(_GLt{bBQXQG+LEGZ{cDuWvN zD&>s1)6=xI@1s;$3DSfhhjSkvR)ED8EMpE0oC zt(5tFzDQ8`uA@v7O3$)5D1Tc_I>o{@{&IYX1h^OE+rfBkO>~3@(SsvvM1+aT@Esw* zY+i_Cnfv;@QuKr54oAo1>7_h-HphHzl*)qKA6nWTCuv(gupkBI=;(vyaz!sRdW(%U z-y!5$yu%r$W=i~Zx&8&uqbyt3w^+p|KI7Vx z%)e&roX(_gp;N+@`QK?Yv@$R`pFm5`6%e7^1K3=WjzlqZ4E!Xt*A=fQ!hMOf8Q|DsOb#RpcSIcUaD0ip6R*2=-GE| z&n83HV%4Efm(K|7?q=n!|JfVx+F&vY%O3#%;xmkSyJaz8s|diEa66o4WK$<(EKOqj z#e7n#U(%3m8Rmy$yZtJ(_=9zt7bD4B6nTO8jwtfWyX=v{IU7zn^{(FTON9dl(>0+L zf*K>@dQ5P~y;FA?g_{)75t1kx+>{u72)QvcZEt5#Y0{{#E{n1{E((<2$8)V+QLg!& z-`@G9DO-jC5agJCdd$gK@uuPAe{=+C#6E4zT6xg*^^pd>zU_PFLqn2!Tt+O$0@zg8sg0No+9DWD0 zD!h>ZwPiBFde-LxQl7X_&2%Ol4C3kOo;=zx_Za{4ONG4x~a>Sqx6pqqL*FB`2pq2 zezKkSIGmeMuQI^P-68qOHyL`f-0?i??LkP-5Hg-gS~kmyPAyZ|AHpD$vYTZmj?$=w z_=l-eoX>F4r8ezxWT>ad;gtxl>6)+I$z&S-FzHFi7LiEve})*?*?)})Ag?z0d*?In zp0vf%U*<-YK)HZ<;K=KG`fyd?Q&W?W70Ub3!24yyMZ3_~m^e6i!3Sx*uNBaFu5#>> z?fsg>9g{wHL!GuKA#YeYCG=1Ml50q3gi>7A-TsI($ZIs(7Ms~B0B9zs2UE9G?Lb={a!03#FI%vX|HESSHL;Cng_e> zz8IJ&0rhb6`+eVmLz7n6opnEEh_nE=OA&K(o)wmehQ+!uE9+J1&;LuksfqzEEcJu+ zXr|hw&9jl%frYOTKhI35tAhA7XNgHDDbmG*L>eA)QI}uP=iTo2!!|zgf>uR;?fGNq zjeq`pVh0gX(!ApMv>TnzbbOArTrm7l0OYtD(&70J#YnD8S(LN~og&2M9?R3Ga14bq zNd@z{Fgrin?sp^0TL)DfC|KsNNWBkm7F}vca#%JI&j{6t3nuSM?7p!E*j6>PO_7wO za4VZ-tv*@tJJOY42JH;WCxhX{*MFBjfT|R5RR%!Iiy_KL3TV=$H*2(rAjYL>5~(FQGQe?B+3j)dvuCg2 zNbJ$@oJbH#08RbPlTr{S(QEtC3?a=ybfp3%3YPP%VK5J((Op;#n8aN#}aUnQA(Kk&%@-PFqK7AA}f-iUVS1 z(lAg_D>W@q8Z?pA&Uv?H19i4P$c!VFJ#3{MS_tcc!?f}<5EE;;+mS6oNi8YsDx?&0 zW|}5#^@W z<8ECWPyYK52KZSlEgaiuuw}P=Kfssl`{8Dlg};*Pn;m#6dF>0((iIkb0HNPDRJu8ForWTUOT|ndWy<2e&zesO+b@S^ z%l25Qb3P&A6a(dJicnx-a{>%j-VAFuJP`-ZehRXD!n3z`W+&*m>a$Ne^^P-G2lR-Z z<6ICpPbJ((t6XJU={x)3y5ofw1h|)uF?bk=gXnPv=X;I4GOGE_A@k${mG~&uk>-8- zYx1gc{YOZR@CzqrAC!`bbq~-Ii-;UPl;wY#;mMb!`~lj<#eV@A<=^Gs9+F=jdpZR0 z-ztmWn)XVu`8jiZ{L4TXoE15HL?h21IMPspnmjZstE`1+DxC|Gn)gp+FGysJ9q>?! zdTVM)jng%i(3`{%u?#V0x+L@W{dvRuvq?X*^iy;bpW!BsUk3?PJLpe1$2>>p+$3xl zl9R9x+3E)rOWZ#SZ86}VbdWR{zkYy9BqF!PejS2a5b1w08Su^KV4W5akXuXG6ksEW zrO9%;(tX%`z%|V653ogh0@Nih2P6&6X16~I@_yYpWXb0Kh>L<4SA2%1_(cIeOyJfS zaymP_e43=ZM?f*6DW7ywjt6Ht^r4wPZQEM2;WcSmANw(yGXOY{hKP-zYI$1Df8?X1 zM-6-*dl;4}Qt-sQdBGkY?#m5b$o{>rE@VvLr2vysliD=W$b*imfc}uFda@L6$73 z5-9K~Oe&?4KLKfbfOf(K%@jPok2v@;8kmn-WhcV|gMN7x`nRxQ2Hq=TPa zoo-*&eC}GyA{6q001)yws&5{DJ+JOwdcm-z@l`9)ziul<9@(M~pR`KIv0q8FM`W!g z9bhrYpR9%`eHbXPN(Xi|QltRYZlkGTyD_V?a2xULI>MVVoH-*^*q;8Nbo& zHW^qwtqM8ea)_mU*`p*H95SiR!8FfJ#zdNmow^X>)uUALqt(Y~a z-`EJ_uFvSuP;k9GEko{C!7m-OH9CSMd{WeOL*)e#%_}Sd7L^8BHW}sBP}hUo^fMH{ zU&55g0GwugK2a1l=4c(3Z&tY(rmHA~##W5Y{k{H&u6 zVJ>VbhEii&&won~!hoQ)9;Jn;u(7Qw5LlDf|1YMFgG_50Mux>15NOSQYINN$lW``? z-+z`ZkPBT>1fV>;iKfGeZD2nz|Is(ntX}fzlN;Ze#>vQ#%`+vkPT|XP$Bm`|ho)q} z!R*Q?Wm}4&b-N-KlcaQUax4Hx1TI&x!;#qfUi$>8Zx@)ih16FG=%QwHy{BeX|7^wgsGkxwJPqv*h#a{1ma2CWW<)(% zEJlUy4_Ip09j~_H{=`fD-AEb+P|?ykgf;KS&lK|j-RAWZNTVm_64r)l{l| zm)@A$QS))d$@}9hDh@h{7P~#7AwO{6+dSsIiG0n_@$_)CH=Y>}*UL-43L33~ZI&57 z4@E82N&<@UM*e2Q${?_oy+^+Zn%@inL{j5l;&o?yW(J%T5`84h6)|aNAk3Vhv3zd7o&O1PHyZTucm6xB%W9i3- zSP8E9NaD1HNeI~fVCsfae7MCt3@+zA_Z`p%fY|b!$N*_0*r@NXH(EV99xbcT+V!vx zty0e0Go*?nwLHhiPo;Z)%zw(v5T9dZ%)Z*rVDQqu1Di~O0ao%sK6l0XT?>={Qn5K$ z;-_o_!uC$QNlloW-z|$Pkts>DOx*Kse_2MIfY{+Y_uFqxx0}g=|3G>PPn)2)4(h$cU4s@CWjy8Jd< z3}eXjWTrPa<>UoW(MTI)7(ZNrA2yz2D9>06r~vi)*kw8yC+Ea9SZ4m4zlm32W&?|= zacgzrMKw6~JcZdFz2@4sFV5qWFn z_YMQmeg08>&tfI&@q4J=!b|f+`_T#j@M1W2-xk>n+lNTNCt{&HI%1>|Erb7qvku0; zpunGpCsTx;yGs%3#;}_K6;U0p&8o37$=BBXKfAoJl;zBToacy|<-!eRmpl0L6;ywp z216*@ef#h91)NisC<1Lj(^s5+evb6!w`8b-f(a|H=(bEyOi-r+a$$Yv#tm8gdE0&j zTf)+TKN}pD`xid^%g2rbFA*=3Y^JM9(&sRZp9{jq{bo7cgdtHwD4HYCgSSJK$Pav) zBXLLNl&xP0!WaW^@~6xmd=73pzHV)->ds&2i7VQ1=H4(OgAn38eU>S~<8cam(6+VL%0BOi+AX?(>T*Ig=Pzb@~ z)jy<|siRqSf@%P?H1@pMED|?=pBEY$j8eiyjGU(awo$%PDhsKyg88j;sm5|Be2RuN zPhd`HHI0>yc|=6PS=)i|NpfC^EX)q%|Kk||zA9UJUK5gS_|fbniqmO0fA7w8$+KLC zUmB%WZD@9F(c$2{a68x~zTTA!3s!Kj!s;#l)TLH^a8h$)|82lSyz(a`TT=_6*rA4j~NNoY(y6;KWZiwox)4&z%Ofw;J&xK+<~BC*$`GBmY}TNUTl}8i%Cmy$(JK6W*y)8z+&7 z;(v=P-bDvc1<~YO9B8-S2c@*%4r|d(o#HV{-~!pU(0ef6_Vx1_-mT7k2ZZK2JFW__{M9*p@fBbm2M z-|x5xj1x8ZN=oq?IaU3{D6R(|ApDJ%vhTm+;|$d~!gupU0Z>Wf$S2a$&hG2H71rX# zZJ-bn;etk0K{jTBh8?S&O{GP>pZiv`pPCX!XCU=?xgt+Lftm7;EPzN#K1TP$_Rx>+37<%57t?RKFC-&e2RVO1?W6W(Q z{*&nFl9_IgYRr*&5k+X_<|QrskP^<32w)7X3I%AB4GGB)u+LyXZW>_;W!bRHbjZ_5 z`r1Q+Jawz8S=~FTft!qcv4=_0mvP?+1%Kg0ff#MXbK!!oFtH zt@-^vWULTS0?j499hZin(nYJ*jdh8XGyXiQX8R!a{X5cfPamv z6hLAFlg+YFTwWZ;=-vg|m651rD_(pKME>$1-=ISdUk{NTY#z3e;^(|~kg#LRC2SO} zJd*iRewrN2%u@Ewe&hqTkTpxOJO&+#+;R%zTN*WSzkAxJONRgpN9u`6yv;OX5qk8_ zquB}lhDGH`NCJ<54G$3Tk%W?2(wR7U>`ZjhRE=@U!u1Z$93uS3?SM;g!*f9$lpW3@ zZf(qL{sc}6{Zqa2m9`#SL-hWk1+d1BmtM$a)k`;KqFT5LvW3rNBnKksXU+;p#JADX`;R%j4}@{208MC_Py6AXlsBP^ zK9QWvD0p)|fa?$Fm1p#;voksV@m~hGhtqaYcA#wE#&bR7;~8#}jemJG`=S#OF%|T0 zO}{b$fO8j)EZAoKuQdp4V^=L)BGg}^l9NCZcf1?d!qL2?)-lHuQr<#xp&-{~alIq7 z+17EH{rJl2ck%-}-lnsl(@X^ba9?6>fiyWk*%3_TbfvgV>7fu`4KH)7hHg`(1*u^~ z!+R2Xg$YuS&1EaW?(&wAHCm#^Vq|SE-={l7DYFp$+ccoI0YEj3fKW!9_m#(ZEJ}pS zy0kd3t*Q=^ng&*BIb`If8j51t(U6)e@Q?c-fqpQI*Lf)^XA~VVAO`d9y=nas7O5!m z5B@ya_T4b-A4pxxf2My^{yJ;-UcN&D9Da&>Cygfwg!hxci}DjevHp_s=z*b();vJwh0;T)YFTT6?3W##5T2Ec^Nf^hM{28gU3s^~$7g?q47~QgCq@w_k19YM}s_EPw5g1Tyh`6yO`3$T#9>Mpz(W zuK02fH^D^mj>nH^!1N`Kzk<&%d71#^9BavhmJ-CZyOmB4pS8ESqYUo>fM1iuvsIF-BCQ9Mp-ikz!kUzf70MYFCdq)1;WpvO7j%hx6SBq9 z^1IC8vZfuM7`*M|)+T4~I{$1p0FR~j(ua{&edf>N) zJqvw2tS{oC(z11EYzU&a_3(o=kAK;-R-E<1EWp0Fh8E6xN4_8ckS1EdHSM?<7jqK_ zv|p|Iq8a`JmwSW9KH}OcrJwg>fRex-U~0|}Q<*?sKn=C%l9MO^(SF&dOvSCtUReeJ zFlDr8^YQb3&yA2fjr&Hr}sxu zwtty%nCu9<&W_m{CMCU3)0C^^hvOBBX18l&Sax12@)Iw222ZpnrCDDz{(mcCNZ}~` z`I!zLF>K(zsmJy4S2YE+G4f^pY!0Uk0FbEJTvDoPS*9&~IT+pwZQ@HSx?%0)F4tki znVwJcjl zEn&0)&!L`E91U_ISR3=f>&98V#-xbmw6vw^gs0=hyZ7#x?}UB|X>z7H=G~<}SY1ZaswaPCmCwNz1(-Et{4aUX(u?qNC=c zrOU^eYEYQoYC==MdvA;P;*LSzSfD^VZUQy(#fR~~l~~TUm?jO8&$(yh zJCXYi&TJN_U&53R^+X-b z(IkvQ8KXGO4ys@3RY@3#RY7Q~FfhZOA+Hx)w@g3+io;Qxmx8M&lYXl)17{9xb{Bu` z@L1A&PgIK2`xkz`&DG(Xgw=SoOU!xUM0q6O5@IUAYjsi-$SM^>ZnyZ)#`QB`5-0Zb zA&K~qbH&`RP4@_YxXEvxDLeMp2ruo;XsSZ6ADoCqUjBQjghPZFS%g&fsJQjM?eO_p z^RTHiuCY#f5%d|e8v7(#0BN%kE#2I78EKz%BMf7Pf7tkeC2ezGPJg zRVSbEvkli}&jmpU^H&Gzd3P2bcI3-grwsfK5T?nbm zwKvbQ%$yB~gJe4V0~P2JS0Vll>TX}&x?xBIrqEtBtTc{BiAlpk(hwHZIw-;Q7UZLS zJ(1)t|8gfNDhLnb{dif5)BGENbgZP#1|5cNGe@VNrr{c9+AONu2i8v`k-Y$a_w+iI zVFZALjhA42dE&2LGwYXw&F$^`FoVB1AjZhQd?$-6&g|j*@siSX*Agr6?uO0rW1nT_ zDbKB$q_rPyi~P%nwK&ZBVc(@;!V?`oiv5Iti@ym%Zb3_-=$?@j+jr2jo~HYBMu%n9 zGB`g*z`r7xJPAf%l@30AtMo8XM$SEl{15uH2ZZi8yB#3|5OK8Vq9sp7Iwfq2XBJB5 zX#pU05wSN3YWL*FXZphkp%T-IEO?D&y{`1>gWJI&>I|hAK!omn@hY*$L?4oVX21-M zE~2CAW1RPaFQi3N@||h)T{AQWp2%8mk6j@I z&jRG5`OAdETiFG>xx_STh1LE?tE zA(ZH6L%A8`M64s%3^2nyMdwecC=NDMD$2N|t|LYW{&fBa7w{PN5@4l~*MaY#(`>bi zZtw$TLqN!LZ}ArQSt^3(*fX)ua)uu2AkDUxa(Wr$gGbs*37(vFimd;Sl#fv<(O4ux zP?7%tzYOjvlAmmy^sH0^&07Q3yoNU_LxZlvG`0`)oRse*@q&qK%7W_a%MI(LOv_|P zMVx{8dE8yfVM9W3?Tp$X)iXpY-c-Y%+9(w}_Ofq29D8vssKL6n>m5XW*DhDH1Sm`m z)Ul#g_2F#DeEE892>=jlVgq6aTLCw720sXgy^u;h@RQ%3e0zz`gV~M#>|q?xeckI2 zZKPrF)T8s|KZ6ZcD^)8&O`qlN#^{}Ed|Xw=@F#5zqUOz%Sbr!@Q3n73X31P};jT?i zT~J$-@(L`QA8}?iEwyPv-tH4~Nbe=k-vQeMwZ?~zQEIs9!{3C;&C)1JU#qfwe_$l? z?H5VNTgnaZrfuRlsaKvF^JkdzXU?$O;1(hbthQ0e?4jP6oex|y`n-QC>` z7>xaf@AEzn{KdGt_uP}8bM85&@@M|pC9gaWnJiMC%an;UytV-R+p=7dc`Kgcjzdc& zIj!KIq16S}?}qe6GA6m{C-`I13I7GLzC02BGM|d41kgB$J1m}T-rsj+!L%u(Cx)X7 z7UX}HugoNTjbqQtg{78(AtA1%vqS#|PLpb)!;OI)%OGTIJMnTMT*^j6Wm_RgU5!(* z4PbqB?M6B0epN*q_^~ahGrmH?$8dgP=H$+++J83?@#{Jcj}J+2!v;(MAPN0Pqx4tu&cUwZWwyJee|P6?(g$g z@VU{tNjt*T819>kBOJfINl!$(7s9xF(*tEFS}Xbe+<@Vwu| z;egvXdOrx5#azc~G#~kj0_0e5>2WdRy$=-;b;9vgT2(v%^aumk=b^5d;kh8vrOaRA z;&Gcc?pBK@cS$oV|004o~wymk0QpH$S zO}2j`tFm3a*WjR~M*Mu?VAu7LE?JahxqC~F zj^=CM+D-a5l!a6d5Qo|O+)`1iQnEW=iC$ua?v#eG zh_ffFr)Rhtr(tQ7OOmPUYc@|H`kVt&LAY%;OS2l%UB4(msF3cPLaP18AlI3cR`iEC zRpQ@*BvcXqDrgleXn4>Qkc`ywSey?hsM>ffEw`eXmh0i!R}FI+&t1*0Gjjd zx8`f0ocCQ7BeWd-I-3agO_q#A7O%306H&lTFkJk=i!i5=Tn$@ zdKL%8q@tOkqRfp>OR(V$yJlgsu6vn7Xzn-4(D;|AsYLS(I`)@=-Vbajs3EvmhBOVb zcVEAfmfdVf+^xwkAq$P$c!S1?MfBzOOZQEAzqQLEVpXFWs6U?}(Uzgu1iuV&|2JQ4 z13JE-IHcq*VtwW%0l7b1O#b;it2#3G>0eHV`uSbHlaQpGapULqdx$kC(G+8YnW!HdqPWvHWB-Y!ki*0`z$< zCdZ@kefv%Opid7b^r&g_1M+Ma<0@xc5O#}@6JAUjz#fg`R1txYV0P=sn3b@loNq3t zCF&o`sA$Fcz6zo^2v!Syeqkr{3(k@_`b*3KXxu!Cr>pkCfWagB+0N~@p_EM~)evTr z^POp&k4Vg;kbbfI>Nv z%vzQVq5=~oJ=^l~VOXVpo1yg?JQfcP%fshF;3w{JfW(XZ{MRmV#xQ1q3YgObjz#}J z-$+#LT{0WEbV`Y~-ua(Dz5@t&c^>djN1YBfKJ>%j$upv z_V8HmCD&E|Dwe85hhaZaG_(WciXSa)Uz0Rg@|4>NPU_mP^*#-wsmw-tr= z6@?DwHej*EmER(=2%%?4Di$iQf+kTyMhZZyA-$w#+xFhN#cqXASkH8PqNa#JePlK9 zS8wFwNJ?*@8Z(Kp>b}fnRr$4utI!e=S*UoC7SkajwPmVsPLtUf$ICVzC&nP`Rkffp z;G_Mfw^VfYUZ=Uo^zj3_* zJD4>heNV;8tM+#@hE!tBCJMmx4ueVem%H;?dV1O~4Q_f`p=hml#$KXG4*;y;B&g%w zd@0YrjkyTC)fs?G_8@E&cbK5C$j0Le#YMs0ymiwX zA~@elb@v{`cWl+Cz=Ox?T?)si}CL9tj^U9nSm9|EcSgiVI0e; z0mrpA9m21uFi9%HFy2Xp;Z>MDWRLEAIwp2i?Zui22sqIl0;+m80FId-iJXKUgP*Cx%w+%i7b%70#Yz zhV;H4=sO!M<8h^UsD2}d3 zMw7|^>Nz9Ctgj$KGdU1(a;Y5re4SSTpRXlKA1^LfYyVT^1I$ikO(|tXAwQN*{ z2%f0MAr(ETOdjZfp|DDo8ep@h(J8p%>kIfy_H@Sa8181H&Ks%0xE!wkDvsWQOY1Mg zf3X+6JZ;tML9!Sk{^s#)Say}KPc7DfV%~3pIVuRc749_Mv!Tt<;6)Nh3mkZ@%uw=a+n+(=vVKE$M##1(FqTKD#SQWq%+jjzN6QvM*Gl zw{r;&?k+&UFRw78u5S=hqKtN`gIN*N?N@uFVVo`t=MA`kTqar+KyaMSyX5G%In4qt zIudHuI?38DFTVulqBBRd<%~k$V(r(Xvx;o}fnJ1nt^TXc*GJumJvPu;=((;F{LZ7; z;V`uzv~VJS@26aBBCWBmcYIaAA!YRqJ`IO=Gw!Ehhhnt-TC_x8dOV_?V`G zqYmfkyzg3NmG<30m-YoL{fsqkUt;x-VZp4LT2Rq;k;@BGj>f{2eNiJ;-}sz&E6qaWVe0i8 zuC)2Rbcks*f5Er(*izGcZlC}78Gp|S*+l+e2!M$$->^!b#KXdzhy$I@M?N+Gtrz!< zFNh<`?al`g4ZIus-Sx%li=P+V*+on*!!Z!`?5E4^b@d^eb7}7=&e-LDNcdNl&9MS7 zweZ+lP=mMj>om+vAnGg39h=UL-O4F^Wc$~{xA4`w&3MFHLjzeal2AO|+^x1)#O^Ml zEaI+y5c0Zq18B+OmSB%#xBzbeAVtnH3fk+q4F zC%<(^12x&ABPc2y6=j2%!7>P~z#lGI!*O1wh`$y6XlQ@+hD45QUNgQTs-k$uQL)-0 zqRE^TA0R`>5`M+xUB3H%95`^)Q{Uy6Xg->M#Wdby!9!MG0tjpr-yelB9Wld-iu_A* zm%<1?sNK0Ep&TFJ@9}XETWJL}O%*o)L^Lk;+pbf>4=~mo)vF?B>8-M@F46WQQ7vCv}RFeo736hPtf63S=E_8nXu{ z;oBa2su^@UCI~zh72Q!yH zj{Cu0Erf!t-_GN)Uohm65mzAi4z_x?V}>DysTtAkeYTl2szEE2V9XwBOGs-FTlDDs zuv6>P(hk}OwBx-M2aM$b3$-qy-y%Y8%*@4@Pm>PGh!fE#@$f&3 zARCi)0P8hrRhx7xtjDg{fKgig)n4LZzZ<8!Mu~8?WHaWPtW{(wev@y2O}(zEdR4 zoC*N=6@Q@u0F*I%VNB0|rT$Ij!fIoVVoiwQE`H<}+0pA@f$-eSgf;4H?*J>e zU;OBog)tJTd`~0CGI(|2ekuaD<7T!UZqR6TuAY9A!zP3pQDPlmun_a-!2aYsv8XuQ zz3Q!)>;r zE>Mnnys;)3+}(fF{rMlQn2O2wkFxua$8b)fL=mwYSXC2^qMvA zI;fMVE0zOm9>->08=l59#$xffX33(@l7y`z72Kx=7u%nZ*PRr^3A=Zr*%cx|HBAlK z@%f1(p)Sb7rk1#A)t;4F*1m}B;TyfwOtk3XAys|!}v#Uc2snZVUb3}zGQeZ z=fsp?_59`U$)v_*?{LoLH>nW@DVivm#!o`UQ?2{Lt@(m`0D-^q^$$>;%m;jcsNj4b z$zA9m>>O?3U|1%^);KfhaNl(royG?7J@&4&cHz2oGgFtV#9g@^Xm%0hyO>xFfZ8;Y zioFL%{1+J!bbR2#Jx-1f*(FrA;dmUuf!v&LV7A`yzT4TME??Q#HJ!#J0xYQLdJV(* zpt5vyTJMsnMg3-GQzDw7^3ko*AKiRI1l{;bZLEK~HA4QGNXPNxPZs{?MP6otq|Aio%+l&6R61C~` zL~H<47&-tTn82-`r^k`p_Uu5OH8z;_a>r~B;|oM6jF6DNIGee-IysdIUi3)^IbcwLoWtt^H9}8lMz) zu$|-5qhA+Et(sZT;Hq}_tMyCVpv3wKvr;FLZV8sVnnSQZ-E^{gY zq>vt;xacd8jUHqp@1XwpRv$$3IXV5^+nblRe9ptJ@tM zD(?7eFgw%B)wo_E+j{!@id+|Qy&Gn7+u42k(0hzO=4-??MGxm%(03Z-idU$RO;uAv_PHbTLDwnkyyTHxLBqxpmieBjRX zhW@nb0=h=85rH%CBk4RxrrIo3B%is08jFG}|-_ zwO?+{cN7+sR}Emc)n|^T6jW(@Cj-a*hc|;k=diWmqzsk*XEK_bU$7mWek`N(yWKB+ zxm%j-(1R2mFUMa?j>ZohoF#=sGBVb{_kF6jM6w0clU|36cWv~ETVHqGjl+l|ncpKL z1@F^gXXjVl%=S8|BSVSA-%>bZt=_W~3HsmcuG^&$aQ57rQnylN;K?YGPjd?9HRDV* z$_Oq|!%yv|+^0BgU9KSYSpWUl?NC%qDVb8GP`6JDJNXW6tgIBS;{tZBXn!Rp-nj|m z=-~4p1d9PG!gB-xd;IE_7op#G!|_x-d8)b1$aKV{a#zrQ&lpHsyCAa0r}zoQmVK0_ zVa9%D^EiV*51ZrK{!`IkdI;o$1k+Qxr8V?qQ3UG8_V($HG; zI8tXBZX>7bQVkT>7gd^OaDdy2wwJKI&K0V)va^h-_EcZsGB}tH^hjz5$gKSxGH*W0 zX`&q8z44+ryeK+%pQMirS$vrVvgafpe*0eR4d`TcNA&f(-E_oKnMK_Pd5d_c4B~ne zKACNv7YK=PnwY{Qu`{P#nV+g=o78JrS$Y}#-*m;$l#o=)!sp`mfHevLU{73vz}b=H z&~Zi|e7Nv!-b0wG>p&b$`Z??rRM4{UrO(d^nnKgHdCG+pz_gq!!k|WD9Nn@ zy=n5ZkGB|a+P=@AkemoC7pR`-OZ}+r=cjOOv~vvmkR!wB_*^A z_Lu{3w33X`tmyt_nHN-xuVmJj9xfhg!BSP9tT&icU#$cj&P-g$kbV5Ih)>9-V^J`# z+u`HuW`EXnPp}XhuY`I6jc*tAvgo#R>%=8Y7{8il``{i+=b(FJ;(h``$gFphqIe<9 znP4}>S672|XOhIGz&{6O_P59DY-P@+k&PI^7Wb6+#lG)r!$ zrv4lp93Wr*eN&~;m}OjRvWUIHYaNVS))sJYeoZUD_xVfd@fYRf?oFgUrvbPG6IA-m&sW7gKP z#ZsLZW;q?=kjhksc&aWSpu zv#DdS?amrkh-JXLf~k{slzfu-cq_%Xr<04Sy&qsUZ|jlWyHH9vCP`_cLAgXjHMRvz1lC>%2(GmIoBAmr&eMf=)Iz_ zy~8B^-1YvXB?dmo^dLlMTXnb@k=6f3*(56JwL!B|b9Hg!V?gqsHf}#Bjs&|CCzQ3O ze}aJh)z*m}bmbWy&9vm$5T7==Z^;V&`5mB^#RgcYz6u>G!Y5rZW_Jb;02v=vx*?Cp z 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 Date: Tue, 12 Dec 2023 15:48:39 -0800 Subject: [PATCH 02/12] Update httpx code to follow redirects A breaking change from awhile ago with httpx. --- apps/py/ch10_async/ascrape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/py/ch10_async/ascrape.py b/apps/py/ch10_async/ascrape.py index e8949f9..6a514df 100644 --- a/apps/py/ch10_async/ascrape.py +++ b/apps/py/ch10_async/ascrape.py @@ -21,7 +21,7 @@ async def get_html(n: int) -> str: # The "async with" syntax ensures that all active connections are closed on exit. async with httpx.AsyncClient() as client: - resp = await client.get(url) + resp = await client.get(url, follow_redirects=True) resp.raise_for_status() return resp.text From 633aa1b31cef8d54fa06e3a22088d1700b68076b Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 15:49:07 -0800 Subject: [PATCH 03/12] Add Requirements Files for Python Application Introduced requirements.piptools file for Python application, and updated requirements.txt according to it. The requirements.piptools file includes packages needed for the project that are then compiled into the requirements.txt file via pip-compile. This way, exact requirements including dependencies and their versions are documented for more deterministic builds. See pip-tools package. --- apps/py/requirements.piptools | 11 ++++ apps/py/requirements.txt | 100 ++++++++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 apps/py/requirements.piptools diff --git a/apps/py/requirements.piptools b/apps/py/requirements.piptools new file mode 100644 index 0000000..31d73e8 --- /dev/null +++ b/apps/py/requirements.piptools @@ -0,0 +1,11 @@ +# comments +colorama +bs4 +httpx +flask +sqlalchemy +requests +pytest +pytest-mock +pytest-clarity +unsync diff --git a/apps/py/requirements.txt b/apps/py/requirements.txt index 31d73e8..41406c1 100644 --- a/apps/py/requirements.txt +++ b/apps/py/requirements.txt @@ -1,11 +1,89 @@ -# comments -colorama -bs4 -httpx -flask -sqlalchemy -requests -pytest -pytest-mock -pytest-clarity -unsync +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +anyio==4.1.0 + # via httpx +beautifulsoup4==4.12.2 + # via bs4 +blinker==1.7.0 + # via flask +bs4==0.0.1 + # via -r requirements.piptools +certifi==2023.11.17 + # via + # httpcore + # httpx + # requests +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via flask +colorama==0.4.6 + # via -r requirements.piptools +flask==3.0.0 + # via -r requirements.piptools +h11==0.14.0 + # via httpcore +httpcore==1.0.2 + # via httpx +httpx==0.25.2 + # via -r requirements.piptools +idna==3.6 + # via + # anyio + # httpx + # requests +iniconfig==2.0.0 + # via pytest +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markdown-it-py==3.0.0 + # via rich +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +mdurl==0.1.2 + # via markdown-it-py +packaging==23.2 + # via pytest +pluggy==1.3.0 + # via pytest +pprintpp==0.4.0 + # via pytest-clarity +pygments==2.17.2 + # via rich +pytest==7.4.3 + # via + # -r requirements.piptools + # pytest-clarity + # pytest-mock +pytest-clarity==1.0.1 + # via -r requirements.piptools +pytest-mock==3.12.0 + # via -r requirements.piptools +requests==2.31.0 + # via -r requirements.piptools +rich==13.7.0 + # via pytest-clarity +sniffio==1.3.0 + # via + # anyio + # httpx +soupsieve==2.5 + # via beautifulsoup4 +sqlalchemy==2.0.23 + # via -r requirements.piptools +typing-extensions==4.9.0 + # via sqlalchemy +unsync==1.4.0 + # via -r requirements.piptools +urllib3==2.1.0 + # via requests +werkzeug==3.0.1 + # via flask From 36d1c80f9548239fb301ea2931a51625d2a75c20 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 15:49:29 -0800 Subject: [PATCH 04/12] Update .gitignore to ignore .idea directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .idea directory generated by JetBrains tools like PyCharm has been added to the .gitignore file. Thus, preventing any IDE-specific files from being accidentally included in the repository. This keeps the project cleaner and prevents files from interfering with others’ development environments. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2333e67..6ba95c4 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,5 @@ x86/ bld/ file.json dataSources.local.xml + +.idea/ \ No newline at end of file From 8691402824b65d519b619353bc42304b087484f0 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 15:51:08 -0800 Subject: [PATCH 05/12] minor code improvements for chapter 3 intro code. --- apps/py/ch03_lang/L06_ternary.py | 4 ++++ apps/py/ch03_lang/L10_errors.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/py/ch03_lang/L06_ternary.py b/apps/py/ch03_lang/L06_ternary.py index 97176ae..f91c930 100644 --- a/apps/py/ch03_lang/L06_ternary.py +++ b/apps/py/ch03_lang/L06_ternary.py @@ -8,3 +8,7 @@ def main(): num = int(text) num_class = "small" if num < 100 else "huge!" print(f"The number is {num_class}") + + +if __name__ == '__main__': + main() diff --git a/apps/py/ch03_lang/L10_errors.py b/apps/py/ch03_lang/L10_errors.py index 4be8460..7de0f69 100644 --- a/apps/py/ch03_lang/L10_errors.py +++ b/apps/py/ch03_lang/L10_errors.py @@ -9,7 +9,7 @@ def main(): print(Fore.YELLOW + f"Calling sketchy_method with {v}...", flush=True) sketchy_method(v) except BrokenPipeError: - print(Fore.LIGHTRED_EX + f" **** Network error, check our wifi.") + print(Fore.LIGHTRED_EX + " **** Network error, check our wifi.") except ArithmeticError: print(Fore.LIGHTRED_EX + f" **** Cannot compute with {v}!") except Exception as e: From b458f9f13eb776f846d0bb20974844e750369fc4 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 15:51:53 -0800 Subject: [PATCH 06/12] Update httpx code to follow redirects A breaking change from awhile ago with httpx. --- apps/py/ch05_pypi/scrape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/py/ch05_pypi/scrape.py b/apps/py/ch05_pypi/scrape.py index d03e08a..1feeff5 100644 --- a/apps/py/ch05_pypi/scrape.py +++ b/apps/py/ch05_pypi/scrape.py @@ -13,7 +13,7 @@ def get_html(n: int) -> str: print(Fore.YELLOW + f"Getting HTML for episode {n}...", flush=True) url = f'https://talkpython.fm/{n}' - resp = httpx.get(url) + resp = httpx.get(url, follow_redirects=True) resp.raise_for_status() return resp.text From 309e1780b6c1c1df158fd0a8cbbc690393f51505 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 15:56:01 -0800 Subject: [PATCH 07/12] Add requirements for data sci notebook section. --- apps/py/requirements.piptools | 3 +++ apps/py/requirements.txt | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/apps/py/requirements.piptools b/apps/py/requirements.piptools index 31d73e8..a310a83 100644 --- a/apps/py/requirements.piptools +++ b/apps/py/requirements.piptools @@ -3,6 +3,9 @@ colorama bs4 httpx flask +matplotlib +numpy +scipy sqlalchemy requests pytest diff --git a/apps/py/requirements.txt b/apps/py/requirements.txt index 41406c1..daa7db3 100644 --- a/apps/py/requirements.txt +++ b/apps/py/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.12 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile requirements.piptools @@ -23,8 +23,14 @@ click==8.1.7 # via flask colorama==0.4.6 # via -r requirements.piptools +contourpy==1.2.0 + # via matplotlib +cycler==0.12.1 + # via matplotlib flask==3.0.0 # via -r requirements.piptools +fonttools==4.46.0 + # via matplotlib h11==0.14.0 # via httpcore httpcore==1.0.2 @@ -42,22 +48,38 @@ itsdangerous==2.1.2 # via flask jinja2==3.1.2 # via flask +kiwisolver==1.4.5 + # via matplotlib markdown-it-py==3.0.0 # via rich markupsafe==2.1.3 # via # jinja2 # werkzeug +matplotlib==3.8.2 + # via -r requirements.piptools mdurl==0.1.2 # via markdown-it-py +numpy==1.26.2 + # via + # -r requirements.piptools + # contourpy + # matplotlib + # scipy packaging==23.2 - # via pytest + # via + # matplotlib + # pytest +pillow==10.1.0 + # via matplotlib pluggy==1.3.0 # via pytest pprintpp==0.4.0 # via pytest-clarity pygments==2.17.2 # via rich +pyparsing==3.1.1 + # via matplotlib pytest==7.4.3 # via # -r requirements.piptools @@ -67,10 +89,16 @@ pytest-clarity==1.0.1 # via -r requirements.piptools pytest-mock==3.12.0 # via -r requirements.piptools +python-dateutil==2.8.2 + # via matplotlib requests==2.31.0 # via -r requirements.piptools rich==13.7.0 # via pytest-clarity +scipy==1.11.4 + # via -r requirements.piptools +six==1.16.0 + # via python-dateutil sniffio==1.3.0 # via # anyio From 5502ea11f7cab6bb83af7f32166ad242495e9286 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 15:58:02 -0800 Subject: [PATCH 08/12] Clean up code format for emerging standard with ruff format. --- apps/py/ch03_lang/L01_structure.py | 8 ++-- apps/py/ch03_lang/L02_iteration.py | 8 ++-- apps/py/ch03_lang/L03_function_basics.py | 10 ++--- apps/py/ch03_lang/L04_function_args.py | 20 ++++----- apps/py/ch03_lang/L06_ternary.py | 8 ++-- apps/py/ch03_lang/L08_closures.py | 4 +- apps/py/ch03_lang/L09_types.py | 5 +-- apps/py/ch03_lang/L10_errors.py | 14 +++---- apps/py/ch03_lang/L11_using.py | 6 +-- apps/py/ch03_lang/L12_switch.py | 17 ++++---- apps/py/ch03_lang/switchlang.py | 25 +++++------ apps/py/ch04_oop/models/basic_car.py | 2 +- apps/py/ch04_oop/models/car.py | 5 +-- apps/py/ch04_oop/models/electric_car.py | 3 +- apps/py/ch04_oop/models/parking_lot.py | 8 +--- apps/py/ch04_oop/models/sports_car.py | 5 +-- apps/py/ch04_oop/program.py | 4 +- apps/py/ch05_pypi/scrape.py | 8 ++-- apps/py/ch06_memory/doomed.py | 4 +- apps/py/ch06_memory/mem_explorer.py | 28 +++++-------- apps/py/ch06_memory/memutil.py | 2 +- apps/py/ch07_web/guitary/data/guitar.py | 1 - .../guitary/services/catalog_service.py | 6 +-- apps/py/ch07_web/speed_test.py | 4 +- apps/py/ch07_web/wsgi.py | 1 - apps/py/ch08_db/guitary/data/data_loader.py | 21 ++++++---- .../ch08_db/guitary/data/session_factory.py | 4 +- .../guitary/services/catalog_service.py | 4 +- apps/py/ch09_testing/guitar_app.py | 8 ++-- apps/py/ch09_testing/lib.py | 15 +++---- apps/py/ch09_testing/test_lib.py | 1 + apps/py/ch10_async/ascrape.py | 11 ++--- apps/py/ch11_notebooks/lorenz.py | 16 +++---- ruff.toml | 42 +++++++++++++++++++ 34 files changed, 174 insertions(+), 154 deletions(-) create mode 100644 ruff.toml diff --git a/apps/py/ch03_lang/L01_structure.py b/apps/py/ch03_lang/L01_structure.py index 4e2d546..4acdfcd 100644 --- a/apps/py/ch03_lang/L01_structure.py +++ b/apps/py/ch03_lang/L01_structure.py @@ -1,14 +1,14 @@ def main(): - name = input("What is your name? ") + name = input('What is your name? ') some_method(name) def some_method(name): if name.strip().lower() == 'michael': - print("Hello old friend!") + print('Hello old friend!') else: - print(f"Nice to meet you {name}.") - print("My name is Python!") + print(f'Nice to meet you {name}.') + print('My name is Python!') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L02_iteration.py b/apps/py/ch03_lang/L02_iteration.py index 9c69018..7d410f5 100644 --- a/apps/py/ch03_lang/L02_iteration.py +++ b/apps/py/ch03_lang/L02_iteration.py @@ -1,5 +1,5 @@ def main(): - print("Python iteration demo") + print('Python iteration demo') # while True: # name = input("What is your name? ") @@ -10,16 +10,16 @@ def main(): nums = [1, 5, 8, 10, 7, 2] # <-- List for n in nums: - print(f"The next number is {n}.") + print(f'The next number is {n}.') print() for idx, n in enumerate(nums, start=1): - print(f"The {idx}th number is {n}.") + print(f'The {idx}th number is {n}.') # NO for (i=0; i < len(nums); i++) print() for _ in range(1, 6): - print("This time!") + print('This time!') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L03_function_basics.py b/apps/py/ch03_lang/L03_function_basics.py index 1fb9f9d..eb0bd13 100644 --- a/apps/py/ch03_lang/L03_function_basics.py +++ b/apps/py/ch03_lang/L03_function_basics.py @@ -18,7 +18,7 @@ def main(): if evaluate_guess(guess, the_number): break - print(f"You got the number in {count} attempts. Thanks for playing, bye!") + print(f'You got the number in {count} attempts. Thanks for playing, bye!') def evaluate_guess(guess, number): @@ -35,14 +35,14 @@ def evaluate_guess(guess, number): def get_guess(): val = None try: - text = input("What number am I thinking of? ") + text = input('What number am I thinking of? ') val = int(text) if val < 1 or 100 < val: - print(f"{val} is not between 1 and 100.") + print(f'{val} is not between 1 and 100.') return None return val except: - print(f"{val} is not an integer!") + print(f'{val} is not an integer!') return None @@ -54,7 +54,7 @@ def show_header(): print('-------------------------------------------') print() print("I'm thinking of a number between 1 & 100. ") - print("How many steps can you guess it in?") + print('How many steps can you guess it in?') print() # implicit diff --git a/apps/py/ch03_lang/L04_function_args.py b/apps/py/ch03_lang/L04_function_args.py index 2a35ba0..934bce5 100644 --- a/apps/py/ch03_lang/L04_function_args.py +++ b/apps/py/ch03_lang/L04_function_args.py @@ -1,22 +1,22 @@ def main(): - print("say_hello()") + print('say_hello()') say_hello() print() - print("say_hello(name)") - say_hello("Zoe") + print('say_hello(name)') + say_hello('Zoe') print() - print("say_hello(name, times)") - say_hello("Zoe", 5) + print('say_hello(name, times)') + say_hello('Zoe', 5) print() - print("say_hello(name, times, 1, 2, 3, 4)") - say_hello("Zoe", 5, 1, 2, 3, 4) + print('say_hello(name, times, 1, 2, 3, 4)') + say_hello('Zoe', 5, 1, 2, 3, 4) print() - print("say_hello(name, times, 1, 2, 3, 4, val=7, mode=prod)") - say_hello("Zoe", 5, 1, 2, 3, 4, val=7, mode="prod") + print('say_hello(name, times, 1, 2, 3, 4, val=7, mode=prod)') + say_hello('Zoe', 5, 1, 2, 3, 4, val=7, mode='prod') print() # THis isn't really an option @@ -30,7 +30,7 @@ def main(): def say_hello(name='friend', times=1, *args, **kwargs): - print(f"Hello {name} with times={times}, args={args}, kwargs={kwargs}!") + print(f'Hello {name} with times={times}, args={args}, kwargs={kwargs}!') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L06_ternary.py b/apps/py/ch03_lang/L06_ternary.py index f91c930..3ee8d5b 100644 --- a/apps/py/ch03_lang/L06_ternary.py +++ b/apps/py/ch03_lang/L06_ternary.py @@ -1,13 +1,13 @@ def main(): while True: - text = input("Enter a number: ") + text = input('Enter a number: ') if not text: - print("Later...") + print('Later...') break num = int(text) - num_class = "small" if num < 100 else "huge!" - print(f"The number is {num_class}") + num_class = 'small' if num < 100 else 'huge!' + print(f'The number is {num_class}') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L08_closures.py b/apps/py/ch03_lang/L08_closures.py index eb24386..b8373ee 100644 --- a/apps/py/ch03_lang/L08_closures.py +++ b/apps/py/ch03_lang/L08_closures.py @@ -11,14 +11,14 @@ def main(): def create_counter(start_val, counter_id): - print(f"Creating a counter with start value {start_val}...") + print(f'Creating a counter with start value {start_val}...') inc = start_val def counter(): nonlocal inc inc += 1 - print(f"#{counter_id}: Counting {start_val}\t -->\t{inc}.") + print(f'#{counter_id}: Counting {start_val}\t -->\t{inc}.') return counter diff --git a/apps/py/ch03_lang/L09_types.py b/apps/py/ch03_lang/L09_types.py index 33a46ae..a7c2a27 100644 --- a/apps/py/ch03_lang/L09_types.py +++ b/apps/py/ch03_lang/L09_types.py @@ -2,13 +2,12 @@ class Wizard: - def __init__(self): self.name: Optional[str] = None self.level: int = 0 @staticmethod - def train(base_level: int) -> "Wizard": + def train(base_level: int) -> 'Wizard': w = Wizard() w.level = base_level @@ -18,7 +17,7 @@ def train(base_level: int) -> "Wizard": def main(): gandolf: Wizard = Wizard.train(100) gandolf.level += 1 - print(f"The wizard Gandolf is level {gandolf.level}") + print(f'The wizard Gandolf is level {gandolf.level}') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L10_errors.py b/apps/py/ch03_lang/L10_errors.py index 7de0f69..f913e19 100644 --- a/apps/py/ch03_lang/L10_errors.py +++ b/apps/py/ch03_lang/L10_errors.py @@ -6,14 +6,14 @@ def main(): for v in values: try: - print(Fore.YELLOW + f"Calling sketchy_method with {v}...", flush=True) + print(Fore.YELLOW + f'Calling sketchy_method with {v}...', flush=True) sketchy_method(v) except BrokenPipeError: - print(Fore.LIGHTRED_EX + " **** Network error, check our wifi.") + print(Fore.LIGHTRED_EX + ' **** Network error, check our wifi.') except ArithmeticError: - print(Fore.LIGHTRED_EX + f" **** Cannot compute with {v}!") + print(Fore.LIGHTRED_EX + f' **** Cannot compute with {v}!') except Exception as e: - print(Fore.LIGHTRED_EX + f" **** Error: {type(e).__name__} ==> {str(e)}") + print(Fore.LIGHTRED_EX + f' **** Error: {type(e).__name__} ==> {str(e)}') # finally: # print("Finally!") @@ -22,13 +22,13 @@ def sketchy_method(value: int): import random if not value: - raise ValueError(f"{value} is not valid.") + raise ValueError(f'{value} is not valid.') elif value % 6 == 0: raise ArithmeticError() elif random.randint(1, 10) == 3: - raise BrokenPipeError("Bad network!") + raise BrokenPipeError('Bad network!') - print("sketchy_method() actually worked!") + print('sketchy_method() actually worked!') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L11_using.py b/apps/py/ch03_lang/L11_using.py index 29bed3a..27d0be8 100644 --- a/apps/py/ch03_lang/L11_using.py +++ b/apps/py/ch03_lang/L11_using.py @@ -3,14 +3,14 @@ def main(): data = { - "name": "Michael", - "language": "Python", + 'name': 'Michael', + 'language': 'Python', } with open('file.json', 'w', encoding='utf-8') as fout: json.dump(data, fout, indent=True) - print("Saved to local file: file.json") + print('Saved to local file: file.json') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/L12_switch.py b/apps/py/ch03_lang/L12_switch.py index dd8f65d..63df7e9 100644 --- a/apps/py/ch03_lang/L12_switch.py +++ b/apps/py/ch03_lang/L12_switch.py @@ -3,23 +3,22 @@ def main(): while True: - - text = input("Enter a number between 1 & 4: ") + text = input('Enter a number between 1 & 4: ') if not text: - print("Later!") + print('Later!') break num = int(text) with switch(num) as s: - s.case(1, lambda: print("One is fun!")) - s.case(2, lambda: print("2 * 2 = 4")) - s.case(3, lambda: print("Three and free.")) - s.case(4, lambda: print("4 more!")) + s.case(1, lambda: print('One is fun!')) + s.case(2, lambda: print('2 * 2 = 4')) + s.case(3, lambda: print('Three and free.')) + s.case(4, lambda: print('4 more!')) s.case(closed_range(10, 20), lambda: num * num) - s.default(lambda: print(f"Say what? {num}.")) + s.default(lambda: print(f'Say what? {num}.')) - print(f"Done and got {s.result}") + print(f'Done and got {s.result}') if __name__ == '__main__': diff --git a/apps/py/ch03_lang/switchlang.py b/apps/py/ch03_lang/switchlang.py index a41d52f..2cb59e8 100644 --- a/apps/py/ch03_lang/switchlang.py +++ b/apps/py/ch03_lang/switchlang.py @@ -4,10 +4,11 @@ class switch: """ - python-switch is a module-level implementation of the switch statement for Python. - See https://github.com/mikeckennedy/python-switch for full details. - Copyright Michael Kennedy (https://twitter.com/mkennedy) + python-switch is a module-level implementation of the switch statement for Python. + See https://github.com/mikeckennedy/python-switch for full details. + Copyright Michael Kennedy (https://twitter.com/mkennedy) """ + __no_result = uuid.uuid4() __default = uuid.uuid4() @@ -58,7 +59,7 @@ def case(self, key, func: Callable[[], Any], fallthrough=False): if isinstance(key, list): if not key: - raise ValueError("You cannot pass an empty collection as the case. It will never match.") + raise ValueError('You cannot pass an empty collection as the case. It will never match.') found = False for i in key: @@ -70,11 +71,11 @@ def case(self, key, func: Callable[[], Any], fallthrough=False): return found if key in self.cases: - raise ValueError(f"Duplicate case: {key}") + raise ValueError(f'Duplicate case: {key}') if not func: - raise ValueError("Action for case cannot be None.") + raise ValueError('Action for case cannot be None.') if not callable(func): - raise ValueError("Func must be callable.") + raise ValueError('Func must be callable.') self.cases.add(key) if key == self.value or not self._found and key == self.__default: @@ -92,8 +93,9 @@ def __exit__(self, exc_type, exc_val, exc_tb): raise exc_val if not self._func_stack: - raise Exception("Value does not match any case and there " - "is no default case: value {}".format(self.value)) + raise Exception( + 'Value does not match any case and there ' 'is no default case: value {}'.format(self.value) + ) for func in self._func_stack: # noinspection PyCallingNonCallable @@ -102,14 +104,13 @@ def __exit__(self, exc_type, exc_val, exc_tb): @property def result(self): if self.__result == switch.__no_result: - raise Exception("No result has been computed (did you access " - "switch.result inside the with block?)") + raise Exception('No result has been computed (did you access ' 'switch.result inside the with block?)') return self.__result def closed_range(start: int, stop: int, step=1) -> range: if start >= stop: - raise ValueError("Start must be less than stop.") + raise ValueError('Start must be less than stop.') return range(start, stop + step, step) diff --git a/apps/py/ch04_oop/models/basic_car.py b/apps/py/ch04_oop/models/basic_car.py index 2624873..0c0935e 100644 --- a/apps/py/ch04_oop/models/basic_car.py +++ b/apps/py/ch04_oop/models/basic_car.py @@ -3,4 +3,4 @@ class BasicCar(Car): def refuel(self): - print("BasicCar: Basic cars take any old gas.") + print('BasicCar: Basic cars take any old gas.') diff --git a/apps/py/ch04_oop/models/car.py b/apps/py/ch04_oop/models/car.py index defb973..71165fd 100644 --- a/apps/py/ch04_oop/models/car.py +++ b/apps/py/ch04_oop/models/car.py @@ -2,7 +2,6 @@ class Car(abc.ABC): - def __init__(self, model_name: str, engine_type: str, cylinders: int, base_price: float): self.base_price: float = base_price self.cylinders: int = cylinders @@ -10,7 +9,7 @@ def __init__(self, model_name: str, engine_type: str, cylinders: int, base_price self.model_name: str = model_name def drive(self): - print(f"Car: The {self.model_name} goes vroom!") + print(f'Car: The {self.model_name} goes vroom!') @abc.abstractmethod def refuel(self): @@ -21,7 +20,7 @@ def is_electric(self): return self.engine_type == 'electric' def __str__(self): - return f"{type(self).__name__}: Model: {self.model_name}, price: ${self.base_price:,.0f}" + return f'{type(self).__name__}: Model: {self.model_name}, price: ${self.base_price:,.0f}' def __repr__(self): return self.__str__() diff --git a/apps/py/ch04_oop/models/electric_car.py b/apps/py/ch04_oop/models/electric_car.py index 042dbf0..ff04246 100644 --- a/apps/py/ch04_oop/models/electric_car.py +++ b/apps/py/ch04_oop/models/electric_car.py @@ -2,14 +2,13 @@ class ElectricCar(Car): - def __init__(self, model_name: str, base_price: float): # first! super().__init__(model_name, 'electric', 0, base_price) # then other stuff.. def drive(self): - print(f"ElectricCar: The electric {self.model_name} zooms silently along!") + print(f'ElectricCar: The electric {self.model_name} zooms silently along!') def refuel(self): print(f'ElectricCar: The {self.model_name} is charging up.') diff --git a/apps/py/ch04_oop/models/parking_lot.py b/apps/py/ch04_oop/models/parking_lot.py index 6d7e69d..fbea0f7 100644 --- a/apps/py/ch04_oop/models/parking_lot.py +++ b/apps/py/ch04_oop/models/parking_lot.py @@ -4,19 +4,15 @@ class ParkingLot: - def __init__(self, spot_names: List[str]): # self.spots = dict() # for n in spot_names: # self.spots[n] = None - self.spots: Dict[str, Optional[Car]] = { - n: None - for n in spot_names - } + self.spots: Dict[str, Optional[Car]] = {n: None for n in spot_names} @staticmethod - def create(spots_per_level: int, levels: int) -> "ParkingLot": + def create(spots_per_level: int, levels: int) -> 'ParkingLot': names = [] level_names = ['A', 'B', 'C', 'D', 'E', 'G'] for ln in level_names[:levels]: diff --git a/apps/py/ch04_oop/models/sports_car.py b/apps/py/ch04_oop/models/sports_car.py index 668df56..fb4487a 100644 --- a/apps/py/ch04_oop/models/sports_car.py +++ b/apps/py/ch04_oop/models/sports_car.py @@ -2,9 +2,8 @@ class SportsCar(Car): - def drive(self): - print(f"SportsCar: The {self.model_name} tears along the highway!") + print(f'SportsCar: The {self.model_name} tears along the highway!') def refuel(self): - print(f"SportsCar: The {self.model_name} only wants the best gas.") + print(f'SportsCar: The {self.model_name} only wants the best gas.') diff --git a/apps/py/ch04_oop/program.py b/apps/py/ch04_oop/program.py index 5791bcc..e3fe45c 100644 --- a/apps/py/ch04_oop/program.py +++ b/apps/py/ch04_oop/program.py @@ -22,12 +22,12 @@ def park_cars(cars: List[Car]): for spot, car in lot: if car: - print(f"Spot: {spot} has car {car}.") + print(f'Spot: {spot} has car {car}.') def use_cars(cars): for car in cars: - print(f"{car.model_name} is electric? {car.is_electric}") + print(f'{car.model_name} is electric? {car.is_electric}') car.drive() car.refuel() print() diff --git a/apps/py/ch05_pypi/scrape.py b/apps/py/ch05_pypi/scrape.py index 1feeff5..b040673 100644 --- a/apps/py/ch05_pypi/scrape.py +++ b/apps/py/ch05_pypi/scrape.py @@ -4,13 +4,13 @@ def main(): - print("Using Python packages") + print('Using Python packages') get_titles() def get_html(n: int) -> str: - print(Fore.YELLOW + f"Getting HTML for episode {n}...", flush=True) + print(Fore.YELLOW + f'Getting HTML for episode {n}...', flush=True) url = f'https://talkpython.fm/{n}' resp = httpx.get(url, follow_redirects=True) @@ -20,12 +20,12 @@ def get_html(n: int) -> str: def get_title_from_html(n: int, html: str) -> str: - print(Fore.CYAN + f"Getting TITLE for episode {n}...", flush=True) + print(Fore.CYAN + f'Getting TITLE for episode {n}...', flush=True) soup = bs4.BeautifulSoup(html, 'html.parser') header = soup.select_one('h1') if not header: - return "MISSING" + return 'MISSING' return header.text.strip() diff --git a/apps/py/ch06_memory/doomed.py b/apps/py/ch06_memory/doomed.py index 72594d6..d405a75 100644 --- a/apps/py/ch06_memory/doomed.py +++ b/apps/py/ch06_memory/doomed.py @@ -1,10 +1,10 @@ class Doomed: def __init__(self, *friends): self.friends = list(friends) - print(f"Created Doomed at {id(self)}") + print(f'Created Doomed at {id(self)}') def __del__(self): - print(f"DEL Doomed at {id(self)}") + print(f'DEL Doomed at {id(self)}') def __str__(self): return self.__repr__() diff --git a/apps/py/ch06_memory/mem_explorer.py b/apps/py/ch06_memory/mem_explorer.py index 09cf184..11e720f 100644 --- a/apps/py/ch06_memory/mem_explorer.py +++ b/apps/py/ch06_memory/mem_explorer.py @@ -9,7 +9,7 @@ def main(): print() print() gcing() - print("PROGRAM ENDING!", flush=True) + print('PROGRAM ENDING!', flush=True) def ref_counting(): @@ -18,18 +18,18 @@ def ref_counting(): v1 = Doomed() v1_id = id(v1) - print(f"Step 1: Ref count is {memutil.refs(v1_id)}") + print(f'Step 1: Ref count is {memutil.refs(v1_id)}') v2 = v1 - print(f"Step 2: Ref count is {memutil.refs(v1_id)}") + print(f'Step 2: Ref count is {memutil.refs(v1_id)}') v2 = None - print(f"Step 3: Ref count is {memutil.refs(v1_id)}") + print(f'Step 3: Ref count is {memutil.refs(v1_id)}') v1 = None - print(f"Step 4: Ref count is {memutil.refs(v1_id)}") + print(f'Step 4: Ref count is {memutil.refs(v1_id)}') - print("End of method!", flush=True) + print('End of method!', flush=True) def gcing(): @@ -42,25 +42,17 @@ def gcing(): v1_id = id(v1) v2_id = id(v2) - print(f"Step 1: GC count is {memutil.refs(v1_id)} {memutil.refs(v2_id)}") + print(f'Step 1: GC count is {memutil.refs(v1_id)} {memutil.refs(v2_id)}') v1 = None v2 = None - print(f"Step 2: GC count is {memutil.refs(v1_id)} {memutil.refs(v2_id)}") + print(f'Step 2: GC count is {memutil.refs(v1_id)} {memutil.refs(v2_id)}') gc.collect() - print(f"Step 3: GC count is {memutil.refs(v1_id)} {memutil.refs(v2_id)}") + print(f'Step 3: GC count is {memutil.refs(v1_id)} {memutil.refs(v2_id)}') - print("End of method!", flush=True) + print('End of method!', flush=True) if __name__ == '__main__': main() - - - - - - - - diff --git a/apps/py/ch06_memory/memutil.py b/apps/py/ch06_memory/memutil.py index 942216e..45be8d0 100644 --- a/apps/py/ch06_memory/memutil.py +++ b/apps/py/ch06_memory/memutil.py @@ -3,7 +3,7 @@ # We use ctypes module to access our unreachable objects by memory address. class PyObject(ctypes.Structure): - _fields_ = [("refcnt", ctypes.c_long)] + _fields_ = [('refcnt', ctypes.c_long)] def refs(obj_id) -> int: diff --git a/apps/py/ch07_web/guitary/data/guitar.py b/apps/py/ch07_web/guitary/data/guitar.py index f0800d0..760e9b8 100644 --- a/apps/py/ch07_web/guitary/data/guitar.py +++ b/apps/py/ch07_web/guitary/data/guitar.py @@ -1,5 +1,4 @@ class Guitar: - def __init__(self, name: str, price: float, img: str, style: str): self.style = style self.img = img diff --git a/apps/py/ch07_web/guitary/services/catalog_service.py b/apps/py/ch07_web/guitary/services/catalog_service.py index 0cf2f41..61dd049 100644 --- a/apps/py/ch07_web/guitary/services/catalog_service.py +++ b/apps/py/ch07_web/guitary/services/catalog_service.py @@ -20,10 +20,6 @@ def all_guitars(style: Optional[str]) -> List[Guitar]: if style is None or style == 'all': return guitars - filtered_guitars = [ - g - for g in guitars - if g.style == style - ] + filtered_guitars = [g for g in guitars if g.style == style] return filtered_guitars diff --git a/apps/py/ch07_web/speed_test.py b/apps/py/ch07_web/speed_test.py index b344f02..9240bae 100644 --- a/apps/py/ch07_web/speed_test.py +++ b/apps/py/ch07_web/speed_test.py @@ -9,9 +9,9 @@ def main(): url = input("What's the URL? ").strip() - times = int(input("How many rounds ? ")) + times = int(input('How many rounds ? ')) - print(f"Running timing against {url}, {times} times.") + print(f'Running timing against {url}, {times} times.') total_time = 0.0 with no_ssl_verification(): with requests.Session() as session: diff --git a/apps/py/ch07_web/wsgi.py b/apps/py/ch07_web/wsgi.py index 4fe26e7..68578b6 100644 --- a/apps/py/ch07_web/wsgi.py +++ b/apps/py/ch07_web/wsgi.py @@ -1,2 +1 @@ from guitary.app import app - diff --git a/apps/py/ch08_db/guitary/data/data_loader.py b/apps/py/ch08_db/guitary/data/data_loader.py index c4cec28..dbe810d 100644 --- a/apps/py/ch08_db/guitary/data/data_loader.py +++ b/apps/py/ch08_db/guitary/data/data_loader.py @@ -3,26 +3,31 @@ def load_guitars_if_empty(): - with session_factory.create_session() as ctx: count = ctx.session.query(Guitar).count() if count > 0: - print(f"Not adding new data, there are {count} guitars already.") + print(f'Not adding new data, there are {count} guitars already.') return guitars = [ Guitar(name='AX Black', price=499, img='/static/img/guitars/ax-black.jpg', style='electric'), - Guitar(name='Jet Black Electric', price=599, img='/static/img/guitars/jet-black-electric.jpg', - style='electric'), + Guitar( + name='Jet Black Electric', price=599, img='/static/img/guitars/jet-black-electric.jpg', style='electric' + ), Guitar(name='Weezer Classic', price=1499, img='/static/img/guitars/weezer-classic.jpg', style='electric'), Guitar(name='Acoustic Black', price=1298, img='/static/img/guitars/black-acoustic.jpg', style='acoustic'), Guitar(name='Mellow Yellow', price=799, img='/static/img/guitars/mellow-yellow.jpg', style='electric'), Guitar(name='White Vibes', price=699, img='/static/img/guitars/white-vibes.jpg', style='electric'), - Guitar(name='Brush Riffs', price=599, img='/static/img/guitars/brushed-black-electric.jpg', - style='electric'), + Guitar( + name='Brush Riffs', price=599, img='/static/img/guitars/brushed-black-electric.jpg', style='electric' + ), Guitar(name="Nature's Song", price=799, img='/static/img/guitars/natures-song.jpg', style='electric'), - Guitar(name='Electric Wood Grain', price=399, img='/static/img/guitars/woodgrain-electric.jpg', - style='electric'), + Guitar( + name='Electric Wood Grain', + price=399, + img='/static/img/guitars/woodgrain-electric.jpg', + style='electric', + ), ] # Do work here... diff --git a/apps/py/ch08_db/guitary/data/session_factory.py b/apps/py/ch08_db/guitary/data/session_factory.py index 3f449f3..8145f5b 100644 --- a/apps/py/ch08_db/guitary/data/session_factory.py +++ b/apps/py/ch08_db/guitary/data/session_factory.py @@ -24,7 +24,7 @@ def global_init(db_name: str): def create_tables(): if not __engine: - raise Exception("You must call global_init() first.") + raise Exception('You must call global_init() first.') # noinspection PyUnresolvedReferences from guitary.data.guitar import Guitar @@ -35,7 +35,7 @@ def create_tables(): def create_session() -> ContextSession: if not __factory: - raise Exception("You must call global_init() first.") + raise Exception('You must call global_init() first.') session = __factory() session.expire_on_commit = False diff --git a/apps/py/ch08_db/guitary/services/catalog_service.py b/apps/py/ch08_db/guitary/services/catalog_service.py index 6e4c997..115a5dd 100644 --- a/apps/py/ch08_db/guitary/services/catalog_service.py +++ b/apps/py/ch08_db/guitary/services/catalog_service.py @@ -12,8 +12,6 @@ def all_guitars(style: Optional[str]) -> List[Guitar]: return list(guitars) # noinspection PyUnresolvedReferences - filtered_guitars = list(ctx.session.query(Guitar) - .filter(Guitar.style == style) - .order_by(Guitar.price.desc())) + filtered_guitars = list(ctx.session.query(Guitar).filter(Guitar.style == style).order_by(Guitar.price.desc())) return filtered_guitars diff --git a/apps/py/ch09_testing/guitar_app.py b/apps/py/ch09_testing/guitar_app.py index 484fd4f..3e8cba0 100644 --- a/apps/py/ch09_testing/guitar_app.py +++ b/apps/py/ch09_testing/guitar_app.py @@ -2,16 +2,16 @@ def main(): - print("Welcome to the guitar app.") + print('Welcome to the guitar app.') while True: print() - style = input("What style of guitar do you want to see? ") + style = input('What style of guitar do you want to see? ') if not style: - print("cya") + print('cya') break guitars = lib.all_guitars(style) - print(f"We found {len(guitars)} guitars.") + print(f'We found {len(guitars)} guitars.') for idx, g in enumerate(guitars, start=1): print(f'{idx}. {g.name} for ${g.price:,.0f} ({g.style})') diff --git a/apps/py/ch09_testing/lib.py b/apps/py/ch09_testing/lib.py index 6b72431..acfbed9 100644 --- a/apps/py/ch09_testing/lib.py +++ b/apps/py/ch09_testing/lib.py @@ -3,8 +3,7 @@ class Guitar: - def __init__(self, name: str = None, price: float = 0.0, - img: str = None, style: str = None): + def __init__(self, name: str = None, price: float = 0.0, img: str = None, style: str = None): self.style = style self.img = img self.price = price @@ -17,27 +16,23 @@ def all_guitars(style: Optional[str]) -> List[Guitar]: style = style.lower() - log(f"Guitars for {style}") + log(f'Guitars for {style}') guitars = get_guitars_from_db() if style == 'all': return guitars - return [ - g - for g in guitars - if g.style == style - ] + return [g for g in guitars if g.style == style] def log(msg: str): # raise Exception("NO LOG!") - print(Fore.YELLOW + "LOGGING THIS TO A FILE, SHOULD NOT SEE IN TEST: " + Fore.WHITE + f"{msg}.") + print(Fore.YELLOW + 'LOGGING THIS TO A FILE, SHOULD NOT SEE IN TEST: ' + Fore.WHITE + f'{msg}.') # noinspection DuplicatedCode def get_guitars_from_db(): # raise Exception("NO DB!") - print(Fore.YELLOW + "GETTING GUITARS FROM DB! Should not see in test." + Fore.WHITE) + print(Fore.YELLOW + 'GETTING GUITARS FROM DB! Should not see in test.' + Fore.WHITE) # This guitar data simulates what we would actually get back from the database. guitars = [ Guitar('AX Black', 499, '/static/img/guitars/ax-black.jpg', style='electric'), diff --git a/apps/py/ch09_testing/test_lib.py b/apps/py/ch09_testing/test_lib.py index b9026bd..7893cec 100644 --- a/apps/py/ch09_testing/test_lib.py +++ b/apps/py/ch09_testing/test_lib.py @@ -4,6 +4,7 @@ import lib import pytest_mock + # noinspection PyUnresolvedReferences from test_fixtures import guitar_data diff --git a/apps/py/ch10_async/ascrape.py b/apps/py/ch10_async/ascrape.py index 6a514df..f34fd76 100644 --- a/apps/py/ch10_async/ascrape.py +++ b/apps/py/ch10_async/ascrape.py @@ -6,17 +6,17 @@ def main(): - print("Python async web scraper") + print('Python async web scraper') t0 = datetime.datetime.now() get_titles().result() dt = datetime.datetime.now() - t0 - print(f"Finished in {dt.total_seconds():,.2f} seconds.") + print(f'Finished in {dt.total_seconds():,.2f} seconds.') @unsync async def get_html(n: int) -> str: - print(Fore.YELLOW + f"Getting HTML for episode {n}...", flush=True) + print(Fore.YELLOW + f'Getting HTML for episode {n}...', flush=True) url = f'https://talkpython.fm/{n}' # The "async with" syntax ensures that all active connections are closed on exit. @@ -30,12 +30,12 @@ async def get_html(n: int) -> str: # @unsync # <-- will run get_title_from_html() on a background thread. # @unsync(cpu_bound=True) # <-- will run get_title_from_html() on a subprocess. def get_title_from_html(n: int, html: str) -> str: - print(Fore.CYAN + f"Getting TITLE for episode {n}...", flush=True) + print(Fore.CYAN + f'Getting TITLE for episode {n}...', flush=True) soup = bs4.BeautifulSoup(html, 'html.parser') header = soup.select_one('h1') if not header: - return "MISSING" + return 'MISSING' return header.text.strip() @@ -46,6 +46,7 @@ def get_title_from_html(n: int, html: str) -> str: # title = get_title_from_html(n, html) # print(Fore.GREEN + title) + @unsync async def get_titles(): tasks = [] diff --git a/apps/py/ch11_notebooks/lorenz.py b/apps/py/ch11_notebooks/lorenz.py index c83aab2..95c02b4 100644 --- a/apps/py/ch11_notebooks/lorenz.py +++ b/apps/py/ch11_notebooks/lorenz.py @@ -3,7 +3,8 @@ import numpy as np from scipy import integrate -def solve_lorenz(sigma=10.0, beta=8./3, rho=28.0): + +def solve_lorenz(sigma=10.0, beta=8.0 / 3, rho=28.0): """Plot a solution to the Lorenz differential equations.""" max_time = 4.0 @@ -17,7 +18,7 @@ def solve_lorenz(sigma=10.0, beta=8./3, rho=28.0): ax.set_xlim((-25, 25)) ax.set_ylim((-35, 35)) ax.set_zlim((5, 55)) - + def lorenz_deriv(x_y_z, t0, sigma=sigma, beta=beta, rho=rho): """Compute the time-derivative of a Lorenz system.""" x, y, z = x_y_z @@ -28,19 +29,18 @@ def lorenz_deriv(x_y_z, t0, sigma=sigma, beta=beta, rho=rho): x0 = -15 + 30 * np.random.random((N, 3)) # Solve for the trajectories - t = np.linspace(0, max_time, int(250*max_time)) - x_t = np.asarray([integrate.odeint(lorenz_deriv, x0i, t) - for x0i in x0]) - + t = np.linspace(0, max_time, int(250 * max_time)) + x_t = np.asarray([integrate.odeint(lorenz_deriv, x0i, t) for x0i in x0]) + # choose a different color for each trajectory colors = plt.cm.viridis(np.linspace(0, 1, N)) for i in range(N): - x, y, z = x_t[i,:,:].T + x, y, z = x_t[i, :, :].T lines = ax.plot(x, y, z, '-', c=colors[i]) plt.setp(lines, linewidth=2) angle = 104 ax.view_init(30, angle) plt.show() - return t, x_t \ No newline at end of file + return t, x_t diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..5537773 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,42 @@ +# [ruff] +line-length = 120 +format.quote-style = "single" + +# Enable Pyflakes `E` and `F` codes by default. +select = ["E", "F"] +ignore = [] + +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".ruff_cache", + ".svn", + ".tox", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + ".env", + ".venv", + "venv", +] +per-file-ignores = {} + +# Allow unused variables when underscore-prefixed. +# dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +# Assume Python 3.11. +target-version = "py311" + +#[tool.ruff.mccabe] +## Unlike Flake8, default to a complexity level of 10. +mccabe.max-complexity = 10 From afd61c1b73674a3b5979dac374af17afc3325130 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:01:43 -0800 Subject: [PATCH 09/12] Update server deployment due to let's encrypt setup changes. --- .../server_setup/server_setup.sh | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/apps/py/ch12_deployment/server_setup/server_setup.sh b/apps/py/ch12_deployment/server_setup/server_setup.sh index da5682e..ceeeb0c 100644 --- a/apps/py/ch12_deployment/server_setup/server_setup.sh +++ b/apps/py/ch12_deployment/server_setup/server_setup.sh @@ -15,8 +15,9 @@ sudo apt-get install -y -q nginx # for gzip support in uwsgi sudo apt-get install --no-install-recommends -y -q libpcre3-dev libz-dev -# Stop the hackers -sudo apt install fail2ban -y +# Fail2ban no longer supported +# Skip this for now. +# sudo apt install fail2ban -y ufw allow 22 ufw allow 80 @@ -78,9 +79,27 @@ update-rc.d nginx enable service nginx restart -# Optionally add SSL support via Let's Encrypt: -# https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04 +# Optionally add SSL support via Let's Encrypt +# NOTE: These steps have changed since the recording. -add-apt-repository ppa:certbot/certbot -apt install python-certbot-nginx +####### NEW STEPS ############################################### +# See https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal&tab=standard + +# Because always a good idea :) +apt update +apt upgrade + +# Not need even though it's in the instructions, is installed on Ubuntu +# Skip -> install snapd https://snapcraft.io/docs/installing-snapd + +snap install --classic certbot +ln -s /snap/bin/certbot /usr/bin/certbot certbot --nginx -d guitary.talkpython.com + +####### THESE ARE THE OLD STEPS ################################# +# +## https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04 +# +#add-apt-repository ppa:certbot/certbot +#apt install python-certbot-nginx +#certbot --nginx -d guitary.talkpython.com From cb55f19ae490b91ff6878d52e6a457a46937cc06 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 3 Apr 2024 17:42:52 +0200 Subject: [PATCH 10/12] Update to dotnet8, update all nugets --- apps/net/Ch3_Lang/Ch3_Lang.csproj | 4 +- apps/net/Ch4_OOP/Ch4_OOP.csproj | 2 +- apps/net/Ch5_nuget/Ch5_nuget.csproj | 2 +- apps/net/Ch6_Web/Ch6_Web.csproj | 2 +- apps/net/Ch7_Db/Ch7_Db.csproj | 6 +- apps/net/Ch8_Testing/Ch8_Testing.csproj | 12 ++-- .../Ch8_Testing_App/Ch8_Testing_App.csproj | 2 +- apps/net/Ch9_Async/Ch9_Async.csproj | 69 ++++--------------- apps/net/Ch9_Async/Program.cs | 6 +- apps/net/Ch9_Async/Properties/AssemblyInfo.cs | 26 ------- apps/net/Ch9_Async/packages.config | 7 -- apps/net/net.sln | 10 +-- 12 files changed, 35 insertions(+), 113 deletions(-) delete mode 100644 apps/net/Ch9_Async/Properties/AssemblyInfo.cs delete mode 100644 apps/net/Ch9_Async/packages.config diff --git a/apps/net/Ch3_Lang/Ch3_Lang.csproj b/apps/net/Ch3_Lang/Ch3_Lang.csproj index 5a59ec4..0e3cc8f 100644 --- a/apps/net/Ch3_Lang/Ch3_Lang.csproj +++ b/apps/net/Ch3_Lang/Ch3_Lang.csproj @@ -2,12 +2,12 @@ Exe - netcoreapp2.1 + net8.0 - + diff --git a/apps/net/Ch4_OOP/Ch4_OOP.csproj b/apps/net/Ch4_OOP/Ch4_OOP.csproj index 898ad85..5670ae8 100644 --- a/apps/net/Ch4_OOP/Ch4_OOP.csproj +++ b/apps/net/Ch4_OOP/Ch4_OOP.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.0 + net8.0 diff --git a/apps/net/Ch5_nuget/Ch5_nuget.csproj b/apps/net/Ch5_nuget/Ch5_nuget.csproj index ada5ca1..bfcc8a2 100644 --- a/apps/net/Ch5_nuget/Ch5_nuget.csproj +++ b/apps/net/Ch5_nuget/Ch5_nuget.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.0 + net8.0 diff --git a/apps/net/Ch6_Web/Ch6_Web.csproj b/apps/net/Ch6_Web/Ch6_Web.csproj index bb9ffce..c255d1e 100644 --- a/apps/net/Ch6_Web/Ch6_Web.csproj +++ b/apps/net/Ch6_Web/Ch6_Web.csproj @@ -1,7 +1,7 @@ - netcoreapp3.0 + net8.0 diff --git a/apps/net/Ch7_Db/Ch7_Db.csproj b/apps/net/Ch7_Db/Ch7_Db.csproj index 01759ca..4bd60f4 100644 --- a/apps/net/Ch7_Db/Ch7_Db.csproj +++ b/apps/net/Ch7_Db/Ch7_Db.csproj @@ -1,7 +1,7 @@ - netcoreapp3.0 + net8.0 @@ -30,7 +30,7 @@ - - + + diff --git a/apps/net/Ch8_Testing/Ch8_Testing.csproj b/apps/net/Ch8_Testing/Ch8_Testing.csproj index 9a9abc2..2d55ab6 100644 --- a/apps/net/Ch8_Testing/Ch8_Testing.csproj +++ b/apps/net/Ch8_Testing/Ch8_Testing.csproj @@ -1,19 +1,19 @@ - netcoreapp3.0 + net8.0 false - - - - runtime; build; native; contentfiles; analyzers; buildtransitive + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/apps/net/Ch8_Testing_App/Ch8_Testing_App.csproj b/apps/net/Ch8_Testing_App/Ch8_Testing_App.csproj index a1ed464..7282f46 100644 --- a/apps/net/Ch8_Testing_App/Ch8_Testing_App.csproj +++ b/apps/net/Ch8_Testing_App/Ch8_Testing_App.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.0 + net8.0 diff --git a/apps/net/Ch9_Async/Ch9_Async.csproj b/apps/net/Ch9_Async/Ch9_Async.csproj index e091d2b..b89bed3 100644 --- a/apps/net/Ch9_Async/Ch9_Async.csproj +++ b/apps/net/Ch9_Async/Ch9_Async.csproj @@ -1,55 +1,14 @@ - - - - Debug - AnyCPU - {82E0B15C-BE72-4F3D-97EB-DA3736244FC4} - Exe - Ch9_Async - Ch8_Async - v4.7.2 - true - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - MSB3276 - - - true - bin\Release - prompt - 4 - true - - - - - ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll - - - ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - - - - - ..\packages\HtmlAgilityPack.1.11.16\lib\Net45\HtmlAgilityPack.dll - - - - - - - - - - - - - \ No newline at end of file + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/apps/net/Ch9_Async/Program.cs b/apps/net/Ch9_Async/Program.cs index 9719381..a6c4cfe 100644 --- a/apps/net/Ch9_Async/Program.cs +++ b/apps/net/Ch9_Async/Program.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; +using System.Diagnostics; using System.Net; -using System.Net.Http; -using System.Threading.Tasks; using HtmlAgilityPack; namespace Ch9_Async diff --git a/apps/net/Ch9_Async/Properties/AssemblyInfo.cs b/apps/net/Ch9_Async/Properties/AssemblyInfo.cs deleted file mode 100644 index bef6021..0000000 --- a/apps/net/Ch9_Async/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("Ch8_Async")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("PDX Web Properties, LLC")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] diff --git a/apps/net/Ch9_Async/packages.config b/apps/net/Ch9_Async/packages.config deleted file mode 100644 index 2ba22b5..0000000 --- a/apps/net/Ch9_Async/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/apps/net/net.sln b/apps/net/net.sln index f42009a..cb22f1d 100644 --- a/apps/net/net.sln +++ b/apps/net/net.sln @@ -17,7 +17,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch8_Testing", "Ch8_Testing\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch8_Testing_App", "Ch8_Testing_App\Ch8_Testing_App.csproj", "{DC35108D-5189-4BC2-8303-5B4799B6A625}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch9_Async", "Ch9_Async\Ch9_Async.csproj", "{82E0B15C-BE72-4F3D-97EB-DA3736244FC4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch9_Async", "Ch9_Async\Ch9_Async.csproj", "{F5C28307-BF7E-419E-97FC-26CC76ECFEF7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -53,10 +53,10 @@ Global {DC35108D-5189-4BC2-8303-5B4799B6A625}.Debug|Any CPU.Build.0 = Debug|Any CPU {DC35108D-5189-4BC2-8303-5B4799B6A625}.Release|Any CPU.ActiveCfg = Release|Any CPU {DC35108D-5189-4BC2-8303-5B4799B6A625}.Release|Any CPU.Build.0 = Release|Any CPU - {82E0B15C-BE72-4F3D-97EB-DA3736244FC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {82E0B15C-BE72-4F3D-97EB-DA3736244FC4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {82E0B15C-BE72-4F3D-97EB-DA3736244FC4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {82E0B15C-BE72-4F3D-97EB-DA3736244FC4}.Release|Any CPU.Build.0 = Release|Any CPU + {F5C28307-BF7E-419E-97FC-26CC76ECFEF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5C28307-BF7E-419E-97FC-26CC76ECFEF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5C28307-BF7E-419E-97FC-26CC76ECFEF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5C28307-BF7E-419E-97FC-26CC76ECFEF7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 9c662d66de04148699985230bfe59514b55485a6 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 22 Aug 2025 11:32:57 -0700 Subject: [PATCH 11/12] Add some vscode config settings. --- .vscode/launch.json | 35 +++++++++++++++++++++++++++++++++++ .vscode/tasks.json | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e960a6a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,35 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md. + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/apps/net/Ch6_Web/bin/Debug/net8.0/Ch6_Web.dll", + "args": [], + "cwd": "${workspaceFolder}/apps/net/Ch6_Web", + "stopAtEntry": false, + // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a151094 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/apps/net/net.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/apps/net/net.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/apps/net/net.sln" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file From ab250b79d828b706b1f1c374022969ebb39fdc51 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 22 Aug 2025 11:33:54 -0700 Subject: [PATCH 12/12] Update to the latest versions of dependencies. --- apps/py/requirements.txt | 101 +++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/apps/py/requirements.txt b/apps/py/requirements.txt index daa7db3..0e6648b 100644 --- a/apps/py/requirements.txt +++ b/apps/py/requirements.txt @@ -1,117 +1,116 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -anyio==4.1.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +anyio==4.10.0 # via httpx -beautifulsoup4==4.12.2 +beautifulsoup4==4.13.4 # via bs4 -blinker==1.7.0 +blinker==1.9.0 # via flask -bs4==0.0.1 +bs4==0.0.2 # via -r requirements.piptools -certifi==2023.11.17 +certifi==2025.8.3 # via # httpcore # httpx # requests -charset-normalizer==3.3.2 +charset-normalizer==3.4.3 # via requests -click==8.1.7 +click==8.2.1 # via flask colorama==0.4.6 # via -r requirements.piptools -contourpy==1.2.0 +contourpy==1.3.3 # via matplotlib cycler==0.12.1 # via matplotlib -flask==3.0.0 +flask==3.1.2 # via -r requirements.piptools -fonttools==4.46.0 +fonttools==4.59.1 # via matplotlib -h11==0.14.0 +h11==0.16.0 # via httpcore -httpcore==1.0.2 +httpcore==1.0.9 # via httpx -httpx==0.25.2 +httpx==0.28.1 # via -r requirements.piptools -idna==3.6 +idna==3.10 # via # anyio # httpx # requests -iniconfig==2.0.0 +iniconfig==2.1.0 # via pytest -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.6 # via flask -kiwisolver==1.4.5 +kiwisolver==1.4.9 # via matplotlib -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich -markupsafe==2.1.3 +markupsafe==3.0.2 # via + # flask # jinja2 # werkzeug -matplotlib==3.8.2 +matplotlib==3.10.5 # via -r requirements.piptools mdurl==0.1.2 # via markdown-it-py -numpy==1.26.2 +numpy==2.3.2 # via # -r requirements.piptools # contourpy # matplotlib # scipy -packaging==23.2 +packaging==25.0 # via # matplotlib # pytest -pillow==10.1.0 +pillow==11.3.0 # via matplotlib -pluggy==1.3.0 +pluggy==1.6.0 # via pytest pprintpp==0.4.0 # via pytest-clarity -pygments==2.17.2 - # via rich -pyparsing==3.1.1 +pygments==2.19.2 + # via + # pytest + # rich +pyparsing==3.2.3 # via matplotlib -pytest==7.4.3 +pytest==8.4.1 # via # -r requirements.piptools # pytest-clarity # pytest-mock pytest-clarity==1.0.1 # via -r requirements.piptools -pytest-mock==3.12.0 +pytest-mock==3.14.1 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via matplotlib -requests==2.31.0 +requests==2.32.5 # via -r requirements.piptools -rich==13.7.0 +rich==14.1.0 # via pytest-clarity -scipy==1.11.4 +scipy==1.16.1 # via -r requirements.piptools -six==1.16.0 +six==1.17.0 # via python-dateutil -sniffio==1.3.0 - # via - # anyio - # httpx -soupsieve==2.5 +sniffio==1.3.1 + # via anyio +soupsieve==2.7 # via beautifulsoup4 -sqlalchemy==2.0.23 +sqlalchemy==2.0.43 # via -r requirements.piptools -typing-extensions==4.9.0 - # via sqlalchemy +typing-extensions==4.14.1 + # via + # beautifulsoup4 + # sqlalchemy unsync==1.4.0 # via -r requirements.piptools -urllib3==2.1.0 +urllib3==2.5.0 # via requests -werkzeug==3.0.1 +werkzeug==3.1.3 # via flask