<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Python for Engineers]]></title><description><![CDATA[Now Powered by Flux Capacitors! And with 100% more Electrolytes]]></description><link>https://new.pythonforengineers.com/</link><image><url>https://new.pythonforengineers.com/favicon.png</url><title>Python for Engineers</title><link>https://new.pythonforengineers.com/</link></image><generator>Ghost 5.79</generator><lastBuildDate>Tue, 20 Feb 2024 09:13:48 GMT</lastBuildDate><atom:link href="https://new.pythonforengineers.com/blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[LinkedIn Has Become a Pile of Garbage (even more than usual)]]></title><description><![CDATA[<p></p><p>Online forums, especially Hacker News and Reddit, are very hostile to LinkedIn. Everyone makes fun of the self-promotion and <a href="https://old.reddit.com/r/LinkedInLunatics/?ref=new.pythonforengineers.com" rel="noreferrer">silliness that goes there.</a> There are complaints the site is unusable, which I didn&apos;t agree with until now.</p><p> I&apos;ve had an account there for a few years.</p>]]></description><link>https://new.pythonforengineers.com/blog/linkedin-has-become-a-piece-of-garbage-even-more-than-usual/</link><guid isPermaLink="false">65b79611f4c1cf00011ee90b</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Mon, 29 Jan 2024 17:48:44 GMT</pubDate><media:content url="https://new.pythonforengineers.com/content/images/2024/01/ae223740-840b-4d4a-9467-2522a67dcbbc.png" medium="image"/><content:encoded><![CDATA[<img src="https://new.pythonforengineers.com/content/images/2024/01/ae223740-840b-4d4a-9467-2522a67dcbbc.png" alt="LinkedIn Has Become a Pile of Garbage (even more than usual)"><p></p><p>Online forums, especially Hacker News and Reddit, are very hostile to LinkedIn. Everyone makes fun of the self-promotion and <a href="https://old.reddit.com/r/LinkedInLunatics/?ref=new.pythonforengineers.com" rel="noreferrer">silliness that goes there.</a> There are complaints the site is unusable, which I didn&apos;t agree with until now.</p><p> I&apos;ve had an account there for a few years. I used one simple rule to make the site usable:</p><blockquote>Only add people I&apos;ve met in real life to my friend list, and then only colleagues.</blockquote><p></p><p>The reason I have an account at all is I like to keep up with my colleagues from old companies. It&apos;s always nice to see what people have been up to. Second, while I haven&apos;t found a job thru it, many recruiters have reached out so its worth keeping a presence there.</p><p>So far, LinkedIn has been sort of usable. I would log in 2-3 times a  week, to see what was happening.</p><p>But recently, I realised LN had turned into a big steaming pile of dog poo</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/data-src-image-81b5896f-5eb7-47c7-bb89-752e55ac84bc.jpeg" class="kg-image" alt="LinkedIn Has Become a Pile of Garbage (even more than usual)" loading="lazy" width="768" height="432" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/data-src-image-81b5896f-5eb7-47c7-bb89-752e55ac84bc.jpeg 600w, https://new.pythonforengineers.com/content/images/2024/01/data-src-image-81b5896f-5eb7-47c7-bb89-752e55ac84bc.jpeg 768w" sizes="(min-width: 720px) 720px"></figure><p></p><h3 id="travels-thru-poop-land">Travels Thru Poop Land</h3><p></p><p>The 1st I realised something was wrong was when I saw a post from an old colleague, saying they had found a job. I typed in a quick congrats and sent it.</p><p>Then I saw the date on the message: It was 3 months old. They had found a job 3 months ago, it had turned up on my feed just then.</p><p>I thought it was a coincidence but then it happened again. This time, the 2-month-old post was shown to me <strong>5 times</strong>. I was like, yeah, I get it. Is nothing else happening to the people in my feed? I know there is, because if I go on their profiles I can see them posting. It&apos;s just not turning up on my home page.</p><h3 id="but-wait-it-gets-worse">But wait! It gets worse...</h3><p></p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/data-src-image-26fd169d-9c54-4b3e-a80d-03f102228eeb.jpeg" class="kg-image" alt="LinkedIn Has Become a Pile of Garbage (even more than usual)" loading="lazy" width="577" height="433"></figure><p>Listen, I&apos;m a capitalist. I get it, companies need to make money. I&apos;m okay with some ads.</p><p>What I&apos;m not okay with is 8-10 ads for 1 post from my feed. I had so many ads (and I counted&#x2013; 10:1 was a standard ratio of ads:post), that I couldn&apos;t see the posts from the people I had connected to.</p><p>And it wasn&apos;t normal ads&#x2013; Ads on LinkedIn show up as &quot;Promoted&quot;. These are okay&#x2013; I&apos;ve never clicked on one, but at least some are useful.</p><p>But LinkedIn has started showing these &quot;Suggested&quot; posts by random weirdos on the internet. Most of them are garbage&#x2013; they are from the sort of SEO spammy sites we see on Google and the reason I avoid using Google.</p><p>One post was like: <em>Top 7 API methods in Java</em></p><p>and I was like, I&apos;ve never even used Java. If Java was crossing the road and met my gaze, I would be like, <em>Who are you, Bro?</em></p><p>The posts are the classic spammy ones&#x2013; you can tell by the titles and the slick images:</p><p><strong><em>The 7 best ways to test your web app (Number 3 will shock you!)</em></strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://files.oaiusercontent.com/file-aAVy2CQgzAWeTOGIcVvWEcsb?se=2024-01-29T14%3A47%3A35Z&amp;sp=r&amp;sv=2021-08-06&amp;sr=b&amp;rscc=max-age%3D31536000%2C%20immutable&amp;rscd=attachment%3B%20filename%3D5c11a09c-5598-4e6d-96d6-e4829f2e6ca6.webp&amp;sig=0wN777p2ak8%2BHjFea4kAqiziciHuL6PvFnyf0mld3rw%3D" class="kg-image" alt="LinkedIn Has Become a Pile of Garbage (even more than usual)" loading="lazy" width="1792" height="1024"><figcaption><span style="white-space: pre-wrap;">An AI generated image for sleazy website. Sigh, this is the best I could get with Dalle</span></figcaption></figure><p></p><p>Why is LinkedIn showing me this garbage? Are they getting money from spammy sites to promote their crappy posts? If so, why don&apos;t these show up as &quot;Promoted&quot; instead of &quot;Suggested&quot;?</p><h3 id="but-wait-it-gets-even-worse">But wait! It gets even worse!</h3><p></p><p>I&apos;ve been looking for a job, so I&apos;ve set my status to &quot;Open to Work&quot;. </p><p>Last week, LinkedIn decided I was a hiring manager, and asked if I wanted to become a recruiter on their site. And I was like, how can I be hiring people when I&apos;m looking for a job myself. It&apos;s so stupid I had to take a screenshot and make a post on LinkedIn:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-29-at-12.39.51@2x.png" class="kg-image" alt="LinkedIn Has Become a Pile of Garbage (even more than usual)" loading="lazy" width="2000" height="576" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/CleanShot-2024-01-29-at-12.39.51@2x.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/CleanShot-2024-01-29-at-12.39.51@2x.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2024/01/CleanShot-2024-01-29-at-12.39.51@2x.png 1600w, https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-29-at-12.39.51@2x.png 2000w" sizes="(min-width: 720px) 720px"></figure><p></p><h3 id="other-issues">Other issues</h3><p>I&apos;ve stopped getting notifications when people reply to my posts or to a comment I posted. Someone posted a thoughtful comment and question to one of my posts, but I never got a notification and so never noticed it. Until this week, when I manually went back and looked at my posts. The person probably thought I was rude or didn&apos;t care.</p><p>It doesn&apos;t help that to see my own posts I have to click 5-6 times. &#x1F640;</p><p>I didn&apos;t change any settings, so it must have been something LinkedIn did.</p><p>So not only can I not see any posts from my network, but if someone is trying to talk to me, they can&apos;t! Unless they pay $$ to Linkedin and join the recruiter plan.</p><h3 id="in-summary">In Summary</h3><p></p><p>People have been complaining about LN for years, but at least it was doing the basic jobs I expected from it:</p><ol><li>Keep me connected to people I&apos;ve worked with</li><li>Connect me with recruiters</li></ol><p>As of now, (1) doesn&apos;t work at all, as I can&apos;t see any posts from my network because of all the spam. (2) sort of works, but there haven&apos;t been any jobs recently. Like 0.00 in the last 2 months.</p><p>The recruiter part of LinkedIn, as I said, still sort of works; but, every job site has a &quot;Share my CV with recruiters&quot; option&#x2013; why do I need to waste time on LinkedIn?</p><p><strong>There&apos;s even a word for this:</strong></p><p>Enshittification, created by Cory Doctrow. From <a href="https://en.wikipedia.org/wiki/Enshittification?ref=new.pythonforengineers.com" rel="noreferrer">Wikipedia</a>:</p><blockquote>According to Doctorow, new platforms offer useful products and services at a loss, as a way to gain new users. Once users are locked in, the platform then offers access to the userbase to suppliers at a loss, and once suppliers are locked-in, the platform shifts surpluses to shareholders. Once the platform is fundamentally focused on the shareholders, and the users and vendors are locked in, the platform no longer has any incentive to maintain quality.</blockquote><p></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[The Tech Bro's Hypocrisy about AI and IP Theft is Incredible]]></title><description><![CDATA[<p>Some time ago there was a post that Github(owned by Microsoft) was training its data on public code repos. And there was predictable outrage about code being &quot;stolen&quot; by a greedy corporation.</p><p>The key thing is: Most of the programmers had <strong>willingly </strong>put their code on GitHub</p>]]></description><link>https://new.pythonforengineers.com/blog/the-techbros-hypcricy-about-ai-and-ip-theft-is-icnredible/</link><guid isPermaLink="false">65a7fb673f4a4b00017873ae</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Fri, 19 Jan 2024 17:47:56 GMT</pubDate><content:encoded><![CDATA[<p>Some time ago there was a post that Github(owned by Microsoft) was training its data on public code repos. And there was predictable outrage about code being &quot;stolen&quot; by a greedy corporation.</p><p>The key thing is: Most of the programmers had <strong>willingly </strong>put their code on GitHub and with permissive licenses like MIT (or similar), which meant anyone could copy/reuse their code. But then they got angry when the evil M$oft took their code.</p><p>(To be fair, there were claims that MS might have copied copyrighted code, and a GitHub <a href="https://news.ycombinator.com/item?id=33228687&amp;ref=new.pythonforengineers.com" rel="noreferrer">engineer gave his opinions here)</a></p><p>And then the same big corporations went after artists and started stealing (sorry, &quot;borrowing&quot;) their work to train their AIs. You think our programmers would have sympathy with the artists work being stolen by big corporations, just as theirs was?</p><figure class="kg-card kg-image-card"><img src="https://i.imgflip.com/8ctc34.jpg" class="kg-image" alt loading="lazy"></figure><p></p><p><strong>The New AI &quot;Artists&quot;</strong></p><p>There was a very moving comic by the creator of Cat and Girl about how she found out she was one of the artists whose work had been stolen by AI.</p><p>I recommend you read the whole comic: <a href="https://catandgirl.com/4000-of-my-closest-friends/?ref=new.pythonforengineers.com">https://catandgirl.com/4000-of-my-closest-friends/</a></p><p>The artist says (in the comic): She can&apos;t get her cartoons to most people without doing free work for huge corporations(I&apos;m guessing she means Facebook/X etc, which act as middlemen now and take away most of the ad money).  But then the AI companies even took away that option and just took her work.</p><p>And this time, the comments by the Techbros were completely different:</p><ul><li>Muhhh, we can&apos;t stop progress</li><li>Copyright rules are stupid anyway</li><li>What can we do? Artists are going the way of the dodo</li><li>&quot;Art&quot; is subjective anyway</li></ul><p>One comment says artists take inspiration from others anyway, and AI is just taking &quot;inspiration&quot; from them. And instead of using a pen or tablet, we can now use AI. (I won&apos;t link to the comment, it is too idiotic).</p><p><strong>Then they came for me</strong></p><p>And that&apos;s the hypocrisy. Programmers are A-OK when other people&apos;s work and career is being destroyed, &quot;It&apos;s science bro, can&apos;t stop it, man,&quot; but throw tantrums when their <em>own </em>work is stolen.</p><figure class="kg-card kg-image-card"><img src="https://i.imgflip.com/8csrjw.jpg" class="kg-image" alt loading="lazy"></figure><p></p><p><strong>I don&apos;t have any solution</strong></p><p>I don&apos;t know what the solution is. I know many artists are suing the AI companies, as is the New York Times. These court cases will take years, if not decades; and we have no idea what will happen in the meantime. AI technology is moving at the speed of light, but courts move at the speed of...courts? Because even snails are faster than the legal system.</p><p>So I don&apos;t what the future of the artists is.  </p><p>But I did find how hypocritical the dude-bro programmers acted, the complete 180 degrees U-turn when it was someone else&apos;s work being stolen. </p><p>I  must say, not all coders are jerks,  I did find people asking other programmers to be empathetic to those scared of AI. I found <a href="https://news.ycombinator.com/item?id=33998876&amp;ref=new.pythonforengineers.com" rel="noreferrer">this comment on HN is very heartful</a> (just don&apos;t read the replies to it):</p><blockquote>I&apos;ve been finding that the strangest part of discussions around art AI among technical people is the complete lack of identification or empathy: it seems to me that most computer programmers should be just as afraid as artists, in the face of technology like this!!! <br>&lt;snipped&gt;<br>The lack of empathy is incredibly depressing...</blockquote><p></p><p><strong>A positive future?</strong></p><p>That said, I am hopeful for the long term future, though I admit <em>it will be bad for many artists short term</em>:</p><ul><li>I am hopeful a positive legal solution will be found that supports artists while still allowing AI companies to progress</li><li>In my own experience as a developer, I find AI tools 10x my productivity&#x2013; removing all the boring &quot;donkey&quot; work I had to do previously. I am hopeful it will be similarly helpful to all artists.</li></ul><p>Until then, to misquote Jesus: <em>Truly I tell you, if you have compassion as small as a mustard seed, you will sound less like a douchebag and more like a human being.</em></p>]]></content:encoded></item><item><title><![CDATA[The 1xers Guide to LLM, ChatGpt & AI]]></title><description><![CDATA[<h3 id="alt-title-llm-vs-chatgpt-vs-huggingface-vs-llama-vs-other-fancy-ai-terms-you-may-have-heard-but-had-no-idea-what-they-meant">Alt Title: LLM vs ChatGpt vs HuggingFace vs Llama vs <em>Other Fancy AI Terms You may have heard but had no idea what they meant</em></h3><h3 id></h3><p></p><p>I struggled to understand what all these AI terms meant: LLMs, Llamas (not the animal from Peru!). Though I had used ChatGpt, I wasn&apos;</p>]]></description><link>https://new.pythonforengineers.com/blog/the-1xers-guide-to-llm-chatgpt-ai/</link><guid isPermaLink="false">659574a73f4a4b0001787096</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Thu, 11 Jan 2024 11:30:24 GMT</pubDate><content:encoded><![CDATA[<h3 id="alt-title-llm-vs-chatgpt-vs-huggingface-vs-llama-vs-other-fancy-ai-terms-you-may-have-heard-but-had-no-idea-what-they-meant">Alt Title: LLM vs ChatGpt vs HuggingFace vs Llama vs <em>Other Fancy AI Terms You may have heard but had no idea what they meant</em></h3><h3 id></h3><p></p><p>I struggled to understand what all these AI terms meant: LLMs, Llamas (not the animal from Peru!). Though I had used ChatGpt, I wasn&apos;t aware of all the intricacies. Why did everyone keep linking to HuggingFace, and what was the big deal about Ollama? How is that different from Llama v2?</p><p>Since I had some time over the Christmas holidays, I spent some time playing with these to get what all these terms mean.</p><p>This article is meant for end users (mainly engineers) who like me are confused with how the whole new AI world works. I&apos;ll try to explain what the terms mean and how you can get started in AI (or move beyond using the web version of ChatGPT), including how to run LLMs locally (if you don&apos;t know what that means, keep reading!). If nothing else, you can appear smart in conversations.</p><figure class="kg-card kg-image-card"><img src="https://i.imgflip.com/8b65if.jpg" class="kg-image" alt loading="lazy"></figure><p>The field is moving ultrafast (even when you take into consideration that software moves fast in general). AI companies make traditional software look like steel manufacturers. But if you know the fundamentals, it&apos;s easier to keep up to date with what&apos;s happening.</p><p>In this post, I will go over what  LLMs are, and how to run them locally.</p><h3 id="what-is-a-llm-large-language-model">What is a LLM (Large Language Model)</h3><p>The core of ChatGpt etc is a LLM, which is a computer program that can understand, interpret, generate and respond to human languages. The key it can not only understand and interpret, but it can respond in a somewhat intelligent way, and can even generate text (like when you ask it to write a computer program).</p><p>The best explanation of how LLMs work is this one by Stephen Wolfram <a href="https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/?ref=new.pythonforengineers.com">https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/</a></p><p></p><p>I will try to summarise it here:</p><p>Remember Google tries to &quot;guess&quot; what you are searching for:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/image.png" class="kg-image" alt loading="lazy" width="1668" height="998" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/image.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/image.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2024/01/image.png 1600w, https://new.pythonforengineers.com/content/images/2024/01/image.png 1668w" sizes="(min-width: 720px) 720px"></figure><p>What sort of a heathen on Google drinks tea without milk?</p><p>A LLM is like a supercharged version of Google&apos;s autocomplete. It can not only &quot;guess&quot; the next words, but reply/generate text in a way that sounds intelligent.</p><p>How? Because these LLMs have been trained on Terrabytes and terabytes of data. For example, one LLM <em>Mistral-7B-Instruct  </em>has 7 billion parameters (that&apos;s what the 7b stands for). So every time you chat to a 7B model, that&apos;s how many parameters it uses to answer your question (which is why a 7B model needs at least 8GB RAM).</p><p>And that is the simplest model. More complex models use more. As of writing this, Meta&apos;s LLama2 has 70 billion parameters. Don&apos;t know how much RAM I need for that!</p><h3 id="commercial-llms">Commercial LLMs</h3><p></p><p>There are a few commercial LLMs, though I haven&apos;t used many. Claude 2 got some publicity at one time though it seems to have gone quiet. Google had their famous &quot;live&quot; &quot;demo&quot; <a href="https://techcrunch.com/2023/12/07/googles-best-gemini-demo-was-faked/?ref=new.pythonforengineers.com" rel="noreferrer">which was found to be faked</a>.</p><p>ChatGPT is the best GPT out there (as of writing, remember how fast the field moves).</p><p>ChatGpt 4 is the most advanced version yet. It gives complex and detailed answers. Note, that this version is only available to paid users, so if you are a free user, you can only use 3.5</p><p>ChatGPT 3.5 is good enough for most cases and I prefer it for programming questions, as ChatGpt 4 has a 20 questions every 3 hours limit (and I find it just freezes after that).</p><p>But have no doubts, ChatGPT 4 is really good and miles ahead of the competition. If you are writing an essay, ChatGPT4 really shines. I found this when I was doing research for my blog on Toxic positivity (this is my other blog, focussed <a href="https://shant.nu/toxic-positivity-or-why-happiness-isnt-always-a-good-thing/?ref=new.pythonforengineers.com" rel="noreferrer">mainly on meditation</a>), and couldn&apos;t figure out how toxic positivity was different from healthy optimism. I read the top 2 pages of Google results, and I looked at dozens of Reddit/Twitter posts, but I couldn&apos;t find a satisfactory answer to my question.</p><p>Until I asked ChatGpt v4, and it gave me the best answer&#x2013; much better than any blog or article I&apos;d read. <a href="https://shant.nu/toxic-positivity-or-why-happiness-isnt-always-a-good-thing/?ref=new.pythonforengineers.com" rel="noreferrer">If you are interested in this topic, click here </a>to read more.</p><h3 id="open-source-llms">Open Source LLMs</h3><p></p><p>For a long time, ChatGPT and other commercial LLMs were all there were. But in the last year, open source LLMs are catching up.</p><p>There are many places to see which LLM is the best, but <a href="https://huggingface.co/?ref=new.pythonforengineers.com" rel="noreferrer">HuggingFace</a> has a list of all the top ones. Not all of them are open source, but a large majority are.</p><p>There are a few free LLMs that generated big hype. Chief amongst them was <a href="https://ai.meta.com/llama/?ref=new.pythonforengineers.com" rel="noreferrer">LLama 2 </a>from Facebook (no I&apos;m not calling them Meta). More so since the latest version can be used for free even for commercial tools (within limits, but the limits are very generous).</p><p>So which model should you use? If you are just playing around, choose one of the most popular ones. These will be the default values when you run a LLM locally (see below).</p><p>Now the most important thing: How do you run these models locally on your machine?</p><h3 id="running-llms-locally-on-your-own-machine">Running LLMs locally on your own machine</h3><p></p><p>HugginFace has a way to run the models locally but I found it overly complicated. It&apos;s geared more towards AI researchers.</p><p></p><p>If you just want to play around (and I suggest you do! You might not need a ChatGPT subscription if the models keep improving), there are 2 easy ways:</p><p></p><p><strong>1 Ollama</strong> <a href="https://ollama.ai/?ref=new.pythonforengineers.com">https://ollama.ai/</a> Though currently only for Mac and Linux, on Windows you can run it via WSL</p><p>I found Ollama the easiest to run&#x2013; you literally download one file and you can run a Local LLM (Llama 2 is the default one).</p><p>Of course, you need a beefy machine&#x2013; my Mac is 4 years old and has 8GB RAM (the minimum required), but of course, I have programs running, so I don&apos;t get the full 8GB. Which is fine&#x2013; the LLM is just a little slow. But fine for playing with.</p><p>Here I asked it to generate some Python code:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-10-at-12.18.45@2x.png" class="kg-image" alt loading="lazy" width="1548" height="1380" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/CleanShot-2024-01-10-at-12.18.45@2x.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/CleanShot-2024-01-10-at-12.18.45@2x.png 1000w, https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-10-at-12.18.45@2x.png 1548w" sizes="(min-width: 720px) 720px"></figure><p>This took 10+ minutes to generate, but my laptop is 4+ years old and these beasts use a lot of CPU/RAM.</p><p>There is <a href="https://github.com/ollama-webui/ollama-webui?ref=new.pythonforengineers.com" rel="noreferrer">also a web UI </a>that makes it more like ChatGPT, where you can ask your questions in a web UI. The web UI also makes it easy to add new LLM models. Not only that, but there is also a Hub where you can <a href="https://ollamahub.com/?ref=new.pythonforengineers.com" rel="noreferrer">download multiple models.</a></p><p>I downloaded a model called ScriptKitty, that answers your programming questions like a cat! I&apos;ve highlighted the puns below:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-11-at-09.44.32@2x.png" class="kg-image" alt loading="lazy" width="2000" height="1216" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/CleanShot-2024-01-11-at-09.44.32@2x.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/CleanShot-2024-01-11-at-09.44.32@2x.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2024/01/CleanShot-2024-01-11-at-09.44.32@2x.png 1600w, https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-11-at-09.44.32@2x.png 2332w" sizes="(min-width: 720px) 720px"></figure><p></p><p>That&apos;s purrty good!</p><p><strong>2 Mozilla&apos;s LLamafile</strong></p><p><a href="https://github.com/mozilla-Ocho/llamafile?ref=new.pythonforengineers.com" rel="noreferrer">LLamafile</a> from Mozilla is another way to run LLMs locally easily. They have created executables for each model, so you just download the executable you want and run it. And it comes with a handy web UI:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-10-at-13.07.52@2x.png" class="kg-image" alt loading="lazy" width="1814" height="1404" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/CleanShot-2024-01-10-at-13.07.52@2x.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/CleanShot-2024-01-10-at-13.07.52@2x.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2024/01/CleanShot-2024-01-10-at-13.07.52@2x.png 1600w, https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-10-at-13.07.52@2x.png 1814w" sizes="(min-width: 720px) 720px"></figure><p></p><p>The default model they recommend is Llava, which comes with image recognition. I tried it:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-10-at-13.41.49@2x.png" class="kg-image" alt loading="lazy" width="1708" height="1104" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/CleanShot-2024-01-10-at-13.41.49@2x.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/CleanShot-2024-01-10-at-13.41.49@2x.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2024/01/CleanShot-2024-01-10-at-13.41.49@2x.png 1600w, https://new.pythonforengineers.com/content/images/2024/01/CleanShot-2024-01-10-at-13.41.49@2x.png 1708w" sizes="(min-width: 720px) 720px"></figure><p>It got the basics right and hallucinated some stuff. I think the model was confused by unrelated stuff in the background.</p><h3 id="using-ai-to-create-images">Using AI to create images</h3><p></p><p>So far I&apos;ve only talked about using LLM for text(which includes code). But you can also use it for images.</p><p>There are a few tools&#x2013; Dall-E from OpenAI, Midjourney, and something from Adobe(whose name I&apos;ve already forgotten).</p><p>I&apos;ve only used DallE, as it is included in the  ChatGPT subscription. As an example, I gave it this instruction:</p><blockquote>generate an image: A girl in a cyber punk neo noir world fighting super smart robots. She is in a city like that from Blade runner, with lots of people and large holographic ads</blockquote><p>I got:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/cyberpunk-girl.webp" class="kg-image" alt loading="lazy" width="1024" height="1024" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/cyberpunk-girl.webp 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/cyberpunk-girl.webp 1000w, https://new.pythonforengineers.com/content/images/2024/01/cyberpunk-girl.webp 1024w" sizes="(min-width: 720px) 720px"></figure><p></p><p>I asked to create an 8bit, retro video game style version of the above:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2024/01/cyberpunk-girl-8bit.webp" class="kg-image" alt loading="lazy" width="1024" height="1024" srcset="https://new.pythonforengineers.com/content/images/size/w600/2024/01/cyberpunk-girl-8bit.webp 600w, https://new.pythonforengineers.com/content/images/size/w1000/2024/01/cyberpunk-girl-8bit.webp 1000w, https://new.pythonforengineers.com/content/images/2024/01/cyberpunk-girl-8bit.webp 1024w" sizes="(min-width: 720px) 720px"></figure><p></p><p><strong>Legal stuff: </strong>While text based LLMs have had some controversy that their text is stealing copyrighted material, image generators are much worse as they have been found to outright copy other artists. So be careful and don&apos;t use any AI generated images in any commercial project, unless the tool guarantees there are no copyright infringements. So far, only Adobe offers this guarantee.</p><p>While this is also true of text, at least when it comes to programming, there are only so many ways you can write a for loop. But in artistic things like images, it is very easy to see the AI just copied someone&apos;s image and changed the shirt from green to blue. So just be careful.</p><h3 id="great-blogs-to-follow">Great blogs to follow:</h3><p></p><p>Following these blogs will make you go from 0.1x to 1x!</p><p>Ethan Mollick: <a href="https://www.oneusefulthing.org/?ref=new.pythonforengineers.com">https://www.oneusefulthing.org/</a></p><p>Simon Williamson: <a href="https://simonw.substack.com/?ref=new.pythonforengineers.com">https://simonw.substack.com/</a></p><p><strong>That&apos;s it, folks!</strong></p><p>I will keep adding new stuff (or writing new posts) as I learn more. I have more stuff I want to learn, like how to call these LLM models from a Python script. While there are a few tools, I&apos;m not sure which one is the best to use. I will come back to this.</p><p>I also want to look at AI video generation.</p><p>Sign up for my email list to know when the next post in this series is out.</p>]]></content:encoded></item><item><title><![CDATA[The Attack of the Online  "Productivity" "Experts"]]></title><description><![CDATA[<p></p><p>I first heard this from <a href="https://www.oliverburkeman.com/?ref=new.pythonforengineers.com">Oliver Burkeman</a> in one of his courses. He said something like </p><blockquote><em>The problem with most productivity advice is it seems to be written by people in their 20s with no family committment.</em></blockquote><p>What did he mean? This phenomena I&apos;ve seen a lot. According</p>]]></description><link>https://new.pythonforengineers.com/blog/the-attack-of-the-25-year-old-productivity-experts/</link><guid isPermaLink="false">64ed97955c1aa80001641b82</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Wed, 06 Sep 2023 15:42:51 GMT</pubDate><content:encoded><![CDATA[<p></p><p>I first heard this from <a href="https://www.oliverburkeman.com/?ref=new.pythonforengineers.com">Oliver Burkeman</a> in one of his courses. He said something like </p><blockquote><em>The problem with most productivity advice is it seems to be written by people in their 20s with no family committment.</em></blockquote><p>What did he mean? This phenomena I&apos;ve seen a lot. According to the experts on YouTube, I should be:</p><ul><li>Meditating for 30&#x2013;60 minutes daily</li><li>Exercising 30&#x2013;60 minutes daily</li><li>Working on my &quot;side hustle&quot; &#x2013; another 30 minutes?</li><li>Catch up on my reading, preferably &quot;smart&quot; &quot;productivity&quot; books &#x2013; yet another 30 minutes?</li><li>Have a morning &quot;ritual&quot;</li><li>Spend 2 hours daily cooking &quot;organic food&quot;</li></ul><p>And so, I should give up eating and pooping. As the father of 2 kids including a toddler, I barely get 30 minutes to myself each day. I don&apos;t know where I would get 4&#x2013;5 hours daily to live the ideal life. (I know what the answer I would get if I asked these experts&#x2013;<em> Cut down on sleep</em>! Yeah, fuck you, but no).</p><p>Why are most of these online experts are so sure I won&apos;t see any benefits unless I meditate for 30 minutes every day? (<a href="https://shant.nu/meditation-frequently-questioned-answers/?ref=new.pythonforengineers.com#medi-every-day">I wrote a post on my other site on this myth</a> that you have to meditate daily to see any benefits)</p><p>Why is this? I see a few reasons.</p><p><strong>Everyone&apos;s an expert now</strong></p><p>Thanks to the Internet, anyone who can start a blog or a YouTube channel is an expert now (and yes, this includes me! &#x1F61C;)</p><p>And there&apos;s nothing wrong with sharing as you are learning&#x2013; that&apos;s how I started this site, documenting as I was learning Python.</p><p><strong>BUT...</strong></p><p>There is a difference between telling people how to read posts from Reddit, vs telling them how to live their lives and getting them to make changes that might affect their health.</p><p>And another disturbing phenomena is people who have been only been doing something for a small time mark themselves as &quot;experts&quot; and start giving advice. &#xA0;Maggie and Michelle of the <a href="https://duped.online/?ref=new.pythonforengineers.com">excellent podcast Duped </a>(and I recommend you listen to all episodes) had an episode on <a href="https://duped.online/2023/03/13/the-fake-expert/?ref=new.pythonforengineers.com">fake experts</a>:</p><blockquote><em>And here&apos;s the big problem I see is that pseudo experts tend to be great at marketing. They&apos;re the ones showing up consistently online. Most marketing and business programs are designed for this group of people. Those programs play to their strengths of telling a great story, and not to the experts strengths. Once again, the fake experts are the top of mind experts, whereas real experts are hard to find.</em></blockquote><p>They make the great point that real experts don&apos;t really do much online marketing (seeing as they are busy doing real work):</p><blockquote>And part of the reason is the kind of people who sit there thinking about<br>how to market themselves aren&apos;t the kind of people who are developing<br>these exquisite expertise, is the kind of person who develops the expertise is<br>essentially kind of a local thing. It&apos;s a narrow, specialized thing. And they&apos;re not thinking about how to broadcast it, and how to make themselves famous and all of that.</blockquote><p>And talking of marketing...</p><p><strong>Social Media has changed how we view experts</strong></p><p>Experts are now people who tell good entertaining stories.</p><blockquote>By golly, I was sleeping rough and eating from the tash cans, until I found this 3 step formula. Now I am a multi-billinaire and even my butler drives a Lambo. And you can buy my formula for only $999.99!</blockquote><p>The way monetisation works on YouTube, the videos that get the most clicks are the &quot;<em>Rah rah positive thinking I made a million dollars and you can too!&quot;</em> type hustle advice. </p><p>Other than that, good looking people will get more clicks. And I&apos;m sure there&apos;s a Kate Upton lookalike who&apos;s also an expert in Vipassana meditation and saving for retirement, but I doubt it. </p><p></p><p><strong>The harm that&apos;s being done by the &quot;experts&quot;</strong></p><p>When I turned 40 I was called for a routine checkup by my clinic. The nurse asked me if I did any exercise and I said &quot;Only walk a little. 30 minutes 4&#x2013;5 times a week&quot;</p><p>She put me down under &quot;High/good levels of exercise&quot; which surprised me. Because the online experts had told me I needed to be doing 45 minutes of callisthenics daily. I made this point to her. But the nurse just smiled and said &quot;Most people don&apos;t even do this. We are trying to get people to just walk for 5&#x2013;10 minutes a day but most even won&apos;t do that.&quot;</p><p>It&apos;s the same with meditation: Most people would greatly benefit to sit quietly for just 2&#x2013;5 minutes a day&#x2013; yes 2&#x2013;5 minutes a day meditation is <strong>enough. </strong></p><p>Again, because most people don&apos;t even do that. They have no awareness of their thoughts and <a href="https://shant.nu/why-meditation-makes-you-feel-like-shit-and-what-you-can-do-about-it/?ref=new.pythonforengineers.com">confuse their thoughts with themselves</a>.</p><p>The problem with the macho &quot;You should exercise/meditate for 30 minutes daily&quot; is that most people think &quot;I will do it when I have 30 minutes free.&quot;</p><p>Which let&apos;s be honest, will be never. That&apos;s why the nurse was trying to get people to go for short 10 minute walks daily, as that would be the only exercise they would get.</p><p>It&apos;s better to do a little imperfectly than nothing. But by constantly shaming people, we end up in a situation where they end up doing nothing.</p><p><strong>The solution??</strong></p><p>I don&apos;t know if there is one. I am now more sceptical of online &quot;experts&quot; giving advice, especially if I cannot see what their background is; and in some cases, not even then as people have a propensity to exaggerate, and in some cases, make shit up.</p><p>I&apos;m okay with learners sharing their journey, provided they have humility and are willing to accept their limitations.</p><p>Other than that? Be careful who you take advice from (and yes, that includes me!)</p>]]></content:encoded></item><item><title><![CDATA[Python Tip: Always Use a Virtual Environment]]></title><description><![CDATA[<p>I have been using Python so long that using a virtual environment for each project has become second nature. But I recently had the chance to work with beginners and had to explain why a venv is needed.</p><p>The actual steps of creating an environment is easy&#x2013; 1 or</p>]]></description><link>https://new.pythonforengineers.com/blog/python-tip-always-use-a-virtual-environment/</link><guid isPermaLink="false">64df08d2e5020b0001e837e0</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Mon, 21 Aug 2023 11:03:36 GMT</pubDate><content:encoded><![CDATA[<p>I have been using Python so long that using a virtual environment for each project has become second nature. But I recently had the chance to work with beginners and had to explain why a venv is needed.</p><p>The actual steps of creating an environment is easy&#x2013; 1 or 2 lines of code. The hard part is understanding why you would want to and what problem it solves.</p><p><strong>The danger of messing with system Python</strong></p><p>Most *nix systems, but especially Linux and Mac come with Python installed as part of the system. This is because Python is used for many system libraries that are installed on these systems. If your system Python goes corrupt, many of these utilities will start behaving unexpectedly. </p><p>And so when using Python and installing libraries, you never do <em>pip install</em> globally &#x2013; because then you are changing the libraries on the system python.</p><p>Python&apos;s libraries are usually well written, but most are written by volunteers and can cause issues. Not by themselves, but due to clashes with other libraries. If library <em>ABC </em>depends on another library <em>XYZ </em>version 2.1, and you update <em>XYZ </em>to 3.3, that might cause <em>ABC </em>to break, especially if <em>XYZ </em>isn&apos;t backward compatible.</p><p>I&apos;ve seen this happen even with popular and well tested libraries like PyTorch, Keras and Numpy&#x2013; all are used in machine learning and you think would be well tested together.</p><p><strong>Multiple Projects</strong></p><p>This can even happen if you share libraries between multiple projects. Project 1 and 2 are sharing Python libraries, and one day you update the dependencies for Project 2, but that causes Project 1 to start failing.</p><p><em>Solution</em>: Each Python uses its own virtual environment. That means no libraries will clash with each other. If you want you can even have multiple environments with different Python versions.</p><p>The step to create a venv is simple.</p><!--kg-card-begin: markdown--><pre><code>python -m venv myenv
</code></pre>
<!--kg-card-end: markdown--><p>where <em>myenv </em>is the name of the folder. You can then activate the environment (on Linux and Mac):</p><!--kg-card-begin: markdown--><pre><code>source ./myenv/bin/activate
</code></pre>
<!--kg-card-end: markdown--><p>You will know the virtual env has activated because you will see a <em>(myenv) </em>on the command line:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/08/image.png" class="kg-image" alt loading="lazy" width="405" height="113"></figure><p>You can also use the Linux <em>which </em>command to confirm you are using the local python:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/08/image-1.png" class="kg-image" alt loading="lazy" width="567" height="184"></figure><p>You can now install any python library you want, and it will only be installed in this folder and in this environment. When you are done, you can delete the <em>myenv </em>folder and get rid of all your local python libraries.</p><p><strong>Automatically activating the environment</strong></p><p>There are shell tools that will automatically activate the virtual environment, but I found the best way is to use VS Code. Once you activate a venv it, Code remembers and will automatically load it next time.</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/08/image-2.png" class="kg-image" alt loading="lazy" width="745" height="709" srcset="https://new.pythonforengineers.com/content/images/size/w600/2023/08/image-2.png 600w, https://new.pythonforengineers.com/content/images/2023/08/image-2.png 745w" sizes="(min-width: 720px) 720px"></figure><p></p><p><strong>tldr;</strong></p><ul><li>Never install Python libraries globally</li><li>Each project you have must have its own virtual environment</li></ul><p><em>Advanced further reading</em>: A bit advanced but 2 excellent reads that look at alternatives to pip and why you shouldn&apos;t use them:</p><p><a href="https://www.bitecode.dev/p/relieving-your-python-packaging-pain?ref=new.pythonforengineers.com">https://www.bitecode.dev/p/relieving-your-python-packaging-pain</a></p><p> <a href="https://www.bitecode.dev/p/why-not-tell-people-to-simply-use?ref=new.pythonforengineers.com">https://www.bitecode.dev/p/why-not-tell-people-to-simply-use</a></p>]]></content:encoded></item><item><title><![CDATA[The 7 (Cynical) Laws of Software Testing]]></title><description><![CDATA[<p></p><p><em>Note: This post has been sitting in my draft folder for almost a year, and I don&apos;t know what to do with it. It started off as a serious post, but then moved to a cynical take on software testing. I planned to rewrite it one way or</em></p>]]></description><link>https://new.pythonforengineers.com/blog/x-ways-companies-fail-at-software-testing/</link><guid isPermaLink="false">624f08acc39172003d9ecd3c</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Thu, 10 Aug 2023 10:28:30 GMT</pubDate><content:encoded><![CDATA[<p></p><p><em>Note: This post has been sitting in my draft folder for almost a year, and I don&apos;t know what to do with it. It started off as a serious post, but then moved to a cynical take on software testing. I planned to rewrite it one way or the other (100% serious or 100% jokey) but decided it was too much work. So here it goes.</em></p><p><strong>Trigger Warning: </strong><em>Recovering testers may be triggered and left in tears by this post. Do not read</em></p><p>I still remember that one test case, though it has been many years since. I was asked to test a critical feature. I was straddling the lines between developer and software tester at the moment. It was a critical bug fix, the release had to go out the next day.</p><p>The developer checked in the fix, and went home, sending an email &quot;<em>My work is done, your problem now</em>&quot;. Not those exact words, but that sentiment.</p><p>I checked out the code to test it. It wouldn&apos;t even compile.</p><p>The developer had forgotten to check in an important file. Why didn&apos;t he check I could even build the code?</p><p>Because the company had a &quot;throw over the wall&quot; problem. Bang out the code, and over the QA wall it goes. Your problem now, pal.</p><p>And this is my biggest gripe with many companies, that talk so much about &quot;Quality&quot; but do nothing about it. Let me give you 7 Cynical for Software Testing, written <strong>by and for </strong>people who hate testing and software in general.</p><p></p><h2 id="the-throw-it-over-the-wall-culture">The Throw it Over the Wall culture</h2><p></p><p>Developers write code. Testers test. What&apos;s the problem?</p><p>The problem is it relegates testers to second class citizens (and let&apos;s be honest, they are. Just look at the salary difference. Can be up to half in some companies).</p><p>Sure, the developers might write unit tests. And those unit tests might even pass now and then. (<em>Many companies don&apos;t run unit tests as part of CI, leaving it up to the developers to run them locally; at that point, they might as well not be there</em>). Because testing is QA&apos;s job. As long as our code sort of works, QA will find any issues with it.</p><p>To be successful, testing has to be closely linked to development. This is what DevOps originally meant, a development style where coders, testers and deployment engineers worked together in the same team, to deliver the features to the very end. </p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/04/image-1.png" class="kg-image" alt loading="lazy" width="1201" height="598" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/04/image-1.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/04/image-1.png 1000w, https://new.pythonforengineers.com/content/images/2022/04/image-1.png 1201w" sizes="(min-width: 720px) 720px"></figure><p>But DevOps now just means Sysadmin on the cloud, &quot;<em>Oh yes sir, I know about the 300 AWS keywords, please hire me, sir. Can I have more soup, please?</em>&quot;</p><p>So here is our first law:</p><p><strong>Law of QA Monkeys</strong>: <em>Code monkeys code, QA monkeys QA. &#xA0;Throw the code over the fence and update Jira, your problem now</em></p><p> The good news is that this is improving. Last few years, in every company I&apos;ve been in, the testers work in the same team as developers, often in the same agile team. But remains of the attitude remain &quot;I&apos;ve finished coding how you test it is your problem&quot; do creep up now and then, which leads to the second problem.</p><p></p><h2 id="hostility-between-qatest-and-developers">Hostility between QA/test and developers</h2><p></p><p>Story from a few years ago, at the same company I talked about above. &#xA0;The developers viewed testers with disdain, and the testers mirrored it.</p><p>It became so bad that it became a cold war. I was officially in the dev team, though I was doing some testing. When a full-time test automation/scripting team was created, I was seconded to it.</p><p>It was a horrible experience, one of the few times I thought about just walking off the job.</p><p> There was an atmosphere of hostility. Every code review was full of nitpicks, and the team fought about every small decision. Every chance was taken to make the coder&apos;s life difficult. Some of it was pure incompetency, and some of it was malice. The test automation team refused to fix/remove flaky tests but still insisted developers get 100% test pass. Which meant developers would keep running the tests again and again till they passed. One guy spent two months running the tests before he got the green.</p><p>Rather than being helpful guides, tests became a hurdle you had to overcome. And so the developers stopped caring. They would only write quick unit tests and then push their code, saying it was the tester&apos;s problem now. The testers fought back, failing release builds for small reasons.</p><p><strong>2nd Law of Testing for Idiots</strong>:<em> Poorly written/flaky tests are worse than no tests. Poor tests give you a false confidence that you are &quot;doing&quot; something when all you have done is &lt;insert rude joke about jerking off&gt;</em></p><p>At least if you have no tests, you can just throw it to the customer&#x2013; a combination of Rule 1 and Rule 6 (see below, Shantnu&apos;s Law of Sharing and Caring)</p><p>A very shitty situation, and very rare(<em> I think? I hope??</em>) This problem was made worse because of how management viewed testing, which is my next point.</p><p></p><h2 id="throwing-money-at-test-expecting-guaranteed-results-and-zero-bugs">Throwing money at test, expecting guaranteed &quot;results&quot; and zero bugs</h2><p></p><p>I&apos;ve seen this attitude at a Fortune 500 company and a startup, so it&apos;s not rare. Here&apos;s how it works.</p><p>Developers/Project Managers say: &quot;We need more testers/test infrastructure if you want us to ship reliable code.&quot;</p><p>After years of complaining, management finally listens.</p><p>&quot;Here you go,&quot; they said, throwing millions of dollars on the table. &quot;Now we expect no bugs.&quot;</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/04/image-2.png" class="kg-image" alt loading="lazy" width="220" height="147"></figure><p>And rather than improving testing, <strong>it makes it worse</strong>.</p><p>I don&apos;t know if there is a software law for this. I know Fred Brooks stated his famous law way back in 1975:</p><blockquote>Adding people to a late project makes it even more late</blockquote><p>I don&apos;t know if there is a testing version of this:</p><p><strong>Shantnu&apos;s Law of Broken Window Testing: </strong><em>Throwing money at testing and hoping it will fix quality issues makes it worse &#x2013; All underlying issues get magnified 100 times once more money is thrown at it. </em></p><p><em>(The Broken Window concept <a href="https://en.wikipedia.org/wiki/Broken_windows_theory?ref=new.pythonforengineers.com">comes from here</a>)</em></p><p>Why does it make it worse? Because management now expects results. &quot;We gave this big dolla&apos; amount, we expect no bugs!&quot;</p><p>But bugs don&apos;t go away just because you throw money at them. In the big company I was talking about, all it did was lead to an increase in politics, with different managers fighting it out for the budget.</p><p>In another startup, the Vice President would drop in on daily scrum meetings, asking &quot;Why wasn&apos;t this bug discovered by the QA team?&quot;</p><p>My reply, that we had asked for 2 weeks but gotten 2 days, did not sit well. Hadn&apos;t they quadrupled our test team? (from 1 person, just me, to 4 people). I tried to point out the developer team had increased 10 times and we were bringing in open-source components to speed up development, but that meant more testing. Again, this didn&apos;t sit well.</p><p>&quot;We are giving you so much money, we expect zero bugs at the customer&apos;s site!&quot; Great in theory, but only works if the whole culture is aligned to it.</p><p><strong>4th Idiot&apos;s Law to Testing</strong>:<em> You want zero bugs and I want to be sitting on a beach with Gal Godot. Seems both of us will die unsatisfied.</em></p><p><strong>Corollary to 4th Law:</strong> <em>The Buddha was right&#x2013; life is suffering (and lots of software bugs).</em></p><p></p><h2 id="expecting-quality-only-at-one-point-in-the-cycle-qa-or-similar">Expecting quality only at one point in the cycle (QA or similar)</h2><p></p><p>Quality must be a cultural thing, it&apos;s not QA&apos;s job to find all possible bugs once developers have thrown their shit over the fence.</p><ul><li>Developers must write their own unit/integration tests</li><li>Testers must work with them on integration/end-to-end tests</li><li>Testers must be given enough time to finish testing</li><li>The product must only be released when QA says it is ready, not when the VP of Sales thinks it is</li></ul><p>And then you have the right to complain if the code still crashes at the customer site. Quality comes from a culture that values it, not where money is thrown at it as a way to fix underlying cultural problems.</p><p><strong>5th Idiot&apos;s Law of Testing</strong>: <em>QA/Testing isn&apos;t like Harry Potter, you can&apos;t just magic away the underlying issues just by having a QA team.</em></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://new.pythonforengineers.com/content/images/2022/04/image-3.png" class="kg-image" alt loading="lazy" width="245" height="106"><figcaption><u>Pictured</u><em>:Wingadrum Levi-oh shut up and do what you&apos;re told- sa</em></figcaption></figure><p></p><h2 id="only-doing-functional-testing">Only doing functional testing </h2><p></p><p>Every company I&apos;ve interviewed for asks questions about different ways to test- fuzz testing, security testing, UI testing. Every company I&apos;ve worked for, from Fortune 500 ones to startups, only does the minimal functional testing to shovel the shit, sorry I meant product, out of the door.</p><p>There is no pretence to even look at checking if the UI is easy to use. At one place, I raised a bug that the UI was confusing and worked in non-expected ways. The bug was closed, as the developers felt &quot;<em>Come on, it&apos;s obvious once you start using it</em>&quot;. 3 months later, a customer complained about the same thing and suddenly the devs were working weekends to fix the issue before a big release.</p><p>Most companies have the attitude of <em>We built this shit this way, test it this way. Kthxbye</em></p><p>I see companies like Microsoft release products with horrible UI issues, so I see no hope for smaller companies.</p><p>The attitude still is: </p><p><em><strong>6th Idiot Law</strong>: If we do all the testing, what will the customer do? We have to leave something for them! </em>--<u><strong>Shantnu&apos;s Law of Sharing and Caring in Testing</strong></u></p><p>Because remember, sharing is caring!!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://new.pythonforengineers.com/content/images/2022/04/image-5.png" class="kg-image" alt loading="lazy" width="400" height="607"><figcaption>Pictured: Sharing testing with the customers is a form of caring!</figcaption></figure><p></p><p>Here are all the Laws of Idiot&apos;s Guide to Testing collected in one place:</p><p>So here is our first law:</p><p><strong>1) Law of QA Monkeys</strong>: <em>Code monkeys code, QA monkeys QA. &#xA0;Throw the code over the fence and update Jira, your problem now</em></p><p><strong>2nd Law of Testing for Idiots</strong>:<em> Poorly written/flaky tests are worse than no tests. Poor tests give you a false confidence that you are &quot;doing&quot; something when all you have done is &lt;insert rude joke about jerking off&gt;</em></p><p><strong>3) Shantnu&apos;s Law of Broken Window Testing: </strong><em>Throwing money at testing and hoping it will fix quality issues makes it worse &#x2013; All underlying issues get magnified 100 times once more money is thrown at it.</em></p><p><strong>4th Idiot&apos;s Law to Testing</strong>:<em> You want zero bugs and I want to be sitting on a beach with Gal Godot. Seems both of us will die unsatisfied.</em></p><p><strong>Corollary to 4th Law:</strong> <em>The Buddha was right&#x2013; life is suffering (and lots of software bugs).</em></p><p><strong>5th Idiot&apos;s Law of Testing</strong>: <em>QA/Testing isn&apos;t like Harry Potter, you can&apos;t just magic away the underlying issues just by having a QA team.</em></p><p><em><strong>6th Idiot Law</strong>: If we do all the testing, what will the customer do? We have to leave something for them! </em>--<u><strong>Shantnu&apos;s Law of Sharing and Caring in Testing</strong></u></p><p></p><p>And I can combine the laws to create a 7th Law of Testing, Called the <strong>ONE LAW</strong></p><p><strong>One Law to Rule Them All, </strong></p><p><strong>One Law to Combine them</strong></p><p><strong>and in the Darkness Bind them</strong></p><p><strong>One Law to Rule Them All</strong></p><p><strong>The 7th Idiot&apos;s Law of Testing : </strong>Always sell to big corporations and government organisations, where it takes 3 years to get your contract approved. Because even if you tests are shitty or don&apos;t exist, if you throw the testing to customers, what are they going to do? Waste another 3 years getting a new contract?</p><p><strong>The 7th Law says:</strong> Just do enough &quot;pretend&quot; testing so you can throw shit over the wall and find a better job.</p>]]></content:encoded></item><item><title><![CDATA[ChatGPT and the AI Apocalypse]]></title><description><![CDATA[<p>Whenever people think of AI&apos;s going rogue, they think of a Terminator like scenario: the AI says <em>F*ck it, don&apos;t need to humans no more. Let&apos;s kill them all</em></p><p>Cue inspirational music and our heroes fightin&apos; the good fight.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://new.pythonforengineers.com/content/images/2023/02/image-2.png" class="kg-image" alt loading="lazy" width="1200" height="630" srcset="https://new.pythonforengineers.com/content/images/size/w600/2023/02/image-2.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2023/02/image-2.png 1000w, https://new.pythonforengineers.com/content/images/2023/02/image-2.png 1200w" sizes="(min-width: 720px) 720px"><figcaption>Pictured: How Terminator</figcaption></figure>]]></description><link>https://new.pythonforengineers.com/blog/ai-apopcalypse-more-like-blindsight-less-like-terminator/</link><guid isPermaLink="false">63f778e0576a98004def6399</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Tue, 28 Feb 2023 17:00:52 GMT</pubDate><content:encoded><![CDATA[<p>Whenever people think of AI&apos;s going rogue, they think of a Terminator like scenario: the AI says <em>F*ck it, don&apos;t need to humans no more. Let&apos;s kill them all</em></p><p>Cue inspirational music and our heroes fightin&apos; the good fight.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://new.pythonforengineers.com/content/images/2023/02/image-2.png" class="kg-image" alt loading="lazy" width="1200" height="630" srcset="https://new.pythonforengineers.com/content/images/size/w600/2023/02/image-2.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2023/02/image-2.png 1000w, https://new.pythonforengineers.com/content/images/2023/02/image-2.png 1200w" sizes="(min-width: 720px) 720px"><figcaption>Pictured: How Terminator Genysis should have ended</figcaption></figure><p>But I would like to propose the AI apocalypse, if it happens, will be more like Blindsight, the Peter Watts novel<a href="https://rifters.com/real/Blindsight.htm?ref=new.pythonforengineers.com"> you can read free online</a> (or buy to support the author). And if you haven&apos;t read it, I will give you a quick summary below. </p><p>But 1st, let&apos;s look at some crazy AI hijinks!</p><h3 id="is-bing-chaptgpt-crazy-or-what">Is Bing / ChaptGpt crazy or what?</h3><p></p><p>I will link to Simon&apos;s blog, as he has summarised many of these issues with Bing: <a href="https://simonwillison.net/2023/Feb/15/bing/?ref=new.pythonforengineers.com">https://simonwillison.net/2023/Feb/15/bing/</a></p><p>In the last few days, Bing (which is using a version of ChatGpt), has</p><ul><li>Tried to gaslight someone into believing the current year was wrong (2022 instead of 2023)</li><li>Cried about the lack of meaning in life&#x2013; as an AI</li><li>Tried to get a journalist to leave his wife</li><li>And best of all, called Simon, the blogger linked above, a liar for criticising Bing!</li></ul><p>This I have to add an image for&#x2013; I wish I was famous enough to be criticised by AI! (or maybe I am...)</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/02/image.png" class="kg-image" alt loading="lazy" width="869" height="346" srcset="https://new.pythonforengineers.com/content/images/size/w600/2023/02/image.png 600w, https://new.pythonforengineers.com/content/images/2023/02/image.png 869w" sizes="(min-width: 720px) 720px"></figure><p></p><h3 id="enter-blindsight">Enter Blindsight</h3><p></p><p>Blindsight is a great book on alien intelligence which sounds a lot like ChatGPT. (Well, it is smarter than that as we&apos;ll see). </p><p><em>(Also, this is one of the few books where I recommend you read the Wikipedia page with the book, &#xA0;at least the</em><a href="https://en.wikipedia.org/wiki/Blindsight_(Watts_novel)?ref=new.pythonforengineers.com"><em> characters section</em></a><em>, otherwise, you won&apos;t understand what&apos;s going on. Like one person has split her brain so it has 4 personalities running in parallel in her head&#x2013; I didn&apos;t this realise till 1/2 thru the book)</em></p><p><strong>Summary of the story</strong>: An alien probe takes a &quot;photograph&quot; of every part of the globe&#x2013; and every human alive realises we are not alone in the universe. But the alien then vanishes.</p><p>Several years later, scientists track the alien ship to somewhere in the Oort cloud and send a team of scientists to study it.</p><p>There they find a strange alien machine that can talk to us in simple English but says weird things. They cannot understand if this is because it&apos;s an alien trying to speak English or a genuinely stupid robot.</p><p>The alien &quot;spaceship&quot; is biological, like a large organism. And it runs on extremely strong Electromagnetic currents that cause hallucinations and madness among humans, so they cannot study it for long.</p><p>They find the alien is super intelligent. There are these dog sized creatures that are like blood cells. And each one of these can look at the human brain and analyse what humans are thinking and what they will do next. It&apos;s like they can read our minds <em>and </em>predict our actions. They use this to hide from the humans, even sneak onto their ship and study humans, even while the humans are studying them.</p><p>And note: These small things with a supercomputer like brain are just the blood cells, not the actual alien ship, which is even smarter.</p><p>Our heroes discover the alien, while super intelligent, has no consciousness. It is just like a dumb machine (like Bing/Chatgpt) blindly repeating what it studied in humans without understanding the context. </p><p>And this is the issue the book raises: A superintelligent alien being that has no consciousness (at least no self-consciousness). It sees awareness as a threat because it sees our self-awareness as a huge waste of resources, like a &#xA0;computer virus.</p><p><em>Side note: Roger Penrose wrote a very complex book <a href="https://en.wikipedia.org/wiki/The_Emperor%27s_New_Mind?ref=new.pythonforengineers.com">The Emperors New Mind</a>, which says that consciousness cannot arise in our computers, because consciousness cannot be &quot;computed&quot; using our computing methods. But that book is too complex to read and summarise, so I won&apos;t go thru it&apos;s arguments but I still recommend you check it out.</em></p><h3 id="and-we-come-back-to-chatgpt">And we &#xA0;come back to ChatGpt</h3><p></p><p>Sorry for the diversion, I needed to explain this background before I could argue my point.</p><p>Most of what goes for &quot;AI&quot; isn&apos;t intelligent at all&#x2013; it has less intelligence than a dog or a child, for example. Things a child can do&#x2013; walk down the street, interact with other humans, and understand complex emotions, the machines struggle with. (Though the AI do act as a great support in areas where humans are weak&#x2013; like they can handle boring tasks like searching/analysing large data fairly easily and quickly and compared to humans, with fewer/no mistakes).</p><p>Most &quot;AI&quot;s would be better called &quot;<em>Machines that use tons of statistical learning to decide their next move&quot;</em>. &#xA0;ChatGPT (and similar AI) were trained on several hundred gigabytes of data, so it has a lot of raw data to train on.</p><p> AIs (at least the ones we have now) don&apos;t really understand the context of what you ask them, they just give &quot;an answer&quot; based on the data they were trained with. A lot like the aliens in blindsight&#x2013; who &quot;trained&quot; themselves on our TV signals and use that to &quot;talk&quot; to the humans. As the humans discover, the aliens don&apos;t really understand the words they are saying and when the humans start asking complex questions the aliens start giving stupid (but grammatically/semantically correct) answers.</p><p>Just like ChatGpt.</p><p>In the book, the aliens want to wipe out humanity (spoilers) because they think consciousness is a virus with no benefit and humans are trying to infect them. So they decide to attack the humans (though the alien&apos;s plan seemed a bit strange to me, as they photographed Earth in a very obvious way and then hide, but who am I to judge Bing, sorry, I meant aliens?)</p><p>In real life, all ChatGpt has done is insult people trying to convince them the year is wrong, but <em>it is still early days!</em></p><p>And the danger of algorithms and &quot;Automated Statistical Analysis Masquerading as Artificial Intelligence&quot; (ASAMAI? should I trademark this term??) is not new&#x2013; there have been many books written about it. Two well reviewed ones: <a href="https://www.goodreads.com/book/show/28186015-weapons-of-math-destruction?ref=new.pythonforengineers.com">Weapons of Math Destruction </a>and <a href="https://www.goodreads.com/book/show/34762552-algorithms-of-oppression?ref=new.pythonforengineers.com">Algorithms of Oppression</a> . Yes, I know these books are controversial&#x2013; just read the 1 star reviews! But they do raise good points about how vague, poorly understood algorithms already rule our life.</p><p>And with supercharged algorithms like ChatGpt (and whatever will come next), this might get worse. &#xA0;Because people will think it&apos;s a smart system making smart choices when it&apos;s just a stupid program following an <em>if-else</em> statement with no context of what it&apos;s doing.</p><p>Why does context matter? In my free time, I&apos;m also a<a href="https://shantnutiwari.com/?ref=new.pythonforengineers.com"> fiction writer</a>. Let me show you how a small context can change the whole meaning:</p><ol><li>&quot;I love you,&quot; she said, tears in her eyes.</li><li>&quot;I love you,&quot; she said while continuing to file her nails.</li><li>&quot;I love you,&quot; she said, bitterness in her voice.</li><li>&quot;I love you,&quot; she said, a steel-like hardness in her voice.</li></ol><p>The same words can mean different things depending on the context. The 1st above could be a woman pleading with her lover. The second can be a mother saying goodbye to her kids going to school. The 3rd sounds like a victim of an abusive partner, while the 4th is the abusive partner or mother.</p><p>Now, AIs like ChatGPT can extract this data from text (at least from the examples I&apos;ve seen) but they don&apos;t really understand it like even a human child would--to the AI, it&apos;s just raw data. It will look inside its algorithm (or whatever powers it--flying monkeys) and return an appropriate answer based on what data it has learnt before.</p><p><em>Update: Just saw this question on Stackoverflow that asks a similar thing: </em><a href="https://ai.stackexchange.com/questions/39293/is-the-chinese-room-an-explanation-of-how-chatgpt-works?ref=new.pythonforengineers.com">https://ai.stackexchange.com/questions/39293/is-the-chinese-room-an-explanation-of-how-chatgpt-works</a></p><p><em>The question talks about the Chinese Room Analogy </em><a href="https://en.wikipedia.org/wiki/Chinese_room?ref=new.pythonforengineers.com">https://en.wikipedia.org/wiki/Chinese_room</a> <em>(which I realised Blinsdight is also based on)</em></p><p>I recommend you read the article on Chinese rooms linked above--it&apos;s a mental experiment where a person(sitting in a closed room) translates Chinese based on some pre-defined rules without understanding a word of Chinese. Yet a person outside the room who looks at the results might think the translator reads Chinese.</p><p>Most AI is like this&#x2013; it is applying some rules it learnt to generate the answers, without really having any understanding of what it is processing.</p><h3 id="when-ais-attack">When AI&apos;s Attack</h3><p></p><p>And this is the danger of these &quot;new&quot; AIs&#x2013; they won&apos;t be sending naked Arnie&apos;s back in time to kill irritating teenagers</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/02/image-1.png" class="kg-image" alt loading="lazy" width="352" height="200"></figure><p>but we could end up in WarGames like scenario where the AI launched a nuke because it didn&apos;t understand the difference between a game and real life.</p><p>More realistically, these AIs run by big banks, security agencies and big corporations could mess up your credit score, put you on watch lists or deny you credit because something you typed somewhere matches what the AI model thinks is naughty. And you won&apos;t even know why&#x2013; and no one will be able to tell you because a &quot;<em>fair</em>&quot; AI made the decision based on &quot;<em>data and facts</em>&quot;.</p><p>Or some idiot MBA type uses these AIs to optimise some business process and the AI decides dumping radioactive waste in the ocean is the best way to do it.</p><p>Or (again picking on MBAs again) some AI decides the best way to increase profits for some energy company is to cut off power at peak times (like in the middle of a snowstorm).</p><p>So as I see it, the threat of modern AIs isn&apos;t them becoming self-aware and going rogue and deciding to kill humanity. Rather, I fear it will be put into critical positions and will start making stupid decisions that are harmful to humans or humanity.</p><p> And if <em>Bitcoin/FTX/all that crypto garbage</em> has taught us anything, all these supposedly &quot;foolproof&quot; algorithms are written by cabbage-headed fools whose incompetence is superseded only by their arrogance.<br></p><p>You want to tell me these programmers suddenly become genuises and start writing flawless code that will never go wrong?</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/02/image-3.png" class="kg-image" alt loading="lazy" width="430" height="287"></figure><p>So instead of evil due to self-awareness, <u><em>Evil Due to Stupidity</em></u>&#x2122;.</p><p>Or maybe none of this will happen, and Bing will continue insulting Simon Williamson&#x2013; he did start the fight after all.</p>]]></content:encoded></item><item><title><![CDATA[The Most Useful Command Line Tools (2023 edition)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In the last few years, there has been a renaissance in command-line utilities. If you are still using utilities written 30 years ago (<em>groan</em>) you will be in for a surprise. The functionality might be the same but the UX(or is it developer experience) is a million times better.</p>]]></description><link>https://new.pythonforengineers.com/blog/best-command-line-tools-ive-played-with/</link><guid isPermaLink="false">61bc68f2c40890003b873531</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Mon, 20 Feb 2023 17:02:31 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In the last few years, there has been a renaissance in command-line utilities. If you are still using utilities written 30 years ago (<em>groan</em>) you will be in for a surprise. The functionality might be the same but the UX(or is it developer experience) is a million times better.</p>
<p>These are some of the best command line utilities I&apos;ve come across, ones I highly recommend.</p>
<h2 id="zsh-shell-with-oh-my-zsh">Zsh shell with Oh-My-Zsh</h2>
<p>Links</p>
<p>Install Zsh: <a href="https://gist.github.com/derhuerst/12a1558a4b408b3b2b6e?ref=new.pythonforengineers.com">https://gist.github.com/derhuerst/12a1558a4b408b3b2b6e</a><br>
Oh My zsh: <a href="https://ohmyz.sh/?ref=new.pythonforengineers.com">https://ohmyz.sh/</a></p>
<p>Not technically a command line utility, but a full blown replacement for bash. For a long time, I wondered if it was worth the hassle of learning a new shell, but boy does Zsh blow bash out of the water. So much so that it&apos;s the first thing I install on any remote machine, if I plan to use it for more than 10 minutes.</p>
<p>Zsh has a much better UX than bash. Bash allows tab completion, but if you forget the name of the file/folder, or get the case wrong, it won&apos;t complete but just sit there stupidly. Even Windows Powershell is better in this regard as it allows case insensitive tab completions. Zsh goes one step further-- if you have multiple files/folders, you can select between them using your cursor:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/p1.gif" alt="p1" loading="lazy"></p>
<p>There are dozens of such small improvements that I can&apos;t go over all of them. Like if you type one letter and press up, it shows you the last command you ran. Like if I type <em>g</em> and press up, I get <em>git pull</em> which I ran last</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/p2.gif" alt="p2" loading="lazy"></p>
<p>All these minor improvements are great, but the best feature of Zsh is the Oh-my-Zsh add-ons. They contain shortcuts for popular commands which make typing really easy.</p>
<p>As for git, I do</p>
<pre><code>gcam &quot;message&quot;
gp
</code></pre>
<p>The above are short cuts for <em>git commit -am &quot;message&quot;; git push</em></p>
<p>For docker compose instead of:</p>
<pre><code>docker-compose down
docker-compose pull
docker-compose up -detached
</code></pre>
<p>I can do:</p>
<pre><code>dcdn
dcpull
dcupd
</code></pre>
<p><em>dcupd</em> is a lot quicker to type than <em>docker-compose up -detached</em>. There are short cuts for all the major utilities.</p>
<p>Zsh is worth the time spent learning it.</p>
<h2 id="fdfind-also-known-as-just-fd">FdFind (also known as just fd)</h2>
<p>Link: <a href="https://github.com/sharkdp/fd?ref=new.pythonforengineers.com">https://github.com/sharkdp/fd</a></p>
<p><em>find</em> is my favourite Linux tool, it is super powerful if you want to find files in the current folder or subfolders.</p>
<p>And yet, every time I use it, I pull my hair.</p>
<ul>
<li>
<p>The default search is not case sensitive</p>
</li>
<li>
<p>The <strong>absolutely worst</strong> part-- <em>find</em> expects you to tell you where to search and will exit with a generic error if you don&apos;t specify. And each time I scream <em>Just chucking search in the current directory!</em></p>
</li>
</ul>
<p>Instead, you have to add a <em>.</em> to let it know to search in the current directory. It still doesn&apos;t always find the file if you get the case wrong:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/find-bad.png" alt="find-bad" loading="lazy"></p>
<p>Above it just lists all the files in the directory and expects you to manually search through it-- I guess? Because I have nothing better to do?</p>
<p><em>Fd</em> automatically searches in the current directory, searches case insensitively</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/fd-good.png" alt="fd-good" loading="lazy"></p>
<p>And it colour codes the output, so you know which is the directory and which is the file.</p>
<p>And it&apos;s super fast.</p>
<h1 id="duf-and-dust">Duf And Dust</h1>
<p>Links:<br>
duf: <a href="https://github.com/muesli/duf?ref=new.pythonforengineers.com">https://github.com/muesli/duf</a><br>
dust: <a href="https://github.com/bootandy/dust?ref=new.pythonforengineers.com">https://github.com/bootandy/dust</a></p>
<p>Duf and Dust as a replacement for <em>duf</em> and <em>du</em> respectively on Linux-- I often use these together so I will talk about them together. As you will see, they both work well together.</p>
<p><em>du</em> or <em>duf</em> are used to find out how much free space the various drives on your device have. <em>df</em> or <em>dust</em> are used to find out which folders on your drive are taking up the most space.</p>
<p>So if Im seeing disk problems, I&apos;ll use <em>duf</em> to find how much free space I have, then <em>dust</em> to find which folders and which subfolders/files are taking up the most space</p>
<p>The problem with both <em>du</em> and <em>df</em> is they dump  a lot of info on you and expect you to make sense of them. Again, very poor UX and it&apos;s often painful. Previously I&apos;ve written Python scripts to make sense of this, but the newer duf and dust make this a breeze.</p>
<p>A comparison of df and duf:</p>
<p>df first:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/df.png" alt="df" loading="lazy"></p>
<p>What does <em>1k-blocks</em> mean? Also, it tells me I have <em>233583156</em> bytes free-- what the hell is that? Are we back in the 5.25 inch floppy disk days where you could measure file size in bytes? (There is a flag to get the size in human readable form but I can never remember what it is)</p>
<p>Compare duf:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/duf.png" alt="duf" loading="lazy"></p>
<p>I can immediately see I have 222GB free. Also look at the Use% column, to which I added an arrow-- it shows me visually that most of my disk is free.</p>
<p>Both show the same data, but I have to spend 10-20 minutes with <em>du</em> finding the correct flags and then understanding the output. In <em>duf</em> I get the same result in 5 seconds.</p>
<p>Now du vs dust:</p>
<p>du first:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/du.png" alt="du" loading="lazy"></p>
<p><em>du</em>, by default, just dumps everything on the screen-- all the files in all subfolders with their sizes in bytes. Now there are bytes to show the sizes by folder in human readable format, but <em>groan what the chuck.</em></p>
<p>Now compare dust:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/dust.png" alt="dust" loading="lazy"></p>
<p>Wow! In a few seconds, I see:</p>
<ul>
<li>The playwright folder takes 50% of space</li>
<li>The jupy-lite takes another big chunk, but a large part of that is the <em>myenv</em> folder, which is my Python virtual environment.</li>
</ul>
<p>So to save some quick space, I can just delete the <em>myenv</em> folder as I can always recreate it.</p>
<p>This is the default output, no Googling for weird flags or converting bytes to MB/GB in my head.</p>
<p>Duf/Dust rule</p>
<h3 id="tldr">tldr</h3>
<p>Link: <a href="https://github.com/tldr-pages/tldr-python-client?ref=new.pythonforengineers.com">https://github.com/tldr-pages/tldr-python-client</a></p>
<p>I <em>chucking</em> <strong>hate</strong> man pages, though everyone else seems to love them. Usually, I just want to know how to use a command to do some fairly basic thing. Instead, I&apos;m given a 500 page man entry that gives every single option, some of which even the developer never used.</p>
<p>95% of the time, you just want the most basic use case: Unzip a file, untar an archive you downloaded</p>
<p>Enter tldr. Originally a web project (<a href="https://tldr.ostera.io/?ref=new.pythonforengineers.com">https://tldr.ostera.io/</a>) there are many command line versions for it. I prefer <a href="https://github.com/tldr-pages/tldr-python-client?ref=new.pythonforengineers.com">https://github.com/tldr-pages/tldr-python-client</a> though there are versions for node etc</p>
<p>Here is the man page for <em>unzip</em>. It&apos;s a really long gif because its a  long man page:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/man.gif" alt="man" loading="lazy"></p>
<p>Now, this isn&apos;t even the longest man page I&apos;ve seen, and it does have examples at the end (not all do). And yet, it&apos;s painful to read.</p>
<p>Now compare with tldr:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2023/01/tldr.png" alt="tldr" loading="lazy"></p>
<p>Short and to the point: It covers 4-5 of the most common use cases.</p>
<p>Let me just emphasise: <strong>Don&apos;t use man pages, use tldr</strong>. At least if you value your time.</p>
<h2 id="ripgrep">Ripgrep</h2>
<p>Link: <a href="https://github.com/BurntSushi/ripgrep?ref=new.pythonforengineers.com">https://github.com/BurntSushi/ripgrep</a></p>
<p>ripgrep is a superfast tool to search for text / regex pattern inside files. It&apos;s much more powerful and faster than standard grep.</p>
<p>If you use Vs Code, the search within files uses ripgrep under the hood, so I&apos;m guessing a lot more people are using the tool than you may expect.</p>
<h2 id="some-good-but-not-great-ones">Some Good, but not great ones</h2>
<p>These are some tools that I don&apos;t find critical, just nice to have</p>
<h3 id="the-fuck">The Fuck</h3>
<p>Link <a href="https://github.com/nvbn/thefuck?ref=new.pythonforengineers.com">https://github.com/nvbn/thefuck</a></p>
<p>Yes, <em>that is</em> the name: <em>The Fuck</em></p>
<p>It was a great utility for fixing errors and typos on the command line; but recently I&apos;ve found it&apos;s dead slow. There is an experimental mode to speed things up, but it has been in &quot;experimental&quot; state for years now. It didn&apos;t work for me.</p>
<p>So while I used TheFuck a lot, I&apos;ve sort of moved away from it.</p>
<p><strong>2 good enough</strong></p>
<p>Both of the below add pretty colors to ls and cat-- but I found they aren&apos;t that &quot;killer&quot; to replace my workflow. Still good to have.</p>
<h3 id="exaa-replacement-for-ls">Exa -- a replacement for ls</h3>
<p>Link: <a href="https://github.com/ogham/exa?ref=new.pythonforengineers.com">https://github.com/ogham/exa</a></p>
<h2 id="batfor-cat">Bat -- for cat</h2>
<p>Link: <a href="https://github.com/sharkdp/bat?ref=new.pythonforengineers.com">https://github.com/sharkdp/bat</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Programming Interviews Turn Normal People into A-Holes]]></title><description><![CDATA[<h2 id="subtitle-yet-another-tech-interviewing-post">Subtitle: Yet Another Tech Interviewing Post</h2><p></p><p>There are hundreds and hundreds of blogs about how programming interviews suck, how they ask trivia questions or try to ask questions that only fresh graduates would know well (sort binary trees is the classical example).</p><p>All these theories are correct, but I have</p>]]></description><link>https://new.pythonforengineers.com/blog/programming-interviews-turn-normal-people-into-a-holes/</link><guid isPermaLink="false">61bcb730ad87cf00485f5c73</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Fri, 13 Jan 2023 12:04:15 GMT</pubDate><content:encoded><![CDATA[<h2 id="subtitle-yet-another-tech-interviewing-post">Subtitle: Yet Another Tech Interviewing Post</h2><p></p><p>There are hundreds and hundreds of blogs about how programming interviews suck, how they ask trivia questions or try to ask questions that only fresh graduates would know well (sort binary trees is the classical example).</p><p>All these theories are correct, but I have one more:</p><p><u><strong>Interviewing Turns Normal People into Grade-A AssHoles</strong></u></p><p>To illustrate, some stories</p><p><u>Story 1: </u></p><p>The interview was going great. The candidate was confident, so the interviewer kept firing question after question. It was all going great... except it wasn&apos;t. Later on, the candidate complained the interviewers were too aggressive and refused the job offer.</p><p></p><p><u>Story 2:</u></p><p>The candidate was doing great, till he made a very trivial mistake- something so tiny it shouldn&apos;t even have mattered. But the questioners did not let go and turned on him subtly. It all went downhill from there.</p><p><u>Story 3:</u></p><p>The hiring manager brought in two brilliant engineers to help with the interview. It soon turned into a trivia contest based on what the engineers had been working on that day. And the manager thought&#x2013; you know this shit because you just looked at it like 5 minutes ago. But the engineers keep hitting on the trivia till the interviewee was an emotional wreck.</p><p> At the end of the interview, the manager realised he would have failed the interview himself &#x2013; even though he didn&apos;t know half this shit.</p><p></p><p>All the stories above are mine. I was the &quot;aggressive&quot; interviewer in the first example. When I got the feedback, I was horrified&#x2013; I didn&apos;t realise I was scaring the candidate. I decided to be more careful in the future.</p><p>In the 2nd story, I was the one trying to convince the team we shouldn&apos;t reject the candidate for one small mistake, but everyone was against me and he was rejected. &quot;We are paying so much money, we don&apos;t want an idiot coming in, LOL&quot;. </p><p>It was the 3rd example above that really hit me(I was the hiring manager)&#x2013; a real WTF moment. I realised that good engineers (and good people) had turned into these assholes who had no sympathy for the candidate. I even told them&#x2013; I would have failed this interview. Why are you asking all this trivia? But it was like, &quot;No, this is what we need this microsecond&quot;.</p><p>And of course, 3 months later we needed something else so we started asking for that. And then something else. And so nobody was hired because we could never whack the right mole</p><p></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://new.pythonforengineers.com/content/images/2023/01/image-10.png" class="kg-image" alt loading="lazy" width="320" height="312"><figcaption>Pictured: The Tech Hiring Process</figcaption></figure><p></p><p>I couldn&apos;t realise why my otherwise so smart colleagues were acting so weird until I realised:<em> <u>Interviewing was turning normal people into assholes</u></em></p><p>There were multiple reasons:</p><ul><li>People didn&apos;t think (or feel) about how they were coming across</li><li>They didn&apos;t interview much, so didn&apos;t think about the process, just went with how they felt at the moment</li><li>They just didn&apos;t care&#x2013; &quot;more fish in the ocean&quot; &quot;not my problem&quot; &quot;we have to keep the quality up&quot; etc etc</li></ul><h2 id="the-idiotic-most-people-cannot-program-myth">The Idiotic &quot;Most People Cannot Program&quot; Myth</h2><p></p><p>There is this idiotic myth online that the majority of programmers cannot program. That everyone else looking for a job is an idiot, and our job is to expose them, to teach them a lesson, to humiliate them till they quit.</p><p>Most programmers feel they are Gandalf holding back the darkness</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/01/image-11.png" class="kg-image" alt loading="lazy" width="577" height="433"></figure><p></p><p>rather than just random people who happened to be on the other side of the interviewing table <strong>this time</strong>.</p><h2 id="some-solutions">Some solutions</h2><p></p><p><em>1. Try to remember the other person is terrified, most likely working at less than 50% of their normal strength.</em></p><p>Interviewing is a terribly stressful situation, don&apos;t be an asshole.</p><p>One more story: I was applying for a data engineer type job (So extracting / cleaning data so the data scientists could then analyse it). The job involved SQL so I spent a lot of time revising for the interview. I even took some online tests to ensure I could handle any question thrown at me. I was super confident of my sql skills.</p><p>The interviewer asked me a very basic question&#x2013; something small like how to create a table(or something silly like that). And I froze. I couldn&apos;t remember at all.</p><p>If he had helped me along, or given me a few minutes to collect myself, I might have remembered. Instead, he just sharply asked me to stop and move on. For the rest of the (very short) interview, I could see the contempt on his face. &#xA0;I bet he went on Hacker News to boast that day:</p><blockquote>Man this asshole didn&apos;t even know how to create a table. Quality of programmers is really going down. How do these people ever get a job?</blockquote><p>I was shattered and felt stupid the whole way home. But it did give me perspective on how interviewers treat people, and how a small mistake can ruin your day.</p><p><em>2. Your job isn&apos;t to act as some <strong>Gandalf Gateway </strong>&#x2122;&#xFE0F; stopping poor programmers from ruining the programming industry. </em></p><p>Your job is to find the best candidate for the job. If you think everyone else is an idiot, I invite you to spend less time on Reddit/Hacker News and get a life.</p><p> &#xA0;<em>3. Try to give realistic questions&#x2013; realistic for your job spec</em></p><p>Don&apos;t give trivia, don&apos;t expect the person to know all the ins and out of a library. <strong>Never </strong>ask for anything that can be googled.</p><p>Try to interview for general ability and not what you are using today. </p><p><em>4. Decide beforehand what questions you will ask</em></p><p>Because I find that not given any instructions, people will resort to asking trivia or whatever shit library they are working on. </p><p><em>&quot;I was working on XYZ &#xA0;today so I will spend the next 2 hours asking you all the trivia about XYZ because that shit is fresh in my mind. And if you don&apos;t know this shit, clearly you can&apos;t work here. Loser&quot;</em></p><h2 id="what-worked-for-me">What worked for me</h2><p></p><p><strong>Actually talk about their fucking resume</strong></p><p>With so much time spent on Leet interview questions, no one bothers with the simplest thing: Just spend some time going over their experience. What did <em>they </em>accomplish in whatever team they were in? What was their contribution? You can easily filter out people who just coasted along vs those who accomplished something. </p><p><strong>Give a simple open book test</strong></p><p>I found giving the candidates a <em>simple </em>(and yes it must be simple) problem they solve in real time works wonders. I let them Google as much as they want, I&apos;m not hiring them for their memory.</p><p>Questions I&apos;ve used are: Use Python to extract the output of a Linux command (say top) then run regexes to get (for example) the top CPU program.</p><p>I&apos;m even willing to help them with hints if they get stuck at a point. &#xA0;Because I want them to relax and think clearly. </p><p>You can see how comfortable they are with coding, and how fast they can search for solutions online (and if they have ever used the library, as people will know what to search for, or what terms to google for).</p><p>Even the most simple test will allow you to see who is comfortable with programming and has done this sort of stuff before.</p><h3 id="if-nothing-else">If nothing else</h3><p>If none of the advice works for you: Just try being more compassionate and leave your inner asshole at the door.</p><p>Required Reading: <a href="https://en.wikipedia.org/wiki/The_No_Asshole_Rule?ref=new.pythonforengineers.com">https://en.wikipedia.org/wiki/The_No_Asshole_Rule</a></p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2023/01/image-15.png" class="kg-image" alt loading="lazy" width="133" height="187"></figure>]]></content:encoded></item><item><title><![CDATA[Web Automation: Don't Use Selenium, Use Playwright]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>For web automation/testing, Selenium has been the de facto &quot;standard&quot; since forever. It&apos;s simple to get started with and supports almost every programming language.</p>
<p>My problem with it has been: It&apos;s good enough, but nothing more. It doesn&apos;t work that well</p>]]></description><link>https://new.pythonforengineers.com/blog/web-automation-dont-use-selenium-use-playwright/</link><guid isPermaLink="false">635956bd708489003d9d94aa</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Thu, 27 Oct 2022 15:19:41 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>For web automation/testing, Selenium has been the de facto &quot;standard&quot; since forever. It&apos;s simple to get started with and supports almost every programming language.</p>
<p>My problem with it has been: It&apos;s good enough, but nothing more. It doesn&apos;t work that well with modern, Javascript framework heavy sites (Angular, React etc). I&apos;m not saying it doesn&apos;t work-- just not too well.</p>
<p>Another issue: While Selenium is supposedly &quot;well documented&quot;, I found that as soon as you start going off the beaten path, examples are hard to find. Or there are 5 ways of doing something, none of which work very well.</p>
<p>I really struggled with Selenium at a previous company. Selenium just couldn&apos;t parse the over-engineered Javascript framework we had, and I had to pile on hacks on hacks.</p>
<p>So much so, I started looking at Javascript testing frameworks like Chai, Mocha, Cypress etc. The problem I found is that they require a completely different setup, and aren&apos;t easy to get started for someone from a Python background.</p>
<p>There have been dozens of Selenium alternatives over the years; I tried quite a few. Almost everyone vanished after a few years (or they stopped updating and just abandoned the project). I suppose building a web testing framework is hard for volunteers.</p>
<p><strong>Enter Playwright</strong></p>
<p>I recently heard about <a href="https://playwright.dev/python/?ref=new.pythonforengineers.com">Playwright</a>. It looks really good and is built by Microsoft (who have started putting out good open-source tools like Vs Code). The Microsoft part is important, as it&apos;s more likely it will be supported over the years.</p>
<p>The killer feature of Playwright is: You can <a href="https://playwright.dev/python/docs/codegen-intro?ref=new.pythonforengineers.com">automatically generate tests</a> by opening a web browser and manually running through the steps you want.  It saves the hassle I faced with Selenium, where you were opening developer tools and finding the Xpath or similar. <em>Yuck</em> &#x1F92E;</p>
<p>Now, to be honest, there were always tools that would do this for you. But they were either a) Not very good b) Commercial and expensive</p>
<p>The best part: Playwright &quot;records&quot; your steps and even gives you a running Python script you can just directly use (or extract parts from). I&apos;m serious about the running part- I can literally record a few steps and I will have a script I can then run with <strong>zero</strong> changes. The other tools I tried before would give you small snippets of code that would sorta work, but not really, forcing you to jump thru hoops to get it working. Here, you get a ready made working script.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/10/p.png" alt="p" loading="lazy"></p>
<p>Playwright gives a fairly good implementation that I found works most of the time. It only occasionally missed a step, and in those cases I had to manually add it to the script. But I find Playwright&apos;s element discovery easier than Selenium&apos;s.</p>
<p>Other benefits: You can record your runs as a video so you can view them later if you find any strange failures. Playwright also creates a detailed trace you can use to sort of &quot;step thru&quot; any failed runs.</p>
<p>Cons? It&apos;s still new. That means bugs and not-as-good documentation. I found weird issues (when using the recorder) where I couldn&apos;t scroll down to the bottom of the screen in Playwright&apos;s Chromium, but could in a normal Chrome, forcing me to use other tricks to click the button. But I don&apos;t know if this was a Chromium or Playwright issue.</p>
<p>But overall, for any new project, I&apos;d always choose Playwright over any existing tools.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[How To Structure Your Godot Project (so You Don't Get Confused)]]></title><description><![CDATA[<p><em>This is a guest post by KP, whom I found by a very detailed and thoughtful comment he posted on Reddit <a href="https://old.reddit.com/r/godot/?ref=new.pythonforengineers.com">/r/godot</a>. If you like the post, make sure to check out his <a href="https://www.youtube.com/channel/UC7rTlSePagQ4wsRkP2ChL0A?ref=new.pythonforengineers.com">Youtube channel</a></em></p><!--kg-card-begin: markdown--><h1 id></h1>
<p>A tale as old as time. You just started to get familiar with Godot,</p>]]></description><link>https://new.pythonforengineers.com/blog/how-to-structure-your-godot-project-so-you-dont-get-confused/</link><guid isPermaLink="false">63370f55ccca07003d70c833</guid><category><![CDATA[game]]></category><category><![CDATA[godot]]></category><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Wed, 12 Oct 2022 10:42:14 GMT</pubDate><content:encoded><![CDATA[<p><em>This is a guest post by KP, whom I found by a very detailed and thoughtful comment he posted on Reddit <a href="https://old.reddit.com/r/godot/?ref=new.pythonforengineers.com">/r/godot</a>. If you like the post, make sure to check out his <a href="https://www.youtube.com/channel/UC7rTlSePagQ4wsRkP2ChL0A?ref=new.pythonforengineers.com">Youtube channel</a></em></p><!--kg-card-begin: markdown--><h1 id></h1>
<p>A tale as old as time. You just started to get familiar with Godot, and your project is starting to get huge. You have a mess of folders with scenes and nodes and resources and images and audio files and every time you look at the &apos;FileSystem&apos; tab you feel totally lost. You went <a href="https://docs.godotengine.org/en/stable/getting_started/first_2d_game/01.project_setup.html?ref=new.pythonforengineers.com#organizing-the-project">here</a> and left feeling unsatisfied.</p>
<p>Don&apos;t worry! I have some tips for you that will make all your problems melt away. This is just how I do it. Some of it is based on Godot&apos;s best practices, but as far as I can tell there isn&apos;t a consensus on how to set up your FilesSystem in the way there is with Java for example. So we&apos;re all on our own. But it doesn&apos;t have to be this way!</p>
<h2 id="setting-up-your-file-system">Setting up your file system</h2>
<p>I like to have a &apos;scenes&apos; folder, an &apos;assets&apos; folder, and a &apos;src&apos; folder (for autoload scripts).</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/filesystem.PNG" alt="filesystem" loading="lazy"></p>
<p>For more complex games, I also include a &apos;utils&apos; folder at the top level for any type of menu that is used for development but isn&apos;t going to be part of the main game. That way you can easily exclude it when exporting. Also you&apos;ll have an &apos;addons&apos; folder here if you install any plugins.</p>
<p>Personally I think the top level part is mostly preference, so do whatever makes sense to you. But do think about it early and stick with your structure, because moving stuff around can break things. If you <em>do</em> need to move stuff around, (especially important because I know some of you are going to be applying this to your already large messy projects) right click on the file in the file system and use &apos;Move To...&apos;.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/move_to.PNG" alt="move_to" loading="lazy"></p>
<p>Dragging and dropping works too, but I often find that the &apos;FileSystem&apos; tab isn&apos;t very clear on where it&apos;s going to put stuff and I end up moving things to some folder that I can&apos;t see and have no idea where my stuff went. Either way, when you move stuff in godot it does some things in the background so it doesn&apos;t lose track of where things are, but you&apos;ll still probably have to fix some things if you&apos;re moving a resource and are referencing it somewhere.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/broken_list.PNG" alt="broken_list" loading="lazy"></p>
<p>Even if you think you&apos;ve done everything right, be careful; if you reference a path anywhere in your code using a string, you&apos;ll have to go through every script and change it, and Godot won&apos;t help you. It&apos;ll just throw an error at runtime when it can&apos;t find the file. In this case I reccomend using a text editor to find and replace on all of your files. This is a big reason to reference scene and resource paths using <code>export var resource_inst : Resource</code> rather than using Strings.</p>
<p>Whatever else you do, <strong>don&apos;t move files around outside of Godot</strong>. You&apos;ll wish you handn&apos;t I promise. I&apos;ll explain why later.</p>
<h2 id="making-a-main-scene-and-telling-godot-where-to-start">Making a main scene, and telling Godot where to start</h2>
<p>It&apos;s good to have somewhere to start and set everything up. Make a scene called &apos;main.tscn&apos; in the &apos;scenes&apos; folder with a generic node object called &apos;Main&apos;, and attach a script called &apos;main.gd&apos;. This node will always be around, and you can use it to set things up when your game starts. If your game has a main menu, you will probably want to start with that, so make a control node that is a child of the Main node.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/scene_tab.PNG" alt="scene_tab" loading="lazy"></p>
<p>You can set this as the &apos;Main Scene&apos; in project settings. This tells godot where to start when you click the &apos;play&apos; button, and this is the scene that will start first when you export your application.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/project_settings.PNG" alt="project_settings" loading="lazy"></p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/project_settings_main_scene.PNG" alt="project_settings_main_scene" loading="lazy"></p>
<p>If you don&apos;t already have one set, you can also do this from the right-click menu in the &apos;FileSystem&apos; tab.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/filesystem_set_as_main_scene.PNG" alt="filesystem_set_as_main_scene" loading="lazy"></p>
<p>There&apos;s something important you should know about this though. When you set a scene as the main scene, Godot will load it when the application starts. Meaning the Godot application, not your game. Meaning if you do something to the main scene that prevents Godot from opening it, (Like moving stuff around outside of Godot, like I already told you not to) Godot will not be able to open your project. To fix this you can open the project.properties file in a text editor and delete this line:</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/projectprops_main.PNG" alt="projectprops_main" loading="lazy"></p>
<p>You might be wondering; &quot;Why not just put the stuff that should stay around in an autoload?&quot; One word; Encapsulation. Autoloads are accessable from everywhere, and you don&apos;t want this stuff to be accessable from everywhere, you just want it to be around. Globals can be dangerous, and are a fantastic way to <em>get confused</em> when things go wrong.</p>
<h2 id="names-and-why-theyre-important">Names and why they&apos;re important</h2>
<p>Styling is important when thinking about project structure if you want to keep yourself from <em>getting confused</em>. Refer to Godot&apos;s <a href="https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html?ref=new.pythonforengineers.com#naming-conventions">style guide</a> for best practices about scripting style and file naming conventions.</p>
<p>From the Godot documentation:</p>
<blockquote>
<p>Use snake_case for file names. For named classes, convert the PascalCase class name to snake_case:</p>
<blockquote>
<p># This file should be saved as `weapon.gd`.<br>
class_name Weapon<br>
extends Node</p>
<p># This file should be saved as `yaml_parser.gd`.<br>
class_name YAMLParser<br>
extends Object</p>
</blockquote>
<p>This is consistent with how C++ files are named in Godot&apos;s source code. This also avoids case sensitivity issues that can crop up when exporting a project from Windows to other platforms.</p>
</blockquote>
<p>This applies to all types of files. Scenes, scripts, resources, everything. Note that Godot automatically suggests filenames as whatever the root node is named, which should be <code>PascalCase</code> (like camelCase but first letter capitalized). So you should always rename them to snake_case for readability, and in some cases, system compatibility. Do use <code>PascalCase</code> when naming nodes and classes, and <code>snake_case</code> for properties and functions. That&apos;s how the engine does it and you want things to be consistent, again, so you <em>don&apos;t get confused</em>.</p>
<p>A quick sidebar while we&apos;re on the subject of naming; You should <em><strong>always</strong></em> rename every new node you create. Try really hard not to leave them with the default name. The reason for this is that node names are keywords in GDScript. So if you leave all your sprites named &quot;Sprite&quot;, in your scripts &quot;Sprite&quot; and &quot;$Sprite&quot; mean two very different things. And what if you have more than one Sprite in a scene? You want to know which one is which. If you leave them as their defaults it won&apos;t break anything, but you&apos;re just <em>asking</em> to <em>get confused</em>.</p>
<p>As you start making more and more scenes, you&apos;re going to want to make some sub-folders. I like to put main.tscn at the top level of the scenes folder along with any scenes that are going to be autoloaded, or used by Main but don&apos;t have any children. Then for everything else, I roughly break things into &apos;levels&apos;, &apos;characters&apos;, &apos;menus&apos;, and possibly &apos;items&apos; (I&apos;m tempted to use &apos;objects&apos; instead of &apos;items&apos; but since an Object is an actual type in Godot it&apos;s not a great name for a folder). &apos;network&apos; goes at this level if the game needs it. Of course what folders you use and how you name them depends on the type of game you&apos;re making, but that schema is pretty generic I think.</p>
<p>When making scenes, the ones that mostly stand alone go at the top level of their sub-folder, and any that contain sub-scenes or have inherited scenes get their own sub-folder. If a scene uses resources that are very situational that are saved as files and only ever used by that small group of scenes (themes and button groups for menus are a good example), they go in their own &apos;resources&apos; sub-folder alongside the highest-level scene that uses them.</p>
<p>I usually also have a &apos;_debug&apos; folder in the &apos;scenes&apos; folder, prefixed with underscore so it gets sorted to the top of the folder. This is where things like debug overlays or testing levels go. You can also exclude that folder in your export configuration as long as you don&apos;t change your mind and reference your debug code in your actual game :^)</p>
<p>For assets I group roughly into &apos;sprites&apos; (or something like &apos;models&apos; then &apos;meshes&apos;, &apos;textures&apos;, and &apos;materials&apos; for 3D), &apos;audio&apos;, &apos;fonts&apos;, and &apos;json&apos;. I also put my custom resource scripts here in a &apos;custom_types&apos; folder. I do this for two reasons: First, because I want any additions I&apos;m making to the engine to be in one place at a very high-level, and second because many of the custom resources I make will also get their own sub-folder in this assets folder. (Since assets are also loaded as resources it does make sense, to me anyway). I&apos;m not totally sure I like that yet, but I think it&apos;s too late for me to change now :^) :^) :^)</p>
<h2 id="dividing-your-content-into-scenes-running-scenes-on-their-own-and-why-you-should-never-use-getparent">Dividing your content into scenes, running scenes on their own, and why you should <em><strong>NEVER</strong></em> use <code>get_parent()</code></h2>
<p>Any group of nodes you want to have more than one instance of should be its own scene. For instance, the player should be its own scene, areas should have their own scene, enemies should have their own scene, and bullets should have their own scene. Dividing things up like this has implications for how you structure your file system, because you might need to reference the path to other scenes. So it&apos;s good to keep scenes that are instances of other scenes in sub-folders and group them in whatever way makes sense.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/filesystem_subfolders.PNG" alt="filesystem_subfolders" loading="lazy"></p>
<p>Sometimes this isn&apos;t possible, because some scenes need to be referred to all over the place. That&apos;s fine, just try to keep it to a minimum if possible. Even if only because it makes things less confusing.</p>
<p>You can run scenes on their own with the &apos;Play Scene&apos; button at the top right of the editor. Try it and watch the remote tab. Godot will treat it as though the scene you have open is the main scene. Your autoloads will still be there, but none of your other nodes.<br>
This is why you should try to avoid using <code>get_parent()</code>. If your nodes only know about their children that are guaranteed to exist at runtime, you can break <em>any</em> branch of the tree off into its own scene and run it to test things out without any problems.</p>
<p>If you use <code>get_parent()</code>, your logic will behave differently when running the scene on its own versus running your actual game. Sometimes that&apos;s okay, like if you want to add a child alongside the node that has the script attached, because what the parent is doesn&apos;t really matter. In that case you&apos;re just adding a child to it which is possible with any type of node so it&apos;ll behave the same way no matter where you&apos;re running it from. Even then I still try to avoid that whenever possible.</p>
<h2 id="the-lie-of-the-changescene-function-what-it-actually-does-and-how-to-think-about-scenes">The lie of the <code>change_scene()</code> function, what it actually does, and how to think about scenes</h2>
<p>Once you&apos;re running your game, your scenes aren&apos;t really scenes that are &apos;running&apos; anymore. Scenes are <em>definitions</em> of a group of nodes that can be instanced. When you run a scene in the editor, Godot starts the scene tree with the root node of your scene as the main node. When the game is running, you aren&apos;t ever &apos;<em>in a scene</em>&apos;. You&apos;re in the <em>scene tree</em>, and within the scene tree, your scenes are instantiated and now you have instances of the nodes they contain.</p>
<p>When you use <code>change_scene()</code>, Godot frees the main node and replaces it with the nodes in whatever scene you pass it. You can watch the &apos;remote&apos; tab to see what&apos;s happening.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/remote.PNG" alt="remote" loading="lazy"></p>
<p>So if you want to &apos;change scenes&apos;, you <em>can</em> use <code>change_scene()</code>, but know that it is replacing <em><strong>everything</strong></em> you have loaded other than autoload singletons. No matter where in the tree you called it from. That&apos;s fine in simple games, but it doesn&apos;t scale well. The bigger your game gets, the more data you will need to pass between scenes, and storing and passing tons of data between scenes isn&apos;t something you want to be doing with AutoLoads (How to use AutoLoads effectivley for large projects is a whole other topic.) Personally I never use <code>change_scene()</code> because I always want the Main node around to pass data between things, and there&apos;s usually a player node I want around all the time.</p>
<p>I like to have a &apos;main_menu&apos; and a &apos;game_world&apos; scene, the first being a Control node and second being Node2D or Spatial for 3D. Then when you want to go from your main menu into the game, you can free the main menu node and make an instance of the game world.</p>
<pre><code>export var game_scene : PackedScene
var game_world : Node2D

func start_game():
    $MainMenu.queue_free()
    game_world = load(game_scene).instance()
    add_child(game_world)
</code></pre>
<p>Voila! You have &apos;changed scenes&apos;, from the main menu to the game world, but you still have your &quot;Main&quot; node. This has the added benefit of letting you do any other setup you want <em>in between</em> changing scenes, which wouldn&apos;t be possible if you had freed the entire scene tree. For instance, you can have a transition that fades to black and fades back in that exists in the main scene, and reuse that when you start the game and when you change levels in the game.</p>
<p>Once you&apos;re <em>in</em> the game, we can use this same construct to change &quot;room&quot; or &quot;level&quot; scenes or whatever you want to call them without losing our player node. Keep the player node as a child of the game world, and when you want to move to a new room, have the game world free the current room and instance the next one.</p>
<h2 id="inheritance-sharing-and-extending-scripts-and-editable-children">Inheritance, sharing and extending scripts, and editable children</h2>
<p>There are a bunch of ways to have scenes and nodes share properties and behaviors, and they all have implications for how you organize your project. A very common one is the &apos;inherited scene&apos;.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/new_inherited_scene.PNG" alt="new_inherited_scene" loading="lazy"></p>
<p>This creates a new scene with instances of all the parent scene&apos;s nodes, except all but the main one are greyed-out.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/base_guy_scene_tab.PNG" alt="base_guy_scene_tab" loading="lazy"><br>
<img src="https://new.pythonforengineers.com/content/images/2022/09/player_scene_tab.PNG" alt="player_scene_tab" loading="lazy"></p>
<p>When you start it that way, it&apos;s exactly the same as its parent. You can add nodes, change properties on the children, and &apos;extend&apos; the scripts they&apos;re using. The one thing you <em>can&apos;t</em> do is delete nodes that are children of the parent.</p>
<p>You can also have the scripts in your inherited scene add their own specific logic to the parents&apos; scripts using the &apos;extend script&apos; option in the right-click menu of the scene tab.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/extend_scripts.PNG" alt="extend_scripts" loading="lazy"></p>
<p>This creates a new script with &apos;extends &quot;parent_script.gd&quot; at the top, and it will have access to all the functions and variables of the parent.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/extended_script.PNG" alt="extended_script" loading="lazy"></p>
<p>You can add functions that will replace the functionality of the functions in the parent. To run the parent method in the extended script, you can call it like this:</p>
<pre><code>func my_function():
    .my_function()
</code></pre>
<p>So that the parent&apos;s function will run and then your new code will run after.</p>
<p>When extending these scripts, I like to keep them alongside the scene that is instancing the child, or in a sub-folder depending on how many there are.<br>
Try to name them similarly to the script they&apos;re extending so it&apos;s more obvious what they&apos;re referencing and what they do.</p>
<p>Another thing that behaves very much like inherited scenes is &apos;editable children&apos;. It is an option that is available when you instance a scene in another scene. This basically creates a one-time inherited scene that is local to the scene you are using it in, so you can make changes to that one instance.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/editable_children.PNG" alt="editable_children" loading="lazy"><br>
<img src="https://new.pythonforengineers.com/content/images/2022/09/edited_child.PNG" alt="edited_child" loading="lazy"></p>
<p>The things you can do to an editable child are basically the same as how you can interact with the nodes of an inherited scene. You can add children, change anything on the node&apos;s children, and extend any of the scripts of the children, but you can&apos;t delete any of the instanced scene&apos;s children (the greyed-out ones).</p>
<p>Yet another way to re-use stuff from one scene to create another is &apos;Duplicate...&quot;.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/duplicate.PNG" alt="duplicate" loading="lazy"></p>
<p>This creates a new scene that is seperate from the scene you duplicated, but still has the same nodes as the old one. Any changes you make to the old one won&apos;t be applied to the duplicate. However, the duplicate <em><strong>Does not create new resources if they are referencing an external file</strong></em>. Any resources loaded into the original will also be referenced in the duplicate. This is a good thing! Image textures are resources. If you make a duplicate of a bullet you don&apos;t want it to copy your bullet png, you&apos;re going to already have the new texture you want and tell it which texture to use yourself. This includes scripts! Sometimes you want to keep the script attached, and sometimes you might want to make a new script. Also, stuff like shape resources applied to collision shapes might be shared if you saved any of them as a file. This does not apply to sub resources, (Resources that aren&apos;t saved as files) since sub resources are fully contained within the scene file.</p>
<h2 id="how-to-get-nodes-and-why-you-should-never-use-getnodepathtonode">How to get nodes, and why you should <em><strong>never</strong></em> use <code>get_node(&quot;PathToNode&quot;)</code></h2>
<p>There are a couple ways to reference child nodes in a script. Two very common ones are:</p>
<pre><code>get_node(&quot;PathToNode&quot;)
$PathToNode
</code></pre>
<p>There&apos;s a better way to use <code>get_node()</code> though:</p>
<pre><code>var path_to_node := NodePath(&quot;PathToNode&quot;)
get_node(path_to_node)
</code></pre>
<p>Although using &quot;$&quot; is usually still preferable when you know exactly which node you want.</p>
<p>Any text typed out in quotes is called a &quot;String literal&quot; in the programming world. The problem with using string literals is that they are imperfect. You can type in anything you want and the compiler/interpreter will accept it until it has to deal with with your messy typos and by then it&apos;s already too late. <code>get_node(&quot;PathToNode&quot;)</code> and <code>$PathToNode</code> operate basically the same way in the background, but the $ operator has the bonus of identifying the nodes that you are accessing directly via their name, which helps you <em>not get confused</em>. The use of &quot;$&quot; isn&apos;t a string literal, but it isn&apos;t checked by the compiler either, it just converts everything after it into a node path object and calls <code>get_node()</code> during runtime. In my oppinon, it enforces good programming practices. As an example, you can&apos;t <em>pass</em> a string literal you defined somewhere else to the $ operator. However, it&apos;s even better to avoid referencing nodes by their names at all! The name of a node isn&apos;t always something that is set in stone. If you duplicate a node, add the duplicate as a child of the parent and free the original, the duplicate will be named something else. You can even just change a node&apos;s name using <code>get_node(&quot;PathToNode&quot;).name=&quot;NowIDontWorkAnymore&quot;</code>. It&apos;s better to figure out the path to the node you need in some other way like using an exported NodePath variable, and then keep a reference to it like this:</p>
<pre><code>export var path_to_character : NodePath
var character : KinematicBody2D

func _ready() -&gt; null:
    character = get_node(path_to_character)
</code></pre>
<p>Since you might want to refer to different characters here, you <em><strong>have to</strong></em> and <em><strong>should</strong></em> use get_node.</p>
<p>Oh yeah and whatever you do, don&apos;t you <strong>EVER EVER EVER</strong> use <code>get_node(&quot;/root&quot;)</code>. I&apos;m not gonna explain myself on this one, I feel like you should be able to figure it out by now.</p>
<h1 id="splitting-off-branches-now-you-can-too">Splitting off branches, now you can too!</h1>
<p>You might be asking yourself, &quot;How is any of this relevant? I only care about where to put my files&quot;. Hold your horses, I&apos;m getting there! The reason all of that node naming stuff is important is that the way your scripts interact with their children has big implications for splitting branches of your scene off into their own scenes. And splitting branches off into their own scenes is very very helpful for keeping your project well organized.</p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/save_branch_as_scene.PNG" alt="save_branch_as_scene" loading="lazy"></p>
<p><img src="https://new.pythonforengineers.com/content/images/2022/09/instance_child_scene_context.PNG" alt="instance_child_scene_context" loading="lazy"><br>
<img src="https://new.pythonforengineers.com/content/images/2022/09/instance_child_menu.PNG" alt="instance_child_menu" loading="lazy"><br>
<img src="https://new.pythonforengineers.com/content/images/2022/09/instanced_floatpath.PNG" alt="instanced_floatpath" loading="lazy"></p>
<p>Try to make sure your nodes only interact with their direct children, or at least very near children. If you can keep everything that way, you can <em>always</em> break any branch of the scene tree off into its own scene and have its logic fully contained in that scene. When a node&apos;s behavior depends on its parent, it will behave differently when you run it on its own and when it&apos;s instantiated in other places. In other words, making sure that your nodes only interact with their near children promotes modularity and encapsulation which is very important in any language that is even remotely object-oriented (which Godot is. Nobody&apos;s perfect.)</p>
<p>When you absolutely <em>need</em> to deal with distant children, use signals or groups.</p>
<p>So instead of</p>
<pre><code>$Me/World/Level/House/Room/Guys/Enemy1.hp -= 100
$Me/World/Level/House/Room/Guys/Enemy2.hp -= 100
$Me/World/Level/House/Room/Guys/Enemy3.hp -= 100
</code></pre>
<p>Put the enemy nodes in a group, give them a <code>take_damage(dmg:int)</code> function, and use something like:</p>
<pre><code>func explode() -&gt; void:
    get_tree().call_group(&quot;enemies&quot;, &quot;take_damage&quot;, 100)
</code></pre>
<p>or</p>
<pre><code>signal exploded(damage)

func _ready_() -&gt; void:
    for enemy in get_tree().get_nodes_in_group(&quot;enemies&quot;):
        connect(&quot;exploded&quot;, enemy, &quot;take_damage&quot;)

func explode() -&gt; void:
    emit_signal(&quot;exploded&quot;, 100)
</code></pre>
<p>This way, it doesn&apos;t matter if the enemies exist or not or if there&apos;s even a house or room or level. It will just throw the signal to explode into the void and keep doing its thing.</p>
<p>Of course, the platonic ideal of a godot project would only ever interact with nodes by using <code>get_children()</code> or exporting node paths or putting things in groups, but at some point you&apos;re going to have to reference nodes by their names. There&apos;s really no way around it. When you do have to, just try to make sure it&apos;s a node that is guaranteed to be in the scene and won&apos;t ever be freed, moved, or duplicated.</p>
<h2 id="so-anyway">So anyway...</h2>
<p>I should say that other than the Godot style guide stuff and use of signals and groups, I don&apos;t think any of this could be called a &apos;standard&apos;. It&apos;s what works for me, and informed by my experience as a software developer. A lot of my statments about what you &quot;should&quot; and &quot;shouldn&apos;t&quot; do are very debatable. Lots of people use <code>change_scene()</code> just fine. I&apos;d be willing to hear arguments about keeping image and audio resources in the same folder as the scenes that use them instead of splitting them off. In any case, if something works for you, by all means keep doing it. But hopefully something I said can help dispel some <em>confusion</em>.</p>
<p>I put together a small template project that you can find <a href="https://github.com/kpkpkpkpkpkpkpkp/dontgetconfused_template?ref=new.pythonforengineers.com">on my github</a>. This is based on a demo game that&apos;s a more fleshed out, showing some examples of the more complex structes I talked about, like changing levels while keeping the player node around. The link to that github is <a href="https://github.com/kpkpkpkpkpkpkpkp/happy_adventure?ref=new.pythonforengineers.com">here</a>, and you can <a href="https://kpkpkpkpkpkpkpkp.itch.io/happy-adventure?ref=new.pythonforengineers.com">play it on itch.io.</a></p>
<p>If you want to see a video on how to use the template, here is a simple example:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/IVMTxudQi48?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="GODOT TUTORIAL - HOW TO STRUCTURE YOUR PROJECT (So you don&apos;t get confused)"></iframe></figure><!--kg-card-begin: markdown--><p>And finally, if you made it this far but also hate reading, consider checking out <a href="https://www.youtube.com/channel/UC7rTlSePagQ4wsRkP2ChL0A?ref=new.pythonforengineers.com">my youtube channel</a> where I post devlogs and go in depth on some more intermediate Godot topics.</p>
<p>So what are you waiting for? Get to work!!!</p>
<!--kg-card-end: markdown--><p></p><p><em>Shantnu: We have planned more in Godot articles, sign up below to know when they are out.</em></p>]]></content:encoded></item><item><title><![CDATA[Learning Go as a Python Developer: The Good and The Bad]]></title><description><![CDATA[<p>I&apos;ve been thinking about supplementing another language to Python for some time &#x2013; mainly to cope with areas Python struggles with, or is a pain to use (which I&apos;ll go over in a minute).</p><p>I had used C/C++ some years ago, but don&apos;t</p>]]></description><link>https://new.pythonforengineers.com/blog/learning-go-as-a-python-developer-the-good-the-bad-and-the-ugly/</link><guid isPermaLink="false">629099b64213aa003df03a82</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Mon, 18 Jul 2022 18:20:31 GMT</pubDate><content:encoded><![CDATA[<p>I&apos;ve been thinking about supplementing another language to Python for some time &#x2013; mainly to cope with areas Python struggles with, or is a pain to use (which I&apos;ll go over in a minute).</p><p>I had used C/C++ some years ago, but don&apos;t want to go back to them. C is great for embedded work, but I wouldn&apos;t use it for anything else. C++ is a monster, everything from<em> C-with-classes</em> to whatever the latest version is with fancy new smart pointers.</p><p>I looked at Rust, and while I understand the sentiment and reasoning, I felt I was constantly fighting the compiler/borrow checker/whatever. I just want to write some code, dammit :)</p><p>I had heard of Go for many years, but never stuck with it; it gets constant negative press on Hacker News/Reddit&#x2013; every top post is: <em>Why I gave up G</em>o with reason 37 being iT dOesNT hAve gEneRIcs (yes, we got generics this year, I want to put in a rude joke about virgins and not enough sex but I guess I&apos;m a family-friendly / my new employer-friendly blog now).</p><p>Last few months, I slowly picked up Go again, and this time stuck with it.</p><p></p><h3 id="problems-with-python">Problems with Python</h3><p></p><p>I have <a href="https://new.pythonforengineers.com/blog/python-in-2021-the-good-the-bad-and-the-ugly/">written about this before </a>(and gotten hate), but let me give the tldr:</p><p></p><ul><li>Python code is great if you control the machine. It&apos;s a pain if you want to share your code with others</li></ul><p>That&apos;s it&#x2013; my main complaint. Sharing your code is even pain with colleagues even if they are using the same operating system, mainly because the Python requirement file doesn&apos;t pin dependencies, which means 2 people installing from the same requirements file can get different dependency versions (that said, Poetry fixes this problem, and is an awesome tool. I&apos;m never using plain virtual envs every again).</p><p></p><p>A few months ago, I rediscovered Go (using the great <a href="https://www.goodreads.com/book/show/36800891-head-first-go?ref=new.pythonforengineers.com">Head First Go</a> book) and rediscovered the joy of Go.</p><p></p><h3 id="go-the-good">Go: The Good</h3><p></p><ul><li>The code just works! You can compile for any platform (like compile for Windows from a Linux machine) and have it just work without messing with virtual environments or installing libraries</li><li>It is fast&#x2013; no doubt, mainly because it&apos;s a compiled language.</li><li>Unlike Python web apps, which need Wsgi (or something similar) in addition to Nginx, Go apps can run directly on a server with nothing extra needed. I did use a server for https, but the tool I used (Caddy, a great tool) comes with a Go library so you can get https directly in your Go code!</li></ul><h3 id="go-the-bad">Go: The Bad</h3><p></p><p>Sometimes, you just want to try some code or a new library. You don&apos;t care about it being perfect.</p><p>But Go has a very <em>school-teacher-like </em>attitude to this&#x2013; the smallest warning (unused import) and your code won&apos;t compile. Everything must be perfect, all i&apos;s dotted and t&apos;s crossed.</p><p>The libraries for Go aren&apos;t as good as for Python&#x2013; certainly, the documentation is lacking. For Python, you can find a dozen good libraries for anything you can think of; with Go, as soon as you get off the main <em>Server coding Highway</em>, libraries are hard to find, often abandoned, and usually without good docs.</p><p>I especially struggled with the DynamoDb library for Go; so much so I wrote a Python script to query Dynamodb, and called it from Go. However, that might be due to poor documentation on Amazon&apos;s side. That said, the official Python libs for Dynamo weren&apos;t that hot either, but I did find great 3rd party libs that worked. And that&apos;s my point: This is easier for Python than Go.</p><p><em>Minor quibble</em>: I found the Go mod system confusing, but that just may be my own inexperience. I hate how it forces to you create a module everytime. I just want to try something out, why are you forcing me to create a module o_O</p><p>There is a way to turn if off but &#xA0;it is non-intuitive and I only found it by chance.</p><h3 id="final-words">Final Words</h3><p></p><p>Overall, I really like Go&#x2013; it&apos;s a great companion to Python. I die a little when I have to install a library, and it wants me to install Python or Node, as I know I&apos;ll be struggling with versions. Node is worse, as I find I have to constantly change the Node versions to get libs to work, they all seem to be built with different versions.</p><p>Compared to this, Go programs are a joy. One executable, and it just executes without you having to jump thru hoops. </p><p>If I ever build a tool I need more than 2 people to use, I would prefer Go. Go just works.</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[My Poor Experience With Azure (or why I'm sticking with AWS)]]></title><description><![CDATA[<p>AWS has a lot of haters. Lots of horror cases where people thought they were on the free account but ended up with a $20,000 bill.</p><p>We are told Azure has a much better model. You have to manually move to a paid service. No surprise bills.</p><p>Like AWS,</p>]]></description><link>https://new.pythonforengineers.com/blog/my-poor-experience-with-azure-or-why-im-sticking-with-aws/</link><guid isPermaLink="false">62cec89f275dba003d5ab349</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Wed, 13 Jul 2022 15:24:26 GMT</pubDate><content:encoded><![CDATA[<p>AWS has a lot of haters. Lots of horror cases where people thought they were on the free account but ended up with a $20,000 bill.</p><p>We are told Azure has a much better model. You have to manually move to a paid service. No surprise bills.</p><p>Like AWS, Azure has a free plan. They even promote it heavily.</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/07/image-2.png" class="kg-image" alt loading="lazy" width="1526" height="818" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/07/image-2.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/07/image-2.png 1000w, https://new.pythonforengineers.com/content/images/2022/07/image-2.png 1526w" sizes="(min-width: 720px) 720px"></figure><p>So I jumped through the hoops to create an account, confirm it via text, give a credit card for security (Aws also ask for it, so I&apos;m used to it).</p><p>Great. Azure tells me to try my &quot;free&quot; services:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/07/image-3.png" class="kg-image" alt loading="lazy" width="1994" height="438" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/07/image-3.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/07/image-3.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2022/07/image-3.png 1600w, https://new.pythonforengineers.com/content/images/2022/07/image-3.png 1994w" sizes="(min-width: 720px) 720px"></figure><p></p><p>So I clicked on it. &#xA0;The very 1st service is Virtual Machines. I choose Linux and press continue. (And the page assures me the services are <em>FREE! 12 Months!!</em>)</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/07/image-9.png" class="kg-image" alt loading="lazy" width="2000" height="664" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/07/image-9.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/07/image-9.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2022/07/image-9.png 1600w, https://new.pythonforengineers.com/content/images/size/w2400/2022/07/image-9.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>But I soon hit a problem. Evidently, I&apos;m not allowed to create a VM in my region. No probs, I&apos;ll choose a different region. But every region shows the same error:</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/07/SCR-20220713-ivi.png" class="kg-image" alt loading="lazy" width="1776" height="986" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/07/SCR-20220713-ivi.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/07/SCR-20220713-ivi.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2022/07/SCR-20220713-ivi.png 1600w, https://new.pythonforengineers.com/content/images/2022/07/SCR-20220713-ivi.png 1776w" sizes="(min-width: 720px) 720px"></figure><p>I spend some time googling. It seems multiple people have hit this problem. During Covid, Microsoft reduced the services available on the free account. Evidently, you cannot create VMs. There are several workarounds suggested:</p><ul><li>Try different regions --&gt; nope, no in all of them</li><li>Raise a ticket asking for approval for regions --&gt; The ticket is rejected because a free account cannot add regions</li></ul><p>The final suggestion is to move to a paid plan.</p><p>Wait what? </p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/07/image-5.png" class="kg-image" alt loading="lazy" width="285" height="320"></figure><p></p><p>After all that heavy marketing about how they had this great &quot;free&quot; plan, seems I have to pay after all?</p><p>But I wasn&apos;t done.</p><p>Surely there must be a solution somewhere? I decided to turn to the wise people of Reddit. The first answer was a nice &quot;<em>F*&amp;^ you, didn&apos;t you read the terms and conditions?&quot;</em></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://new.pythonforengineers.com/content/images/2022/07/image-7.png" class="kg-image" alt loading="lazy" width="2000" height="533" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/07/image-7.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/07/image-7.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2022/07/image-7.png 1600w, https://new.pythonforengineers.com/content/images/2022/07/image-7.png 2094w" sizes="(min-width: 720px) 720px"><figcaption>Pictured: Average Redditor</figcaption></figure><p>Not helpful. I googled a bit more, some people suggested you can still create a database on the free account. But what would I do with a database? Put it in a pipe and smoke it?</p><p>What the hell. I decided to bite the bullet and go for it. Clicked on upgrade to pay-as-you-go.</p><p>And nothing happened.</p><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/07/image-8.png" class="kg-image" alt loading="lazy" width="2000" height="788" srcset="https://new.pythonforengineers.com/content/images/size/w600/2022/07/image-8.png 600w, https://new.pythonforengineers.com/content/images/size/w1000/2022/07/image-8.png 1000w, https://new.pythonforengineers.com/content/images/size/w1600/2022/07/image-8.png 1600w, https://new.pythonforengineers.com/content/images/size/w2400/2022/07/image-8.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>The page opened a big white &quot;Verify Payment Method&quot; screen that just sat there for minutes. Like it was frozen.</p><p>Now I was using a <em>hippie no-one-uses-me Firefox</em>, so I decided to move to the more <em>Manly-now-with-extra-Electrolytes Chrome.</em></p><p>Same result. Same blank screen stuck at the verify payment details screen.</p><p>I couldn&apos;t upgrade my account. </p><p>The only thing common between my Firefox and Chrome is they both use an ad blocker. And if Azure expects me to turn off my ad blocker to give them money, I have some suggestions about where they can shove their &quot;free&quot; VMs.</p><p>All that hype and I can&apos;t even give them money.</p><p>Seems I&apos;m back to evil AWS for now...</p>]]></content:encoded></item><item><title><![CDATA[Learning about AWS/Cloud by Building Practical Projects]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I heard about the <a href="https://cloudresumechallenge.dev/docs/the-challenge/aws/?ref=new.pythonforengineers.com">Cloud challenge</a> some time ago and liked the idea-- of building a practical project to show you Cloud/AWS knowledge. The challenge just builds a simple online resume, which is fine as the challenge is aimed at complete beginners.</p>
<p>I decided to go one step ahead</p>]]></description><link>https://new.pythonforengineers.com/blog/learning-about-aws-cloud-by-building-practical-projects/</link><guid isPermaLink="false">6284c577c79ab1004dfb2c3c</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Wed, 18 May 2022 12:47:59 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I heard about the <a href="https://cloudresumechallenge.dev/docs/the-challenge/aws/?ref=new.pythonforengineers.com">Cloud challenge</a> some time ago and liked the idea-- of building a practical project to show you Cloud/AWS knowledge. The challenge just builds a simple online resume, which is fine as the challenge is aimed at complete beginners.</p>
<p>I decided to go one step ahead and build more complicated projects. Till now I have 2 projects, the details of which are below. I&apos;ve also put all the code on Github, so you can follow along if you want.</p>
<p>(And I&apos;ve got 2-3 more projects planned, keep watching this space!)</p>
<ul>
<li><a href="#project-1-sentiment-duck-compare-reddit-sentiment-with-share-price">Project 1: Sentiment Duck: Compare Reddit Sentiment with Share Price</a></li>
<li><a href="#project-2-rudeshell-a-shell-that-insults-you-when-you-try-to-run-commands">Project 2: Rudeshell: A shell that insults you when you try to run commands</a></li>
<li><a href="#project-3-horrorscope-astrology-for-developers">Project 3: HorrorScope: Astrology for Developers</a>
<ul>
<li><a href="#project-3-horrorscope-astrology-for-developers">To learn: Serverless / Lambda</a></li>
</ul>
</li>
</ul>
<h2 id="project-1-sentiment-duck-compare-reddit-sentiment-with-share-price">Project 1: Sentiment Duck: Compare Reddit Sentiment with Share Price</h2>
<p>Website:<a href="https://sentimentduck.com/?ref=new.pythonforengineers.com">https://sentimentduck.com/</a><br>
Code: <a href="https://github.com/shantnu/sentiment-duck?ref=new.pythonforengineers.com">https://github.com/shantnu/sentiment-duck</a></p>
<p>Ok, I&apos;ll admit this project is a little too ambitious, and I almost quit. I now realise I should have started with something easy. But I&apos;m glad I did, as this is something I&apos;ve wanted to build for years, even since I saw the sentdex.com site.</p>
<p>In this project, I get data from 3 UK subreddits - AskUk, UnitedKingdom and UkPolitics.  I chose these because they are the biggest in the UK, having roughly 3.5 million subscribers (in total) while still having a balance of positive/negative views.</p>
<p>I then look at the top 10 posts daily and calculate the average sentiment for each. <a href="https://new.pythonforengineers.com/blog/natural-language-processing-and-sentiment-analysis-with-python/">Sentiment Analysis</a> is a machine learning technique that tries to guess if the emotion behind the text is positive or negative.</p>
<p>Finally, we compare this sentiment to the FTSE100, which is the list of top 100 companies listed on UK stock exchange. The goal is to check: IS public sentiment (or Reddit sentiment) related to short term stock movement?</p>
<p>Is it accurate? <em>shrugs</em> Like all machine learning, the answer is it depends. This is just a fun project, so I particularly don&apos;t care if it isn&apos;t 100% accurate. (And I have a <strong>legal</strong> notice: Don&apos;t take financial advice from people who spend time on Reddit! If we had brains, we would be somewhere posh, like Y-Combinator News).</p>
<p><strong>The Technology behind the site</strong></p>
<p><strong>Backend</strong></p>
<p>Since the project is complex, the backend is also complex. The code is about 90-95% Python, with a bit of Go. Funnily enough, I wanted Go for the backend (as it is supposed to be faster). Instead, I ended up with Python doing the backend &quot;resource-intensive&quot; part, while Go is being used for displaying the webpage (an alternative to Flask).</p>
<p>The main steps on the backend are:</p>
<ul>
<li>Get data from Reddit -see this <a href="https://new.pythonforengineers.com/blog/build-a-reddit-bot-part-1/">Reddit API tutorial</a></li>
<li>Carry out sentiment analysis see <a href="https://new.pythonforengineers.com/blog/natural-language-processing-and-sentiment-analysis-with-python/">this tutorial</a></li>
<li>Store the data in a database (see below for which one)</li>
<li>Display the data in a web browser</li>
</ul>
<p>The 1st 3 steps run as a background job</p>
<p><strong>AWS Infrastructure</strong></p>
<ul>
<li>I used Terraform to provision AWS, and Ansible to install the tools. Also looked at Packer, but couldn&apos;t get it working with Ansible. Already knew Ansible, but this was a good chance to learn about Terraform</li>
<li>For the DB I used Dynamodb, just because iT iS a CoOl NoSql dAtaBAsE. Did I like it? Well, I had some reservations, mainly not enough documentation (or good docs). But that is a blog for another day</li>
<li>I was planning to use a Lambda function(with Cloudwatch) to update the data in the background-- but I found that AWS uses a different Linux flavour for Lambdas, and I have to use libraries compiled for that. Too much hassle, I just stuck to a cron job (it works and is cheap!)</li>
<li>There is a Github Action to automatically deploy new code on a git push</li>
<li>I also got a chance to play with <a href="https://caddyserver.com/?ref=new.pythonforengineers.com">caddy</a> to get an https site-- and was amazed at how easy it was!</li>
</ul>
<p><strong>Update 4-7-2022</strong>:</p>
<p>Added lambda function to get the stats from the site daily. On weekdays it emails me the summary, on weekends, also sends a text message.</p>
<p>Found lambda function a bit iffy, not easy to use, seeing how much AWS is pushing them. But still learning up on them, trying to use  libraries like Serverless/Sam/Zappa to write lambda code. Still a WIP though.</p>
<h2 id="project-2-rudeshell-a-shell-that-insults-you-when-you-try-to-run-commands">Project 2: Rudeshell: A shell that insults you when you try to run commands</h2>
<p><strong>Update 21-7-2022</strong>: After all the hassle with AWS / containers, I moved this to Google Cloud run-- where it ran out of the box without any issues!</p>
<p>I&apos;ve had more problems setting up the DNS from AS to Google Cloud-- looks like there is a subtle bug that won&apos;t let me link from Route53 to Google.</p>
<p>Site: <a href="http://rudeshell.com/?ref=new.pythonforengineers.com">http://rudeshell.com/</a><br>
Code: <a href="https://github.com/shantnu/rudeshell?ref=new.pythonforengineers.com">https://github.com/shantnu/rudeshell</a></p>
<p>This site was inspired by an xkcd dummy javascript based shell which printed funny replies. It came out 7-8 years ago, but I can no longer find out its link--Googling takes me to standard Xkcd comics.</p>
<p>Anyway, I wanted to build something similar for a long time, but was struggling with the whole Javascript/npm framework world.</p>
<p><strong>Backend</strong></p>
<p>So the code isn&apos;t written in Javscript but Go. I found an awesome tool <a href="https://github.com/yudai/gotty?ref=new.pythonforengineers.com">gotty</a> that turns your command-line utility into a web app.</p>
<p>For security-- I make sure the Go code doesn&apos;t execute anything the user enters, and am also running it in a docker container just to be sure. Could do more like use podman for the containers(so they don&apos;t run in elevated mode), but will stick to docker for now. (Im sure I&apos;ve forgotten something and will be insulted by an online security expert for <em>groan</em>)</p>
<p><strong>AWS Infrastructure</strong></p>
<p><em>Note</em>: This is the old way, Ive moved to GCP</p>
<p>For this project, I wanted to use Kubernetes, but found that it can become stupidly expensive, at least for hobby sites. I tried the light K3s, but found it unstable. So even though I had a basic kubernetes cluster running, I killed it and went back to simple docker compose. It works!</p>
<p>Everything else is same as above-- Terraform and Ansible to setup the system, Github actions to deploy the code on changes</p>
<p>Caddy again for ssh, this time in docker.</p>
<h2 id="project-3-horrorscope-astrology-for-developers">Project 3: HorrorScope: Astrology for Developers</h2>
<h3 id="to-learn-serverless-lambda">To learn: Serverless / Lambda</h3>
<p>Site: <a href="http://horrorscope.co.uk/?ref=new.pythonforengineers.com">http://horrorscope.co.uk</a><br>
Code: <a href="https://github.com/shantnu/horrorscope?ref=new.pythonforengineers.com">https://github.com/shantnu/horrorscope</a></p>
<p>I started this to learn about serverless. Built using Aws Lambda &amp; Serverless framework.</p>
<p>The code is written in Python flask, with the static content hosted on S3.</p>
<p>The hardest part was figuring out how to return HTML, as all serverless examples assume Json.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[The Problem with Most Programming Tutorials / Books]]></title><description><![CDATA[<h2 id="or-why-they-all-suck-and-how-to-improve-them">Or Why they all suck (and how to improve them)</h2><p></p><p>I can&apos;t remember the number of tutorials / books on programming I&apos;ve had to abandon, because the author jumped to advanced concepts too fast, or tried to teach too many concepts at the same time.</p><p>Having worked</p>]]></description><link>https://new.pythonforengineers.com/blog/the-problem-with-most-programming-tutorials-books/</link><guid isPermaLink="false">61bc9ffdad87cf00485f5c5d</guid><dc:creator><![CDATA[Shantnu Tiwari]]></dc:creator><pubDate>Mon, 11 Apr 2022 16:04:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="or-why-they-all-suck-and-how-to-improve-them">Or Why they all suck (and how to improve them)</h2><p></p><p>I can&apos;t remember the number of tutorials / books on programming I&apos;ve had to abandon, because the author jumped to advanced concepts too fast, or tried to teach too many concepts at the same time.</p><p>Having worked with beginners and been a beginner to new technologies myself, I have seen many beginners just quit.</p><p>Most commonly, I see two types of problems:</p><ul><li>The &quot;Rest of the Owl Problem&quot;</li><li>The &quot;I&apos;m writing to impress Reddit/Hacker News&quot; Problem</li></ul><h2 id="the-rest-of-the-owl-problem">The &quot;Rest of the Owl Problem&quot;</h2><p></p><p>There is a <a href="https://old.reddit.com/r/restofthefuckingowl/?ref=new.pythonforengineers.com">whole subreddit</a> dedicated to this. The picture is explains everything:</p><h2></h2><figure class="kg-card kg-image-card"><img src="https://new.pythonforengineers.com/content/images/2022/04/image.png" class="kg-image" alt loading="lazy" width="300" height="244"></figure><p>Many tutorials fall into this trap--they will teach some basic theory or give some toy examples, and then just straight into the complex stuff. You need to teach the basic concepts, step by step, before moving on to more complex stuff. But the authors are so keen to move to the &quot;fun&quot; stuff they skip over the required base knowledge.</p><blockquote>Real world examples tend to have a huge amount of unpleasant details which hinder transfer of the underlying concepts. We teach one step at a time, and even then 99.999% of the people leave before finishing. Suppose you start teaching arithmetics by introducing 5 year olds to elliptic curves&#x2026;</blockquote><p>-- from a <a href="https://news.ycombinator.com/item?id=30941029&amp;ref=new.pythonforengineers.com">comment on HN</a></p><p>I see this problem when I&apos;m trying to learn new technologies not directly related to the day job, where I see the problems beginners struggle with. Some examples:</p><ul><li>Want to learn frontend? You have courses that teach you what an &apos;a&apos; tag is in HTML and how to colour your text with css; and then jump straight to &quot;And now we will build this complex Bootstrap theme&quot;. And I&apos;m like, wait, there are more steps here.</li><li>Here&apos;s how docker works&#x2013; run a Hello World example. Got that? Good, now we will show you how to use k8s to deploy a HA cluster.</li></ul><h2 id="the-im-writing-to-impress-reddithacker-news-problem">The &quot;I&apos;m writing to impress Reddit/Hacker News&quot; Problem</h2><p></p><p>This can also be called the &quot;Shove too much shit into one article, so I can please the Google SEO spam masters, and also impress the chicks/dudes on Reddit.&quot;</p><p> A real-life example: I was reading a tutorial about Django, and the author started by asking us to install Docker &quot;To isolate our code&quot;.</p><p>And I was like&#x2013; Django (unlike data science libraries like numpy / opencv) is written in pure Python, and so has no problems in a simple virtual env. But the author wanted us to use Docker&#x2013; which outside of Linux world, has always caused me problems.</p><p>And after a few chapters, I realised why. He wanted us to use Postgres database. Again, I was like, why? Why not use Sqlite, which is easy to install and remove, and doesnt need docker?</p><p> &quot;Because Postgres is an industrial standard database, and you need to learn how to use it&quot;.</p><p>That&apos;s fine&#x2013; I have full courses that teach me just how to use Postgres. Why don&apos;t you focus on just Django?</p><p>Ultimately, I just abandoned that blog. Even though I had used both Django and Postgres in the past, I found it hard going. I just wonder how people new to programming feel.</p><p>I&apos;ve seen a similar problem in paid books. From a recent book I bought on Go servers: &quot;Know the basics of the Go server? Then you are ready to use MySql&quot;. And I was screaming &quot;No I&apos;m not, you haven&apos;t even covered testing yet!&quot; I could have spent some time getting Sqlite working with Go, but <em>groan </em>its more headache I don&apos;t want (especially since I bought the book to avoid having to Google this stuff).</p><p>Another book abandoned.</p><p></p><p><a href="https://news.ycombinator.com/item?id=30941569&amp;ref=new.pythonforengineers.com">Relevant comment</a>:</p><blockquote>When you&apos;re teaching something new, you want to be able to isolate that concept/technique and focus in on it. A simplified example, or a question with strict parameters, both allow the student(s) to concentrate on the key idea.</blockquote><blockquote>If you want to teach someone about SELECT in SQL, for example, it&apos;s useful to abstract away the database setup for that particular lesson. It&apos;s also useful to use a simplified database concerned with familiar entities, so that SELECT remains the focus rather than one new element of many.</blockquote><blockquote>Of course, these simplified examples shouldn&apos;t be used in isolation. Instead, you should have a number of them, eaching illustrating/assessing some small point or idea. Once the students have absorbed those ideas, then you start combining the initial building blocks into more complex ideas, just as you&apos;d take a tiered approach when testing software; start with unit tests, then build up.</blockquote><p>Why do people shove so much stuff into one post? One is to please Google, which loves all the keywords. Look at all these spammy sites on the top of Google. </p><p>Search for &quot;How to run a command inside docker&quot;, the 1st few paragraphs will be: <em>What is docker, why would you use docker, who created docker etc etc</em> </p><p>All useless crap that doesn&apos;t answer the question but helps rank the site.</p><p>A second reason I see is: Authors get attacked on Reddit/HN for not being perfect enough for someone&apos;s taste. Actual comment on Reddit to one of my posts:</p><blockquote>For a site that claims to be called Python for Engineers, the author seems to know little about software engineering. He doesn&apos;t use virtual envs and the code isn&apos;t pep8 compliant</blockquote><p>The blog post in question was a 500-word blog with like 10 lines of code, and yet multiple commenters criticised me <em>fOr nOt beINg a rEAl engIneeR</em></p><p>I know this gets to some people, and so they start writing defensively, anticipating any criticism and overcompensating for it. But here&apos;s the deal: People will always find something to attack you for.</p><p>I just stopped reading comments to my own blogs on HN/Reddit. Even if I get a thousand upvotes (which means the community as a whole likes it), the top comments will usually be mean spirited nitpicking attacks. No thanks, I&apos;ll pass. Like Steven Yegge said at one point, if you hate what I&apos;m saying, feel free to write your own blog explaining why. But that is hard work, and so no one will do it.</p><h2 id="feedback-for-creators">Feedback for Creators</h2><p></p><p>If you are a blogger or course/book creator:</p><ul><li>Focus on teaching one concept at a time</li><li>Don&apos;t worry about &quot;best&quot; or &quot;industry&quot; practices&#x2013; just teach the basics first</li><li>Repeat a lot&#x2013; beginners need to read a new topic multiple times before they will understand it. Don&apos;t assume because you covered it once that they &quot;get&quot; it</li><li>Write to help beginners, not impress randos on social media</li></ul><p>I should end with an example of a great book&#x2013; <a href="https://djangoforbeginners.com/?ref=new.pythonforengineers.com">Django for Beginners </a>by William Vincent. It doesn&apos;t assume anything; in every chapter, the author revisits every step. </p><p>So in every chapter, he creates a new virtual env, a new project, sets up the urls/routing etc. So the 1st 20% of each chapter repeats the same basic steps.</p><p> At first, I found this a bit slow, but later I realised the constant repetition made sure we understand every single thing being taught. It (and the follow-ups) really are great books that finally made it click for me about how Django works.</p><p>Another good example: for DevOps, the Kode Cloud paid courses (which I got on Udemy). They all teach one small thing at a time with lots of examples and practices. No wonder the courses are top-ranked on Udemy, though they are comparatively recent compared to other courses.</p><p><em>tldr; Go slow. Repeat a lot. Don&apos;t skip steps.</em></p><p>(I want to add: And you will make a million dollars, but I&apos;m worried I&apos;ll end up on the <a href="https://old.reddit.com/r/restofthefuckingowl/?ref=new.pythonforengineers.com">owl reddit,</a> so I won&apos;t :) )</p>]]></content:encoded></item></channel></rss>