[{"content":"LLMs won\u0026rsquo;t replace engineers AI is improving at a sustained, impressive pace. During 2025, models went from being a novelty with potential to being a genuinely useful tool that I use daily. The improvement in both models and tooling has been remarkable.\nThat said, I\u0026rsquo;m still not convinced that LLMs will replace software engineers. It will just make engineers more productive and reduce the pressure on the workforce of this industry. The day we achieve artificial general intelligence everything will change, then it won\u0026rsquo;t just be the software engineers job that we should be worried about. Until then, what we have is a very capable tool, a leverage that landed quicker than probably any other before it.\nI\u0026rsquo;ve been doing this job for 15 years. It is obviously impossible to tell where the LLM\u0026rsquo;s capabilities will land, however my gut feeling is that there is only so much that we can squeeze out it. Based on my current conversation with Opus 4.6, which I consider to be the best of the best at the moment, it is incredibly capable but it is no senior software engineer. It is like dealing with a smart junior engineer that works at 100 times the speed.\nThe easy part easier, the hard part harder There\u0026rsquo;s an excellent article by Blundergoat called AI Makes the Easy Part Easier and the Hard Part Harder that I agree with completely.\nWriting code was never the hard part. It\u0026rsquo;s writing code well. It is understanding the problem, navigating ambiguity, knowing why a particular approach is the right one, and having the judgment to make architectural decisions.\nThis is exactly why you should lean into AI for the easy parts and stop fighting it on the hard parts. Use it where it shines, go old school where it doesn\u0026rsquo;t.\nThere are still plenty of times where even the most capable model, across multiple providers, leads me absolutely nowhere and I have to do things the old-fashioned way. In the previous year, I invested a significant amount of my time into experimenting with the capabilities of AIs and I\u0026rsquo;ve started to understand what it is good at and what it is not good at. And so, being able to speed up my work when I\u0026rsquo;m quite confident that LLM will do well and not waste my time where I am not confident that it will, is what I think is the trick that a lot of people are missing out on.\nFrom assembly to English Here\u0026rsquo;s how I see the current landscape.\nConsider the history of programming: machine code was written for computers, by humans who had to think like computers. Then came C, relatively close to the metal, but more readable, more expressive. Then Python built on top of it, abstracting further. Each layer made things easier to read, easier to express, easier to reason about. The human brain is capable of infinite wisdom and capacity of understanding, however, in our day-to-day, this amount is actually very finite. For example, Python allows us for our thoughts to go much further because they are abstracted much more than C and assembly were capable of.\nNow we\u0026rsquo;ve added another layer: English.\nWe\u0026rsquo;ve gone from a language designed for computers, to a compromise between computer and human language (at varying degrees), to the actual native language of the programmer. AI is giving us a similar leap over high-level languages as high-level languages gave us over assembly.\nHowever, here I should also address another concern of mine, and that is that our natural language is actually not as perfect as we usually like to think. When you express a concept to somebody, you may have to go into a certain level of detail that varies depending on shared context and how much you think your interlocutor is going to understand from what you\u0026rsquo;re saying. And so, in real time, you adapt and express more or less, depending on the situation. You will certainly be familiar with how sometimes the thoughts that you have expressed in your native language may have not landed in the way that you thought they should have.\nThe real bottleneck is human willpower I\u0026rsquo;ve been saying this for years: the limiting factor in programming is not the computer or the language. It\u0026rsquo;s the human brain, but in particular, not even necessarily our intelligence. We only have so much willpower to chase down a bug. So much memory to hold a system in our heads. So much patience to set up a test environment, write boilerplate, or untangle someone else\u0026rsquo;s abstractions.\nThis is why I\u0026rsquo;ve always advocated for keeping code simple, not over-optimising, and making things easier for your future self. If you make things easier for future-you, then future-you will have more willpower to spend on the actual investigation, planning, etc.\nThe interface between humans and the power of computers has always been the bottleneck. When higher-level languages were introduced, humans suddenly achieved much more — not because they got smarter, but because the interface got better, the friction lower. The exact same thing is happening now with AI.\nI\u0026rsquo;m still doing the thinking I\u0026rsquo;ve read people on Hacker News saying they miss \u0026ldquo;doing the thinking\u0026rdquo; now that AI is involved. I disagree. I\u0026rsquo;m still doing the same amount of thinking. Maybe even more, because I can now tackle problems I would have previously shelved as too laborious.\nPerhaps those people mean they miss tinkering with lower-level details, which is perfectly valid. I understand the appeal. But I don\u0026rsquo;t feel like AI is doing the thinking for me. It\u0026rsquo;s more like working together: I think, I direct, I review, I decide. The AI helps me execute faster. The thinking is still mine.\nThe complaint that they miss doing the thinking is the same as saying \u0026ldquo;I miss setting the registries of the CPU manually now that I have a higher level language that doesn\u0026rsquo;t require me to do it\u0026rdquo;. By all means, you can go and set the registries of the CPU manually, but is that really practical? Aren\u0026rsquo;t there other interesting problems that you can tackle with how much brain power you have freed up?\nWhat AI has unlocked for me Now that I feel that I have a good understanding as to where I can leverage AI and the very latest models are generally good, I\u0026rsquo;d say that in the best cases I can achieve the mythical 10x programming. Maybe even more. Side projects that I always wanted to do but never had the time or energy for are now feasible. Investigations that used to be laborious are quicker. Things that were annoying to put together now have shortcuts.\nI built a few VS Code extensions that I\u0026rsquo;d wanted for years — small tools to navigate code more effectively. I\u0026rsquo;m particularly proud of one that lets you navigate to any line of Python code just by having the stack trace in your clipboard. It\u0026rsquo;s not perfect, but it\u0026rsquo;s something I always wanted and never would have built without AI. Not because I wasn\u0026rsquo;t capable, but because the friction to work in typescript and understand how to write a VScode extension was too high.\nI\u0026rsquo;ve built machine learning models to predict delinquency for invoices at Yelp. I trained a model to recognise my black cat compared to other black cats. Small things, silly things, practical things — all of them now within reach.\nAnd I\u0026rsquo;m writing a book. This is something I\u0026rsquo;ve always wanted to do, but it always seemed too much — too many words, too much structure, too much effort on top of a full-time job.\nPractical advice AI is great for greenfield, less so for production Accept this and work with it. For new projects, AI is extraordinary. For complex, established codebases with years of accumulated decisions, it struggles. That\u0026rsquo;s fine, leverage the strengths and avoid the weaknesses.\nPlan ahead and explain well You reap what you sow. If you express something in as few words as possible and hit enter don\u0026rsquo;t complain if the response isn\u0026rsquo;t what you were hoping for. Then you\u0026rsquo;ll review it, redo it, and start losing patience. You may even think that LLMs are a fad, and you would be better off without it.\nInstead: explain things well, once. Link the files you refer to. Do some planning together with the AI before you start. Then execute your plan. The upfront investment pays for itself.\nagents.md is the most important thing you should configure The file agents.md is probably the single most powerful leverage point you have, and I don\u0026rsquo;t see this being said enough, or strongly enough.\nEvery single time you open a new chat, it\u0026rsquo;s as if you\u0026rsquo;re talking to a brand new engineer on their first day. There is absolutely no reason not to invest time in writing, optimising, and tuning these files.\nUse AI to use AI I use AI to help me use AI better. I ask it what prompt would work best, whether syntax and grammar matter when writing prompts, whether the order of instructions makes a difference. If there\u0026rsquo;s a disagreement and I think the AI should have known better, I ask it why it thinks the disagreement originated and how we can prevent it. More often than not, I end up having the AI update my agents.md file to avoid the same issue next time. I review everything, of course.\nExperiment more Think about all the things you couldn\u0026rsquo;t do before. Just try asking AI to do something, go on, just for the lols. See how far you can push it. You might be surprised.\nWhen making the placeholder website for my book I thought \u0026ldquo;Now that I have made the cover image I wonder if I can make the book in 3D\u0026rdquo;. The result, after several iterations, is quite stunning.\nLLMs are cheerful but I\u0026rsquo;m grumpy LLMs are tuned by companies that want to make money. I imagine that those companies have figured out that making LLMs sound cheerful and overconfident makes users happier. As long as the user is sold then the bottom line is subscriptions. A suppose that a fair, balanced and trustworthy LLM wouldn\u0026rsquo;t sell as much. They are accommodating to a fault. They will compliment your awesome ideas. \u0026ldquo;Great catch!\u0026rdquo;. \u0026ldquo;You are absolutely right\u0026rdquo;.\nLLMs can\u0026rsquo;t be trusted. I\u0026rsquo;ve addressed this in my own agents.md by asking them to label their own confidence about their statements, to not sound like cheerleaders, and to flag uncertainty explicitly. You should do the same.\nCase in point: this post This post you\u0026rsquo;re reading right now is AI-generated. But the difference between a low-quality AI post and a high-quality one is the same as the difference between low-quality and high-quality code. I carefully selected what to say. I let AI help me write it. Then I checked everything, added a little, rewrote some parts, adapted some more. Two passes. I have probably saved some time, and in the meantime I migrated the website from prose.sh to Hugo on Cloudflare. Why not.\n","permalink":"https://stefano.chiodino.uk/posts/2026-02-10-2026-is-the-year-of-serious-ai-engineering/","summary":"\u003ch1 id=\"llms-wont-replace-engineers\"\u003eLLMs won\u0026rsquo;t replace engineers\u003c/h1\u003e\n\u003cp\u003eAI is improving at a sustained, impressive pace. During 2025, models went from being a novelty with potential to being a genuinely useful tool that I use daily. The improvement in both models and tooling has been remarkable.\u003c/p\u003e\n\u003cp\u003eThat said, I\u0026rsquo;m still not convinced that LLMs will replace software engineers. It will just make engineers more productive and reduce the pressure on the workforce of this industry. The day we achieve artificial general intelligence everything will change, then it won\u0026rsquo;t just be the software engineers job that we should be worried about. Until then, what we have is a very capable tool, a leverage that landed quicker than probably any other before it.\u003c/p\u003e","title":"2026 Is The Year Of Serious AI Engineering"},{"content":"The boring prose bit Journaling has been a useful tool for personal reflection. One thing that I really like is that it\u0026rsquo;s private, which means that I can be open and honest. I don\u0026rsquo;t need to worry to be judged or hurt people\u0026rsquo;s feeling. It\u0026rsquo;s just like thinking, but with rubber-ducking included. It\u0026rsquo;s interesting to go back and read old entries, and I find it it\u0026rsquo;s easier to focus on my thoughts.\nSo far, I really liked Day One to keep my journal. This is a fantastic free option if you want to journal from one computer. To sync your journal between computers (and more) it requires a premium subscription of $34.99 per year (currently £27.74). This is a very good price for what you get.\nHowever, I was a bit bored, and I wanted to play with Obsidian because Hacker News absolutely loves Obsidian. I regretted getting advices from Hacker news only 70% of times.\nThere are various solutions to encrypt notes, add secrets, etc in Obsidian. However, I couldn\u0026rsquo;t find a plugin that ticked all the boxes, so I iterated on an Obsidian forum answer.\nHow to encrypt your Obsidian vault On MacOS, open The Disk Utility app.\nIf you don\u0026rsquo;t already have a vault, in the menu, select File -\u0026gt; New Image -\u0026gt; Blank Image... If you already have a vault, in the menu, select File -\u0026gt; New Image -\u0026gt; Image From Folder..., and use your vault\u0026rsquo;s folder Then, select the strongest encryption option, and a read/write image format. Since you are at it, put it in your iCloud / dropbox / gDrive / etc folder.\nYou now have an encrypted file. To mount it you\u0026rsquo;ll be asked for the password, but if you\u0026rsquo;d like you can save it in your keyring so that you won\u0026rsquo;t have to type it every time. This, however, goes against most of the reasons you\u0026rsquo;d be wanting this setup 😉. When mounted, you vault folder will be located in /Volumes/Obsidian Vault or something similar, and easy to reach in finder:\nHow to sync Obsidian vaults are folders. They are portable, in the sense that they contain all the settings and plugins related to the vault. This is a great advantage because it makes synching even easier.\nJust put your encrypted vault file in a folder synched with any cloud service.\nThe file will be written when the vault is ejected from the system. This is an important consideration to keep in mind, which I couldn\u0026rsquo;t work around.\nRefinements So far we have tickets all the boxes that I wanted, but automating is fun, so here is how to turn a 3-clicks workflow into a 1-click one.\nThe biggest issues with the setup so far is that the vault needs to be ejected from the system for the file to be synched, and preventing anybody from accessing their raw content without the password.\nMounting, journaling, ejecting, synching Automating mounting the vault before Obsidian is launched is even easier: create a script to mount the vault, then launch Obsidian, then eject the folder.\nopen --wait-apps /Users/stefanochiodino/Documents/Obsidian\\ Vault.dmg \u0026amp;\u0026amp; open --wait-apps /Applications/Obsidian.app \u0026amp;\u0026amp; hdiutil detach /Volumes/Obsidian\\ Vault --wait-apps tells open to wait for that app, which makes it easier to chain commands together.\nWhen you run this, you\u0026rsquo;ll see a terminal window open during this workflow.\nAnnoyingly, closing the Obsidian window but keeping the app running means that the vault is not ejected. A non ejected vault is a not synched vault either!\nA safer ejection To help with the issue of Obsidian not shutting down just by closing the window, you could force ejecting the vault when that window is open.\nShell commands is an awesome Obsidian plugin that allows to run shell commands, automatically. You can configure it to automatically eject the folder when Obsidian is closed:\nCreate a new command hdiutil detach -force /Volumes/Obsidian\\ Vault.\nConfigure the command to execute automatically when Obsidian is closed:\nPro and cons Pro:\nSimple setup Very low friction to write encrypted synched notes Leverages Apple\u0026rsquo;s encryption, because the less encryption you do the safer it is Few and easy to understand commands, so that you know what you are doing and that I\u0026rsquo;m not screwing you over Free Cons\nHow can I be sure that Apple/Dropbox/Google/etc won\u0026rsquo;t just delete my account an my files? You could setup a symlink to make sure that the files are in another folder as well. No mobile setup In this incarnation, MacOS only The vault syncs only when it\u0026rsquo;s ejected from the system The lack of CLI commands for Obsidian makes this harder than it could have been ☹️ Alternatives Obsidian Sync offers end-to-end encryption, and supports the Obsidian project. However, it doesn\u0026rsquo;t encrypt the vault at rest. You could still mix and match the approaches: encrypt the vault at rest using the method above, and sync using Obsidian\u0026rsquo;s service.\njrnl.sh is a command line journaling tool. It offers very good encryption at rest, and can be synched using any cloud service. Comes with the usual pro and cons of a mostly CLI app.\nDay One is a great app for journaling. The premium plan is quite accessible and allows to sync. It even works on a browser (beta), which means that it\u0026rsquo;s platform agnostic. This doesn\u0026rsquo;t solve encrypting at rest tho!\nGotchas I\u0026rsquo;m not an Obsidian expert, so don\u0026rsquo;t just listen to me. By default, Obsidian will move deleted files to the system trash, where they will be stored unencrypted. ","permalink":"https://stefano.chiodino.uk/posts/2023-08-29-encrypted-synched-obsidian-vault-journaling-macos/","summary":"\u003ch1 id=\"the-boring-prose-bit\"\u003eThe boring prose bit\u003c/h1\u003e\n\u003cp\u003eJournaling has been a useful tool for personal reflection. One thing that I really like is that it\u0026rsquo;s private, which means that I can be open and honest. I don\u0026rsquo;t need to worry to be judged or hurt people\u0026rsquo;s feeling. It\u0026rsquo;s just like thinking, but with rubber-ducking included. It\u0026rsquo;s interesting to go back and read old entries, and I find it it\u0026rsquo;s easier to focus on my thoughts.\u003c/p\u003e","title":"Encrypted synched Obsidian vault journaling on MacOS"},{"content":"The idea of pirate treasure derives from a single incident involving William Kidd in 1699. Kidd was about to be arrested, but before confronting the authorities he buried his treasure on Gardiners Island. He first asked permission to John Gardiner, the island\u0026rsquo;s owner, who later handed over the treasure to the authorities.\nThis is the whole history of pirate treasure. It inspired Robert Louis Stevenson\u0026rsquo;s Treasure Island, which almost single handedly created the modern image of pirates.\nSource: How To, by Randall Munroe\n","permalink":"https://stefano.chiodino.uk/posts/pirate-treasures-are-fiction/","summary":"\u003cp\u003eThe idea of pirate treasure derives from a single incident involving William Kidd in 1699. Kidd was about to be arrested,\nbut before confronting the authorities he buried his treasure on Gardiners Island. He first asked permission to\nJohn Gardiner, the island\u0026rsquo;s owner, who later handed over the treasure to the authorities.\u003c/p\u003e\n\u003cp\u003eThis is the whole history of pirate treasure. It inspired Robert Louis Stevenson\u0026rsquo;s Treasure Island, which almost single\nhandedly created the modern image of pirates.\u003c/p\u003e","title":"Pirate treasures are fiction"},{"content":"Do you want to add geotagging (latitude and longitude coordinates) to your photos?\nThis is particularly useful if you use DSLR or mirrorless cameras that often lack this feature.\nAll you need for this is to have location history enabled in google maps. This process will add a location to a photo based on where your phone reported you where when the photo was taken.\nGo to your timeline. and download each day you want to use using the cog at the bottom right\nPut the photos to tag and the KML activity files in the same folder, and for each run\nexiftool -overwrite_original -geotag act_ity_file.kml . If you receive a warning like\nWarning: No writable tags set from ./2022-05-08 13.33.27.jpg Warning: Time is too far from nearest GPS fix in File:Geotime (ValueConvInv) - ./2022-05-08 13.33.37.jpg This means that there are no GPS points within the default 30 minutes of the photo. To extend this time you can use the -api flag like -api GeoMaxIntSecs=9999 -api GeoMaxExtSecs=9999. See the exiftool documentation.\nSee also this post where I refined this idea from.\n","permalink":"https://stefano.chiodino.uk/posts/geotag-photos-with-gps-coordinate-from-google-maps-location-history/","summary":"\u003cp\u003eDo you want to add geotagging (latitude and longitude coordinates) to your photos?\u003c/p\u003e\n\u003cp\u003eThis is particularly useful if you use DSLR or mirrorless cameras that often lack this feature.\u003c/p\u003e\n\u003cp\u003eAll you need for this is to have location history enabled in google maps. This process will add a location to a photo based on where your phone reported you where when the photo was taken.\u003c/p\u003e\n\u003cp\u003eGo to \u003ca href=\"https://timeline.google.com/maps/timeline\" title=\"your timeline\"\u003eyour timeline\u003c/a\u003e. and download each day you want to use using the cog at the bottom right\u003c/p\u003e","title":"Geotag photos with GPS coordinate from Google Maps location history"},{"content":"Ask for more money Have you received a new job offer? Ask for more money. Have you received a pay raise? Ask for more money. If you cringe at the idea of asking for more money, you likely really need to ask for more money.\nEvery year you have (hopefully) improved. You are wiser, learned some tech for a whole year, learned the processes, met the people, and therefore are worth more. So ask to be remunerated accordingly. Every time you receive a pay rise, google for the current inflation and discount that percentage from it. Lead the conversation this way during the meeting.\nNever tell recruiters how much you earn, or want There is no way any of this is going to play in your favor. Always decline to say how much you are currently making, or want. On the contrary, always ask for a salary bracket.\nAsk why Workers know how, gods know why.\nAsk why, always. Why should you ask why you say? You learn quickly, I\u0026rsquo;m impressed! People tend to tell you how to solve a problem, rather than what the problem is, and they may not have considered certain things. This is particularly true when talking to non-engineers. Knowing why you are doing something also strengthens your understanding, and allows you to do a better job.\nYou should also keep this in mind when you are asking for help yourself: don\u0026rsquo;t just say what you need help with, start saying why you are doing it!\nIf you are new and feel like it would cause friction, just say that you really really want to learn.\nDoing vs. learning I\u0026rsquo;m more of a doer, and this had a negative impact over time. The pressure to deliver and prove yourself will push you to try and cut the learning short, and push forward. This is what my friend Lee calls “programming by coincidence”.\nSo, remember to take it slowly, and research a topic before jumping in and try to fix something you don’t know well. It will pay dividends.\nImpostor syndrome It\u0026rsquo;s important for you to understand that you will always feel like you don\u0026rsquo;t know what you are doing. That\u0026rsquo;s because you think most of your job should be \u0026ldquo;doing\u0026rdquo;, but in reality it is to find out how or even what you are doing.\nThe more you know, the more you know what you don’t know.\nI’m often asked “when will this stop?”. If you do things right, it will never stop.\nCareer leverage points There are a few things in your career that you can get a lot of leverage out of. Interviewing and your CV are a couple of them.\nInvest a lot of time on your CV. Be 100% sure there are no typos. Keep it around 2 pages. Sell yourself without lying.\nI revise mine often, mostly adding whatever comes to mind. Afterall, it will come with you for decades to come!\nI’ve probably done more than a hundred interviews. I’ve also run dozens of them as an interviewer, which by the way helps (so go on sign up to run interviews for your company now!). This helps me to know what interviewers want, perform better in tech tests, being more confident, etc. It reduces the cognitive load during interviews, allowing time to think at a higher level.\nBuy “Cracking the Coding Interview “by Gayle Laakmann McDowell, it’s worth it!\nOwnership Try to make all problems your problems and people will love you for it. In the right company, you’ll also get rewarded for it.\nWork life balance Make the most of your 7/8 hours of work every day, then switch off. If you can\u0026rsquo;t finish something that\u0026rsquo;s too bad, there is always tomorrow. Do you have too much to do and you can\u0026rsquo;t possibly fit it in your working day? That\u0026rsquo;s too bad, but your manager/team-lead should probably have planned things so that they could fit in your working day.\nI only have two exceptions to this rule:\nIf you screwed something up, you need to clean up after yourself.\nAs a one-off, if there is a particular deadline, go-live, or the like, be flexible.\nYes, but Whether it\u0026rsquo;s been planned in an agile fashion, or another way, you\u0026rsquo;ll have a certain stream of work. At some point you\u0026rsquo;ll be asked to work on something else. This usually comes in the form of \u0026ldquo;could you just\u0026hellip;\u0026rdquo; or \u0026ldquo;spend 5 minutes on\u0026hellip;\u0026rdquo;. The person you are talking to probably don\u0026rsquo;t realize how complicated things are, hence they think it\u0026rsquo;s a \u0026ldquo;5 minutes\u0026rdquo; job. But there is no such thing.\nWhen you work, your time doesn\u0026rsquo;t belong to you, you are selling it, and if someone asks you to do something the only plausible answer is \u0026ldquo;yes\u0026rdquo;. Yes, but.\n\u0026ldquo;Yes, but unfortunately this is not quite a 5 minutes job. If I do this I won\u0026rsquo;t be able to hit the deadline we set during our sprint planning. But if you are happy with this and you have communicated to the right people I\u0026rsquo;ll be happy to do this\u0026rdquo;.\nI\u0026rsquo;ve been delivering this line or variations thereof for the best part of a decade. It never fails me.\nCommunication Invest a lot of time and effort in communication. Nowadays a lot of this happens in emails, chats, etc, and this gives you the chance to be more mindful about it. Read back what you are about to send (it helps if you read it out loud). Make it as short as possible. Rewrite any ambiguities. Don’t show off.\nI’ve done a business writing course on Coursera and I’d recommend it to anybody. It’s a great investment.\nHonesty Always try to be honest, people can tell subconsciously even if they don’t catch you. Even if you get away with it, it\u0026rsquo;s only a matter of time. Lack of honesty breaks trust, and we are nothing without it.\nIf you have a problem, communicate. Do you think you won’t make a deadline? Do you think you are doing something that’s not worth your while? Or is there something else that should be done? Speak up!\nPeople are not computers In the long term, this is a team sport, and “people” is one of the biggest problems to crack. You may be in the business because you like to write software, but to do well in this job you need to deal with people effectively.\nLearn how to:\nPersuade people by not creating friction (e.g. “I’m right and you are wrong, and I’m going to prove it to you”) but rather bringing them on a journey with you. Build relationships. Gently and tactfully ask personal questions. Ask colleagues to go out. Etc. Give in a little sometimes. ","permalink":"https://stefano.chiodino.uk/posts/2022-02-12-advice-to-new-software-engineers/","summary":"\u003ch1 id=\"ask-for-more-money\"\u003e\u003cstrong\u003eAsk for more money\u003c/strong\u003e\u003c/h1\u003e\n\u003cp\u003eHave you received a new job offer? Ask for more money. Have you received a pay raise? Ask for more money. If you cringe at the idea of asking for more money, you likely really need to ask for more money.\u003c/p\u003e\n\u003cp\u003eEvery year you have (hopefully) improved. You are wiser, learned some tech for a whole year, learned the processes, met the people, and therefore are worth more. So ask to be remunerated accordingly. Every time you receive a pay rise, google for the current inflation and discount that percentage from it. Lead the conversation this way during the meeting.\u003c/p\u003e","title":"Advice to new software engineers"},{"content":"Here are some non obvious thoughts about reviewing code.\n\u0026hellip; it depends This has little to do with code reviews, yet it\u0026rsquo;s some of the best advice you\u0026rsquo;ll ever find around: it depends. Don\u0026rsquo;t take this article, or any other articles out there, for gospel.\nWhen you are looking for a review Do your homework Do not submit code for reviewing before you reviewed it yourself. It\u0026rsquo;s annoying. It shouldn\u0026rsquo;t be the reviewer\u0026rsquo;s job to tell you to remove print statements, write tests, etc.\nI usually review the code before every commit, but when I\u0026rsquo;m almost ready to submit my code for a review I give it a once-over to make sure it\u0026rsquo;s ready.\nMake sure the tests pass, you didn\u0026rsquo;t leave TODOs, you are even accomplishing what you set out to, etc.\nIf you aren\u0026rsquo;t sure about your code then don\u0026rsquo;t ask for a code review, ask for an opinion, help, or pair programming. Never submit code you are not sure it\u0026rsquo;s correct.\nThe Swiss cheese model refers to a security model, but applies to so much more, including code quality and code review. The less confident you are about your code, the bigger the holes in your slice of cheese.\nMake sure the reviewer is happy before progressing Whatever the process in your company/project/team, make sure the reviewer is happy to proceed before you move forward. Don\u0026rsquo;t go resolving all the issues they raised and click merge.\nWhen you are reviewing It takes time To review code it takes approximately 1/10 of the time it took to write it. Take your time, it\u0026rsquo;s not a race, and it\u0026rsquo;s important.\nTailor your review to your audience When you know your colleagues you\u0026rsquo;ll start to be able to conduct yourself differently, depending on their strengths and weakness. I know a developer who is thorough, writes tests, etc. I reviewed thousands and thousands of lines of their code, and all I ever found was maybe a forgotten print statement. So now, whenever I review their code, I sit back, scroll a bit faster, and maybe even focus on learning from them. When I review some other people\u0026rsquo;s code I know that I need to check every comma, insist good code style is maintained, etc.\nYou are dealing with people There will be times that you\u0026rsquo;ll be technically correct. The best kind of correct.\nBut how should you express yourself?\nLet\u0026rsquo;s be honest, people skills are not rampant in this industry. Computers don\u0026rsquo;t care how you express your thoughts to them, but people do, and software development is a team sport. Whenever you find something that\u0026rsquo;s not quite right, please, try to express your thoughts politely.\n\u0026ldquo;This is wrong because\u0026hellip;\u0026rdquo; CTRL+A DEL \u0026ldquo;Have you considered\u0026hellip;\u0026rdquo;. What\u0026rsquo;s the difference between these two? One may upset some people, the other is less likely to do so. One is a critic, the other one a suggestion.\nSometimes niceties run short, and you may have to tell people that what they are doing is not good, but being right is not a good reason for being nasty.\nIt\u0026rsquo;s not time for debates Tabs or spaces? Code reviews are not the right venue to establish it! In part because it\u0026rsquo;s obviously spaces, but also because your opinion doesn\u0026rsquo;t matter at code review time.\nThere should be relatively specific code styles for your company/project/team. Hopefully they are up for debate.\nYou prefer double quotes to single ones? One for the committee, not for a merge/pull request.\nSee this insightful talk from Raymond Hettinger on PEP8, which dictates the style for Python.\nStart from understanding what needs to be done One thing is to scan some code to find bugs, but you also need to make sure that the code is achieving the right thing. Start from the ticket, or wherever else the code came from, to make sure it\u0026rsquo;s doing what it should.\nPerfect is the enemy of good My friend James is a ninja 🥷 hacker 👨‍💻, yet he\u0026rsquo;s not going to pester you to make your code perfect. Why? Because when work needs to be done, good is good enough.\nBe like James.\nThis is just another area where the Pareto principle (A.K.A. 80/20 rules) applies. Don\u0026rsquo;t sweat the small stuff.\nOther general advice Double tap Not sure? Ask for more people to review! If either party feels unsure, then it\u0026rsquo;s fair to say you\u0026rsquo;d benefit from having someone else reviewing the same code.\nI already mentioned the Swiss cheese model. Here you are adding more slices to catch more problems.\nOther resources Smartbear\u0026rsquo;s Best Practices for Code Review\n","permalink":"https://stefano.chiodino.uk/posts/2021-10-23-what-you-should-know-about-reviewing-code/","summary":"\u003cp\u003eHere are some non obvious thoughts about reviewing code.\u003c/p\u003e\n\u003ch1 id=\"-it-depends\"\u003e\u0026hellip; it depends\u003c/h1\u003e\n\u003cp\u003eThis has little to do with code reviews, yet it\u0026rsquo;s some of the best advice you\u0026rsquo;ll ever find around: it depends. Don\u0026rsquo;t take this article, or any other articles out there, for gospel.\u003c/p\u003e\n\u003ch1 id=\"when-you-are-looking-for-a-review\"\u003eWhen you are looking for a review\u003c/h1\u003e\n\u003ch2 id=\"do-your-homework\"\u003eDo your homework\u003c/h2\u003e\n\u003cp\u003eDo not submit code for reviewing before you reviewed it yourself. It\u0026rsquo;s annoying. It shouldn\u0026rsquo;t be the reviewer\u0026rsquo;s job to tell you to remove print statements, write tests, etc.\u003c/p\u003e","title":"What you should know about reviewing code"},{"content":"I have found out that recruiters have hunted me down using the email address I have inadvertently used to commit in Github. Unfortunately it\u0026rsquo;s not straightforward to replace this, but here is what I\u0026rsquo;ve done:\nFrom an empty folder clone all your public repos using github API. Replace YOUR-GITHUB-USERNAME.\nfor SSH_URL in $(curl -s https://api.github.com/users/YOUR-GITHUB-USERNAME/repos | grep ssh_url | cut -d\u0026#39;\u0026#34;\u0026#39; -f 4) do git clone $SSH_URL done This is a good time to BACKUP THIS ENTIRE FOLDER.\nFor every repo just cloned, run git filter-branch and check the committer and author email (they are two different things).\nI had multiple emails, and each needs to be checked for each case. This looks crazy syntactically, but still easier than an in operator in bash\u0026hellip; You\u0026rsquo;ll need one line to test for each case you may have used like \u0026ldquo;EmailOne\u0026rdquo;, \u0026ldquo;emailone\u0026rdquo;, \u0026ldquo;emailTwo\u0026rdquo;, etc, depending on how you tend to type this.\nForce push after this is done. I have commented out this line because you\u0026rsquo;ll probably want to check what happened (use git log).\nfor dir in ./*/ do cd $dir || exit pwd FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --commit-filter \u0026#39; if [ \u0026#34;$GIT_COMMITTER_EMAIL\u0026#34; = \u0026#34;ONE.OF@YOUR.EMAILS\u0026#34; ] \\ || [ \u0026#34;$GIT_COMMITTER_EMAIL\u0026#34; = \u0026#34;ANOTHER.ONE.OF@YOUR.EMAILS\u0026#34; ] \\ || [ \u0026#34;GIT_AUTHOR_EMAIL\u0026#34; = \u0026#34;ONE.OF@YOUR.EMAILS\u0026#34; ] \\ || [ \u0026#34;GIT_AUTHOR_EMAIL\u0026#34; = \u0026#34;ANOTHER.ONE.OF@YOUR.EMAILS\u0026#34; ]; then GIT_COMMITTER_EMAIL=\u0026#34;i-dont-want@to-be-recuited.thank-you-very-much\u0026#34;; GIT_AUTHOR_EMAIL=\u0026#34;i-dont-want@to-be-recuited.thank-you-very-much\u0026#34;; git commit-tree \u0026#34;$@\u0026#34;; else git commit-tree \u0026#34;$@\u0026#34;; fi\u0026#39; HEAD #git push -f cd .. done If you are trying to dodge recruiters maybe you should check out this project that will allow you to filter their emails in Gmail: I don\u0026rsquo;t want to be recruited, thank you very much on Github.\n","permalink":"https://stefano.chiodino.uk/posts/2021-01-19-change-all-github-email-addresses/","summary":"\u003cp\u003eI have found out that recruiters have hunted me down using the email address I have inadvertently used to commit in Github. Unfortunately it\u0026rsquo;s not straightforward to replace this, but here is what I\u0026rsquo;ve done:\u003c/p\u003e\n\u003cp\u003eFrom an \u003cstrong\u003eempty folder\u003c/strong\u003e clone all your public repos using github API. Replace \u003ccode\u003eYOUR-GITHUB-USERNAME\u003c/code\u003e.\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003efor SSH_URL in $(curl -s https://api.github.com/users/YOUR-GITHUB-USERNAME/repos | grep ssh_url | cut -d\u0026#39;\u0026#34;\u0026#39; -f 4)\ndo\n    git clone $SSH_URL\ndone\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThis is a good time to \u003cstrong\u003eBACKUP THIS ENTIRE FOLDER\u003c/strong\u003e.\u003c/p\u003e","title":"Change all Github email addresses"},{"content":"One day Chris, head of devops, gave me a tour of our setup. He proudly pointed out to me how they prefer to write arguments using the long version, like --allow instead of -a. This is to make it easier to understand the system, and thus maintaining it. It made so much sense: decrease the cognitive load, increase productivity.\nThen I started working for the NHS, the biggest employer in the UK, and 5th in the world, just after McDonald\u0026rsquo;s. Seems like in such a big company nobody has time to spell things out, and after more than a year I\u0026rsquo;m still struggling to catch up on some acronyms. I often come across acronyms that I never bothered or dared to ask about, and despite having developed a sense for that they represent, I still don\u0026rsquo;t know what they stand for.\nWhen writing code, good sense dictates you should call your variable pageTitle, rather than pt. So why is it ok to abbreviate GPES Data for Pandemic Planning and Research in a nested acronym to GDPPR?\nI took a business writing course recently, and one of the key points was that you have to write for your audience. Look, I get it. I review a lot of merge requests, and the temptation to call them MR is strong, but think about your audience. Are you in a group chat with your Product Owner and the New Starter?\nUse all the acronyms you are confident your colleagues know, when you are writing to them in private. Maximise understanding everywhere else.\n","permalink":"https://stefano.chiodino.uk/posts/2020-07-27-tma-too-many-acronyms/","summary":"\u003cp\u003eOne day Chris, head of devops, gave me a tour of our setup. He proudly pointed out to me how they prefer to write arguments using the long version, like \u003ccode\u003e--allow\u003c/code\u003e instead of \u003ccode\u003e-a\u003c/code\u003e. This is to make it easier to understand the system, and thus maintaining it. It made so much sense: decrease the cognitive load, increase productivity.\u003c/p\u003e\n\u003cp\u003eThen I started working for the NHS, the biggest employer in the UK, and 5th in the world, just after McDonald\u0026rsquo;s. Seems like in such a big company nobody has time to spell things out, and after more than a year I\u0026rsquo;m still struggling to catch up on some acronyms. I often come across acronyms that I never bothered or dared to ask about, and despite having developed a sense for that they represent, I still don\u0026rsquo;t know what they stand for.\u003c/p\u003e","title":"Acronyms"},{"content":"It\u0026rsquo;s important to smile when talking on the phone, it sounds different.\nMirror is the technique of repeating the last three words, or the last critical one. It makes the other party feel in tune with yourself and push them to continue talking.\nPause 4 seconds, especially after a mirror, to let it sink in and force a reaction. This may lead to the other party disclose more information.\nLabelling is the technique of describing how the other party feels. It helps clarify the matters, adds a chance for a pause, and shows that we are listening.\nCheap negotiators want to hear yes. Good ones want to hear no, because when a party says no they feel they are in control.\nPut yourself in the other party\u0026rsquo;s place and understand their situation. You\u0026rsquo;ll know what to offer, and what you can ask.\nDeadlines cut two ways. The pressure to make a deal is on any party ware of a deadline. If you have a deadline let the other party know.\nWe are irrationality more concerned with losses than gains. Mention what the other party stands to lose.\n\u0026ldquo;Fair\u0026rdquo; is one of the strongest words. Use it to propose you are meeting the other party in the middle, or that they aren\u0026rsquo;t.\nFrame the negotiation so that what you ask actually seems convenient. E.g. for a salary negotiation ask for a range where you wish to receive the lower bound.\nAlways try to get non monetary incentives. This also shows that you have reached the limit of how much money you are willing to bargain. Use towards the end.\nRound numbers seem artificial and subject to bargain. We perceive precise numbers as elaborated and more sticky.\nUse open ended calibrated questions like \u0026ldquo;how am I supposed to do that?\u0026rdquo;. They start with how or what, deliver them with calm, and follow by a pause. Open ended means they need more than a yes or no answer. Calibrated means you need to adjust them to a particular scenario. These questions provoke a shift in the position of the other party, or at least more information. Instead of saying \u0026ldquo;don\u0026rsquo;t go!\u0026rdquo; say \u0026ldquo;what do you hope to achieve by going?\u0026rdquo;. \u0026ldquo;Why\u0026rdquo; almost always comes across as an accusation.\nIt\u0026rsquo;s important to keep emotions in check at all times. Make sure to pause. Understand that negotiation is about emotions as much as rationality. Keep the goal in sight.\nListening is being in control.\nA negotiator role is to establish what to do, how to do it, and make sure it\u0026rsquo;s done. For example lead from a verbal agreement to a contract, and from there to a payment.\nSummarise the other party situation until you hear \u0026ldquo;that\u0026rsquo;s right\u0026rdquo;. If they say \u0026ldquo;you are right\u0026rdquo; then it means they feel you forced the plan on them. \u0026ldquo;I\u0026rsquo;ll try\u0026rdquo; indicates not enough buy-in. If you happen to hear these dive back in with calibrated questions until resolved.\nBe aware of decision killers as much as decision makers. Other stakeholders are sometimes not obvious, probe to get to know them.\nSelf esteem, pride, images, etc are often as important as money. Remember it\u0026rsquo;s not a rational process.\nUse the other party\u0026rsquo;s name but not too much. Also use your own name if possible. It all makes it more relatable.\nSay \u0026ldquo;no\u0026rdquo; without using the word, with phrases like \u0026ldquo;how am I supposed to do that?\u0026rdquo;, \u0026ldquo;your offer is very generous, I\u0026rsquo;m sorry that just doesn\u0026rsquo;t work for me\u0026rdquo;, \u0026ldquo;I\u0026rsquo;m sorry but I\u0026rsquo;m afraid I can\u0026rsquo;t do that\u0026rdquo;, and \u0026ldquo;I\u0026rsquo;m sorry, no\u0026rdquo;. \u0026ldquo;No\u0026rdquo; should have a gentle downward inflection to not sound aggressive.\nGoing in a negotiation set limits and work within those. Never get angry, even tho sounding a bit angry can be beneficial at times, but often comes across fake. Never consider the other party the problem: the negotiation is the problem.\nFollow the Ackerman model:\nSet your target price (your goal).\nSet your first offer at 65 percent of your target price.\nCalculate three raises of decreasing increments (to 85, 95, and 100 percent).\nUse lots of empathy and different ways of saying “No” to get the other side to counter before you increase your offer.\nWhen calculating the final amount, use precise, non round numbers, it gives the number credibility and weight.\nOn your final number, throw in a non monetary item (that they probably don’t want) to show you’re at your limit.\nBlack swans are events you thought were impossible, and never consider.\n","permalink":"https://stefano.chiodino.uk/posts/2020-10-23-notes-on-book-never-split-the-difference/","summary":"\u003cp\u003eIt\u0026rsquo;s important to \u003cstrong\u003esmile\u003c/strong\u003e when talking on the phone, it sounds different.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eMirror\u003c/strong\u003e is the technique of repeating the last three words, or the last critical one. It makes the other party feel in tune with yourself and push them to continue talking.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003ePause\u003c/strong\u003e 4 seconds, especially after a mirror, to let it sink in and force a reaction. This may lead to the other party disclose more information.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eLabelling\u003c/strong\u003e is the technique of describing how the other party feels. It helps clarify the matters, adds a chance for a pause, and shows that we are listening.\u003c/p\u003e","title":"Notes on book Never Split the Difference"},{"content":" Clarity above all. Don\u0026rsquo;t waste the reader\u0026rsquo;s time. \u0026ldquo;If I had more time, I would have written a shorter letter\u0026rdquo; - Blaise Pascal. The look makes a difference. Make your text easier on the eyes. Use bullet points, white space, shorter sentences, margins, boldface, etc . Be smart: don\u0026rsquo;t try to sound smart. Avoid jargon. Be the authority: don\u0026rsquo;t use \u0026ldquo;I\u0026rsquo;m thinking\u0026rdquo;, \u0026ldquo;in my opinion\u0026rdquo;, etc. Scaffold well to write well. Structure you text in 3 phases: say what you want to say, say it, repeat it. One idea per paragraph Every paragraph should start with a strong sentence on the paragraph\u0026rsquo;s topic. Start with your purpose, not the motivation or justification for it. The text may become too mechanical after revising. Keep your \u0026ldquo;voice\u0026rdquo; in your document by reading it out loud. If you find duplicate sentences, cut out the negative sounding ones first. Grammar matters. Grammar - I vs me: use I if it\u0026rsquo;s a subject Attribute modifiers like adjectives need to one of the nouns. Make them adjacent. pronouns are words that take the place of nouns, like I, he, them. They refer to the closest antecedent noun. Think of the writing from your reader perspective Cut adjectives and adverbs; qualifiers and amplifiers; “in fact”, “possibly”, “generally”, etc Cut out generalities like \u0026ldquo;everyone knows\u0026rdquo;, they often include the words: all everybody, everywhere, etc. You may need to rewrite sentences to make them more specific if they include words like: some, somebody, etc. use an active voice: \u0026ldquo;Bob did X\u0026rdquo;, not \u0026ldquo;X was done by Bob\u0026rdquo;. Passive voice is longer, less clear, and less emphatic. But it\u0026rsquo;s acceptable in scientific papers because it sounds more impartial. Limit verbs \u0026ldquo;to be\u0026rdquo; and \u0026ldquo;to have\u0026rdquo;. Including forms is, am, are, were, was, will be, have, has, had, have been and more. Ref: Business Writing course on Coursera\n","permalink":"https://stefano.chiodino.uk/posts/2020-10-22-notes-on-coursera-business-writing-course/","summary":"\u003cul\u003e\n\u003cli\u003eClarity above all.\u003c/li\u003e\n\u003cli\u003eDon\u0026rsquo;t waste the reader\u0026rsquo;s time. \u0026ldquo;If I had more time, I would have written a shorter letter\u0026rdquo; - Blaise Pascal.\u003c/li\u003e\n\u003cli\u003eThe look makes a difference. Make your text easier on the eyes. Use bullet points, white space, shorter sentences, margins, boldface, etc .\u003c/li\u003e\n\u003cli\u003eBe smart: don\u0026rsquo;t try to sound smart. Avoid jargon.\u003c/li\u003e\n\u003cli\u003eBe the authority: don\u0026rsquo;t use \u0026ldquo;I\u0026rsquo;m thinking\u0026rdquo;, \u0026ldquo;in my opinion\u0026rdquo;, etc.\u003c/li\u003e\n\u003cli\u003eScaffold well to write well. Structure you text in 3 phases: say what you want to say, say it, repeat it.\u003c/li\u003e\n\u003cli\u003eOne idea per paragraph\u003c/li\u003e\n\u003cli\u003eEvery paragraph should start with a strong sentence on the paragraph\u0026rsquo;s topic.\u003c/li\u003e\n\u003cli\u003eStart with your purpose, not the motivation or justification for it.\u003c/li\u003e\n\u003cli\u003eThe text may become too mechanical after revising. Keep your \u0026ldquo;voice\u0026rdquo; in your document by reading it out loud.\u003c/li\u003e\n\u003cli\u003eIf you find duplicate sentences, cut out the negative sounding ones first.\u003c/li\u003e\n\u003cli\u003eGrammar matters.\u003c/li\u003e\n\u003cli\u003eGrammar - I vs me: use I if it\u0026rsquo;s a subject\u003c/li\u003e\n\u003cli\u003eAttribute modifiers like adjectives need to one of the nouns. Make them adjacent.\u003c/li\u003e\n\u003cli\u003epronouns are words that take the place of nouns, like I, he, them. They refer to the closest antecedent noun.\u003c/li\u003e\n\u003cli\u003eThink of the writing from your reader perspective\u003c/li\u003e\n\u003cli\u003eCut adjectives and adverbs; qualifiers and amplifiers; “in fact”, “possibly”, “generally”, etc\u003c/li\u003e\n\u003cli\u003eCut out generalities like \u0026ldquo;everyone knows\u0026rdquo;, they often include the words: all everybody, everywhere, etc. You may need to rewrite sentences to make them more specific if they include words like: some, somebody, etc.\u003c/li\u003e\n\u003cli\u003euse an active voice: \u0026ldquo;Bob did X\u0026rdquo;, not \u0026ldquo;X was done by Bob\u0026rdquo;. Passive voice is longer, less clear, and less emphatic. But it\u0026rsquo;s acceptable in scientific papers because it sounds more impartial.\u003c/li\u003e\n\u003cli\u003eLimit verbs \u0026ldquo;to be\u0026rdquo; and \u0026ldquo;to have\u0026rdquo;. Including forms is, am, are, were, was, will be, have, has, had, have been and more.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eRef: \u003ca href=\"https://www.coursera.org/learn/writing-for-business/\"\u003eBusiness Writing course on Coursera\u003c/a\u003e\u003c/p\u003e","title":"Notes on Coursera Business Writing Course"},{"content":"Most of the sun\u0026rsquo;s energy is in the green wavelength, however that\u0026rsquo;s exactly what the plants bounce back, as chlorophyll of type a and b absorbs light in the red and blue spectrum.\nIt was thought that collecting too much of the available wavelength could harm the plant (think of how hot black surfaces can become). However it has recently been discovered that plants are trying to optimise for a steady flux of energy, because flickers in the energy collected can cause energy failures or tissue damage.\nIn the long run evolution selects for performances, but also stability.\nSource: Reddit /r/til\nRef: https://www.quantamagazine.org/why-are-plants-green-to-reduce-the-noise-in-photosynthesis-20200730/\n","permalink":"https://stefano.chiodino.uk/posts/2020-08-08-why-are-plants-green/","summary":"\u003cp\u003eMost of the sun\u0026rsquo;s energy is in the green wavelength, however that\u0026rsquo;s exactly what the plants bounce back, as chlorophyll of type a and b absorbs light in the red and blue spectrum.\u003c/p\u003e\n\u003cp\u003eIt was thought that collecting too much of the available wavelength could harm the plant (think of how hot black surfaces can become). However it has recently been discovered that plants are trying to optimise for a steady flux of energy, because flickers in the energy collected can cause energy failures or tissue damage.\u003c/p\u003e","title":"Why are plants green?"},{"content":"Kim Il-sung died in \u0026lsquo;94, but it\u0026rsquo;s been nominated eternal President of the Republic, making the country\u0026rsquo;s system a necrocracy.\nSource: Reddit /r/til\nRef.: https://en.wiktionary.org/wiki/necrocracy\n","permalink":"https://stefano.chiodino.uk/posts/2020-08-04-north-korea-is-a-necrocracy/","summary":"\u003cp\u003eKim Il-sung died in \u0026lsquo;94, but it\u0026rsquo;s been nominated eternal President of the Republic, making the country\u0026rsquo;s system a necrocracy.\u003c/p\u003e\n\u003cp\u003eSource: Reddit /r/til\u003c/p\u003e\n\u003cp\u003eRef.: \u003ca href=\"https://en.wiktionary.org/wiki/necrocracy\"\u003ehttps://en.wiktionary.org/wiki/necrocracy\u003c/a\u003e\u003c/p\u003e","title":"North Korea is a necrocracy"},{"content":"I recall a friend complaining about \u0026ldquo;PAT test\u0026rdquo;, because PAT already stands for Portable Appliance Test, so adding test at the end was redundant.\nI\u0026rsquo;ve eventually came across the RAS syndrome, which is a self-referential name for this problem.\nOther common cases of RAS syndrome are PIN and VIN numbers, ATM machine, HIV virus, LCD display.\nAcronyms suffering from RAS syndromes are widely accepted as the redundancy adds clarity.\n","permalink":"https://stefano.chiodino.uk/posts/2020-07-30-ras-syndrome/","summary":"\u003cp\u003eI recall a friend complaining about \u0026ldquo;PAT test\u0026rdquo;, because PAT already stands for Portable Appliance Test, so adding test at the end was redundant.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;ve eventually came across the \u003ca href=\"https://en.wikipedia.org/wiki/RAS_syndrome\"\u003eRAS syndrome\u003c/a\u003e, which is a self-referential name for this problem.\u003c/p\u003e\n\u003cp\u003eOther common cases of RAS syndrome are PIN and VIN numbers, ATM machine, HIV virus, LCD display.\u003c/p\u003e\n\u003cp\u003eAcronyms suffering from RAS syndromes are widely accepted as the redundancy adds clarity.\u003c/p\u003e","title":"RAS Syndrome"},{"content":"A skeuomorph is an object that maintained design cues that have become non functional. For example the tiny handle on maple syrup bottle is to retain the distinctive appearance of the much bigger jugs maple syrup was once stored in. Other examples are many icons on modern mobile phones and computers, light bulbs in the shape of candles, etc.\nSource: Googling for the reason why maple syrup bottles have a tiny handle.\n","permalink":"https://stefano.chiodino.uk/posts/2020-06-30-skeuomorph/","summary":"\u003cp\u003eA skeuomorph is an object that maintained design cues that have become non functional. For example the tiny handle on maple syrup bottle is to retain the distinctive appearance of the much bigger jugs maple syrup was once stored in. Other examples are many icons on modern mobile phones and computers, light bulbs in the shape of candles, etc.\u003c/p\u003e\n\u003cp\u003eSource: Googling for the reason why maple syrup bottles have a tiny handle.\u003c/p\u003e","title":"Skeuomorph"},{"content":"Dicots and monocots differs on several more features other than the one that gives them their names: the number of cotyledon (leafs) in their embryo. Monocots have parallel veins in their leafs, which usually means elongate leafs as well, complexly arranged vascular system, fibrous roots, and floral parts usually in multiple of three. Dicots have a network of branching veins, a vascular system arranged in rings, a taproot system (a long main root), and floral parts usually arranged in multiple of four or five.\nSource: Coursera\u0026rsquo;s Understanding Plants - Part II: Fundamentals of Plant Biology Week 2 2.1 Plant organs.\nURL: https://www.coursera.org/learn/plant-biology/lecture/4927r/2-1-plant-organs\n","permalink":"https://stefano.chiodino.uk/posts/2020-06-07-monocote-vs-dicot-plants/","summary":"\u003cp\u003eDicots and monocots differs on several more features other than the one that gives them their names: the number of cotyledon (leafs) in their embryo. Monocots have parallel veins in their leafs, which usually means elongate leafs as well, complexly arranged vascular system, fibrous roots, and floral parts usually in multiple of three. Dicots have a network of branching veins, a vascular system arranged in rings, a taproot system (a long main root), and floral parts usually arranged in multiple of four or five.\u003c/p\u003e","title":"Monocote vs dicot plants"},{"content":"Plasmodesma is a narrow thread of cytoplasm that passes through the cell walls of adjacent plant cells and allows communication between them.\nSource: Coursera\u0026rsquo;s Understanding Plants - Part II: Fundamentals of Plant Biology Week 1 1.7 The vacuole and plasmodesmata\nURL: https://www.coursera.org/learn/plant-biology/lecture/gwRmz/1-7-the-vacuole-and-plasmodesmata\n","permalink":"https://stefano.chiodino.uk/posts/2020-06-05-plasmodesma/","summary":"\u003cp\u003ePlasmodesma is a narrow thread of cytoplasm that passes through the cell walls of adjacent plant cells and allows communication between them.\u003c/p\u003e\n\u003cp\u003eSource: Coursera\u0026rsquo;s Understanding Plants - Part II: Fundamentals of Plant Biology Week 1\n1.7 The vacuole and plasmodesmata\u003c/p\u003e\n\u003cp\u003eURL: \u003ca href=\"https://www.coursera.org/learn/plant-biology/lecture/gwRmz/1-7-the-vacuole-and-plasmodesmata\"\u003ehttps://www.coursera.org/learn/plant-biology/lecture/gwRmz/1-7-the-vacuole-and-plasmodesmata\u003c/a\u003e\u003c/p\u003e","title":"Plasmodesma"},{"content":"Xylem are tubes that allows water and substances to go through a plant. They are made of cells that die through apoptosis (programmed cell death). This process thickens the side walls, remove the top and bottom ones, and progressively kills the cell, leaving a tube of all those cell walls in their place.\nSource: Coursera\u0026rsquo;s Understanding Plants - Part II: Fundamentals of Plant Biology Week 1 1.8 Vascular tissue - xylem\nURL: https://www.coursera.org/learn/plant-biology/lecture/jZRR7/1-8-vascular-tissue-xylem\n","permalink":"https://stefano.chiodino.uk/posts/2020-06-05-xylem/","summary":"\u003cp\u003eXylem are tubes that allows water and substances to go through a plant. They are made of cells that die through apoptosis (programmed cell death). This process thickens the side walls, remove the top and bottom ones, and progressively kills the cell, leaving a tube of all those cell walls in their place.\u003c/p\u003e\n\u003cp\u003eSource: Coursera\u0026rsquo;s Understanding Plants - Part II: Fundamentals of Plant Biology Week 1\n1.8 Vascular tissue - xylem\u003c/p\u003e","title":"Xylem"},{"content":"The Fundamental attribution error is the tendency for people to attribute far too much importance to personality rather than situations.\nSource: Coursera - Yale\u0026rsquo;s Introduction to Psychology https://www.coursera.org/learn/introduction-psychology/lecture/Urm4G/attribution\n","permalink":"https://stefano.chiodino.uk/posts/2020-05-20-fundamental-attribution-error/","summary":"\u003cp\u003eThe Fundamental attribution error is the tendency for people to attribute far too much importance to personality rather than situations.\u003c/p\u003e\n\u003cp\u003eSource: Coursera - Yale\u0026rsquo;s Introduction to Psychology \u003ca href=\"https://www.coursera.org/learn/introduction-psychology/lecture/Urm4G/attribution\"\u003ehttps://www.coursera.org/learn/introduction-psychology/lecture/Urm4G/attribution\u003c/a\u003e\u003c/p\u003e","title":"Fundamental attribution error"},{"content":"In the USA the value of a life has been estimated to be worth 10 million USD. This was initially much smaller, being just what a person would earn for the rest of his life, in average. It was later adjusted to reflect what a human life is worth, other than just work, by calculating how much the market values the danger of more risky job to be worth, but also what is it worth to their dears.\nSource: Planet Money podcast, episode \u0026ldquo;Lives vs the economy\u0026rdquo;.\n","permalink":"https://stefano.chiodino.uk/posts/2020-04-26-a-life-is-valued-10-million-dollars/","summary":"\u003cp\u003eIn the USA the value of a life has been estimated to be worth 10 million USD. This was initially much smaller, being just what a person would earn for the rest of his life, in average. It was later adjusted to reflect what a human life is worth, other than just work, by calculating how much the market values the danger of more risky job to be worth, but also what is it worth to their dears.\u003c/p\u003e","title":"A life is valued 10 million dollars"},{"content":"Conjunction fallacy occurs when it is assumed that specific conditions are more probable than a single general one.\nSource: Rationality Course\nVia: Harvard\nURL: 45 minutes in https://harvard.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a780e65f-e1d0-47a2-97c4-ab3b0140edfb\n","permalink":"https://stefano.chiodino.uk/posts/2020-04-23-conjunction-fallacy/","summary":"\u003cp\u003eConjunction fallacy occurs when it is assumed that specific conditions are more probable than a single general one.\u003c/p\u003e\n\u003cp\u003eSource: Rationality Course\u003c/p\u003e\n\u003cp\u003eVia: Harvard\u003c/p\u003e\n\u003cp\u003eURL: 45 minutes in \u003ca href=\"https://harvard.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a780e65f-e1d0-47a2-97c4-ab3b0140edfb\"\u003ehttps://harvard.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a780e65f-e1d0-47a2-97c4-ab3b0140edfb\u003c/a\u003e\u003c/p\u003e","title":"Conjunction fallacy"},{"content":"To produce an Amazon basic alkaline battery may require 100 times more energy than what the battery can actually produce.\nSource: The Verge\nVia: Apple News\n","permalink":"https://stefano.chiodino.uk/posts/2020-04-22-alkaline-battery/","summary":"\u003cp\u003eTo produce an Amazon basic alkaline battery may require 100 times more energy than what the battery can actually produce.\u003c/p\u003e\n\u003cp\u003eSource: The Verge\u003c/p\u003e\n\u003cp\u003eVia: Apple News\u003c/p\u003e","title":"Alkaline battery"},{"content":"After the Second World War forecasts were that Asia was going to be a trouble area because it was poorer that Africa and without the same amount of resources. Turned out that labour force and education can overcome that.\nSource: Masters in business podcast\n","permalink":"https://stefano.chiodino.uk/posts/2020-04-22-asia-after-world-war-two/","summary":"\u003cp\u003eAfter the Second World War forecasts were that Asia was going to be a trouble area because it was poorer that Africa and without the same amount of resources. Turned out that labour force and education can overcome that.\u003c/p\u003e\n\u003cp\u003eSource: Masters in business podcast\u003c/p\u003e","title":"Asia after World War Two"},{"content":"If I flip a coin and look at the result in secret, being heads, then the chances that it\u0026rsquo;s heads it\u0026rsquo;s 100% for me, but 50% for everybody else.\nSource: Rationality Course\nVia: Harvard\nURL: 32 minutes in https://harvard.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a780e65f-e1d0-47a2-97c4-ab3b0140edfb\n","permalink":"https://stefano.chiodino.uk/posts/2020-04-22-probability-can-be-subjective/","summary":"\u003cp\u003eIf I flip a coin and look at the result in secret, being heads, then the chances that it\u0026rsquo;s heads it\u0026rsquo;s 100% for me, but 50% for everybody else.\u003c/p\u003e\n\u003cp\u003eSource: Rationality Course\u003c/p\u003e\n\u003cp\u003eVia: Harvard\u003c/p\u003e\n\u003cp\u003eURL: 32 minutes in \u003ca href=\"https://harvard.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a780e65f-e1d0-47a2-97c4-ab3b0140edfb\"\u003ehttps://harvard.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a780e65f-e1d0-47a2-97c4-ab3b0140edfb\u003c/a\u003e\u003c/p\u003e","title":"Probability can be subjective"},{"content":"Written by Andrew Hunt and David Thomas. Originally published October 1999. 25th printing, 10th Feb version. 320 Pages. ISBN: 978-0-2016-1622-4. Publisher: Addison-Wesley.\nThe book invites the reader to progress in whatever order, as reading from front to back is not necessary.\nThroughout the book you are prompted to visit other parts to expand on an topic. At the end of each section you are sometimes prompted with challenges that make you reflect on what you just read.\nProgramming is a craft. At its simplest, it comes down to getting a computer to do what you want it to do (or what your user wants it to do). What Makes a Pragmatic Programmer? Early adopter/fast adapter. Inquisitive. Critical thinker. Realistic. Jack of all trades. Care About Your Craft “Kaizen” is a Japanese term that captures the conceptof continuously making many small improvements CHAPTER 1 - A PRAGMATIC PHILOSOPHY The Cat Ate My Source Code TIP 3: Provide Options, Don’t Make Lame Excuses Software Entropy While software development is immune from almost all physical laws,entropy hits us hard TIP 4: Don’t Live with Broken Windows […] Don’t let entropy win. Even with a fire to put out, don’t be the first to break a window! Stone Soup and Boiled Frogs TIP 5: Be a Catalyst for Change TIP 6: Remember the Big Picture Challenge: Sometimes deception is needed to catalyse change, so don’t use it to do harm Good-Enough Software If trade-offs are possible ask for them: how good is this software meant to be? TIP 7: Make Quality a Requirements Issue Often great software today is better than perfect software tomorrow. (MVP, agile) Challenge: Think about the software that you use. Is it perfect? Would you rather wait for the \u0026ldquo;perfect\u0026rdquo; version? Your Knowledge Portfolio An investment in knowledge always pays the best interest. (Benjamin Franklin) Knowledge in software is an expiring asset Knowledge is an asset and can be treated like an investment: Learn regularly Diversify your knowledge Learn some new up-and-coming tech Give up on old tech Goals: Learn one new language every year (seems a lot). Different languages will force you to think differently. E.g.: Rust forces you not to use nulls and think of return types as Option and Result. Read a technical book each quarter Take classes Participate in local groups Experiment with different environments Stay current online and offline It doesn’t matter what use you are going to make of your new knowledge, the process of learning will expand your thinking. TIP 9: Critically Analyze What You Read and Hear. How to ask for knowledge: be specific, frame the question carefully and politely, once your question is written down look one more time for the answer, be patient, give back. Communicate! \u0026ldquo;A good idea is an orphan without effective communication.\u0026rdquo; \u0026ldquo;Plan what you want to say. Write an outline\u0026rdquo; Ask yourself about your audience the WISDOM acrostic (what, interest, sophisticated, detail, own, motivate) Chose a style (short, long, factual, funny, etc) Make it look good if you want people to listen to you listen to them TIP 10: It’s Both What You Say and the Way You Say It Emails are forever Chapter 2 - A Pragmatic Approach The Evils of Duplication\nTIP 11: DRY—Don’t Repeat Yourself \u0026ldquo;It isn’t a question of whether you’ll remember: it’s a question of when you’ll forget.\u0026rdquo; Duplication can be due to developers feeling there is no other way, without realising it, for laziness or because different developers produced by coincidence the same functionality. Imposed duplication can be worked around by using a pre-processor. Inadverted duplication can be due to unnormalised data. Comments are knowledge too and take part in duplication. Performances may tempt developers to duplicate, however this is just a cheap solution (e.g. some calculated data can be stored due to the expense of being produced, however care needs to be taken to update it if any of the inputs changes) TIP 12: Make It Easy to Reuse Ease or reusing functionality is a step towards de-duplication. Orthogonality\nOften overlooked but core concept of other methods and techniques. Refers to the decoupling of things so that moving on one line your position projected on the other doesn’t change. TIP 13: Eliminate Effects Between Unrelated Things Productivity gain \u0026ldquo;Changes are localized, so development time and testing time are reduced” Promote reuse. It’s easier to combine orthogonal components. Reduce Risk Compartamentalise problems. Robustness Probably better tested as tests are easier to write. 3rd party changes have less effect on your system. Layering is a powerful way to achieve orthogonality. Test for orthogonality are easy: ask yourself how many parts of the software would be affected if you had to change any other part. It should be one. Unit testing and documentation is an easy winner when code is orthogonal. OOP can provide with tools for more orthogonality, but also more chances for less of it. Reversibility\n\u0026ldquo;Requirements, users, and hardware change faster than we can get the software developed.\u0026rdquo; TIP 14: There Are No Final Decisions \u0026ldquo;keep decisions soft and pliable\u0026rdquo; Tracer Bullets\nTracer bullets are used to correct the aim of fire arms in the dark TIP 15: Use Tracer Bullets to Find the Target Like prototyping but keeping the code. Build skeleton of a system Prototypes and Post-it Notes\nPrototypes don’t need to be on code. Could be on post-its or whiteboard. TIP 16: Prototype to Learn You can prototype anything new, risky, experimental, etc. Prefer high level language, stick with an at least similar language if testing for performances. Architecture wise prototyping is valuable to check for coupling, responsibilities and collaborations of components, interface definition, possible duplications, data access. Make very clear to everybody that it’s disposable code. Domain Languages\nTIP 17: Program Close to the Problem Domain. Come up with high level languages to help define a problem. Different part of a problem may require their own language. Define a syntax first with a notation such as BNF. Tools such as bison and yacc can convert well defined languages to programming languages. Estimating\nPractice estimating to be able to get a feel for order go magnitudes. TIP 18: Estimate to Avoid Surprises. The first question when asked for an estimation should be \u0026ldquo;how accurate?”. The smaller the granularity of the estimations the greater the assumption of degree of accuracy. Duration Quote estimate in 1–15 days days 3–8 weeks weeks 8–30 weeks months 30+ weeks think hard before giving an estimate The easiest way to improve on you estimate is to draw from other peoples experience. Build a model for the estimate e.g. variants, building blocks. \u0026ldquo;Your experience will tell you when to stop refining.” As the estimate becomes more complex you’ll want to hedge your answers. Take notes of you estimate and the actual values. Investigate when there is a substantial difference. TIP 19: Iterate the Schedule with the Code \u0026ldquo;What to Say When Asked for an Estimate? You say \u0026lsquo;I’ll get back to you.’” Chapter 3 - The Basic Tools Start with basic tools then adopt new ones. Go back to to the basics from time to time to sharpen your skills. The Power of Plain Text TIP 20: Keep Knowledge in Plain Text Cons: slower to computer, takes more space. Pros: easier to remember the meaning of data, flexible, easier to test (e.g.: change data without recompiling). Shell Games GUI are best for simple operation, shell are more powerful. TIP 21: Use the Power of Command Shells. Power Editing TIP 22: Use a Single Editor Well. Make sure that your editor of choice is available on multiple platforms/OS/shells. Source Code Control Source Code Control Systems allows for decentralisation, collaboration, backup, statistics, undoing changes, compartmentalisation, TIP 23: Always Use Source Code Control Use SCCS for everything, not just code. [This may be a bit anachronistic now that a similar effect can be achieved with Google Docs and the like] SCCS allows for automated and repeatable builds. Debugging \u0026ldquo;Embrace the fact that debugging is just problem solving, and attack itas such.” TIP 24: Fix the Problem, Not the Blame. TIP 25: Don’t Panic. Resist the urge to fix just the symptoms you see. […] Always try to discover the root cause of a problem, not just this particular appearance of it. Bug reporting isn’t an exact science. Accuracy in bug reports is further diminished when they come through a third party Isolate the steps to reproduce the bug In the process of elimination assume you are at fault before a third party. If a third party is at fault you’ll still probably need to isolate the problem as much as possible for a bug report. TIP 26: “select” Isn’t Broken TIP 27: Don’t Assume It—Prove It If it took a long time to fix try to find ways to make it easier for the next time. If the bug came from one person’s misunderstanding see if anyone else had that misunderstanding. Text Manipulation TIP 28: Learn a Text Manipulation Language Code Generators TIP 29: Write Code That Writes Code Passive code generators produce source code that becomes part of the project. They don’t always have to be totally accurate. [e.g.: templating] Active code generators helps to comply with the DRY principle and are meant to be used continuously to feed changes from the input files to the output ones [e.g.: asp.net transforms] Chapter 4 - Pragmatic Paranoia TIP 30: You Can’t Write Perfect Software Be defensive of other peoples code, and of your own. Design by Contract \u0026ldquo;Dealing with computer systems is hard. Dealing with people is even harder.” \u0026ldquo;Bertrand Meyer developed the concept of Design by Contractfor the language Eiffel.” In DBC there are 3 expectations that needs to be met: preconditions, postconditions and class invariants. TIP 31: Design with Contracts “Be strict in what you will accept beforeyou begin, and promise as little as possible in return” Dead Programs Tell No Lies TIP 32: Crash Early \u0026ldquo;many times, crashing your program is the bestthing you can do” Assertive Programming TIP 33: If It Can’t Happen, Use Assertions to Ensure That It Won’t Most “assert” should be left in the code even in production. Asserts should have no side effects. When to Use Exceptions \u0026ldquo;One of the problems with exceptions is knowing when to use them. Webelieve that exceptions should rarely be used as part of a program’snormal flow; exceptions should be reserved for unexpected events” TIP 34: Use Exceptions for Exceptional Problems. How to Balance Resources TIP 35: Finish What You Start Don’t couple code with shared resources \u0026ldquo;Deallocate resources in the opposite order to that in which you allocate them.” If a series of resources are allocated in more than one place try to allocate them in the same order to avoid deadlocks. Is always a good idea to invest in writing code to check the resource balance, like wrappers that tracks resources. Chapter 5 - Bend, or Break Decoupling and the Law of Demeter Write ‘shy’ code: don’t reveal yourself to others and don’t interact with too many people. Organise code in cells and limit their interaction like organisations that value privacy TIP 36: Minimize Coupling Between Modules \u0026ldquo;The Law of Demeter for functions states that any method of anobject should call only methods belonging to: itself, any parameters that were passed in to the method, any objects it created and any directly held component objects” Metaprogramming Get the details out of the code to make it soft and configurable. Metadata is data about data. TIP 37: Configure, Don’t Integrate TIP 38: Put Abstractions in Code, Details in Metadata Writing configuration out of the code allows for decoupling, abstraction, configuring application more easily and changing the configuration without compilation step Decide if it’s worth implementing a mechanism to reload the configuration on the fly. Consider how long-running the application will be and how quick and easy restarting it would be. Temporal Coupling Time is often ignored in software architecture. Time aspects to consider are concurrency and ordering. Workflow needs to be modelled with UML activity diagram or similar. TIP 39: Analyze Workflow to Improve Concurrency. The hungry consumer model consists of workers getting tasks from a queue. TIP 40: Design Using Services. TIP 41: Always Design for Concurrency. Adding concurrency to a system that has not been designed as such is very difficult. It’s Just a View Use events to decouple. Dispatching events from a single routine cause more coupling. Use the publish/subscribe pattern. TIP 42: Separate Views from Models. Use Model-View-Controller (MVC) to separate the model from both the GUI and the controls. MVC typically exists in a GUI context, but the same concept on segregation of concerns can be applied to any kind of programming: Model is the data, the view is a way of interpreting the data, and the controller feeds the data to the view Blackboards A blackboard system is a data storage that allows actors to asynchronously work on shared data. Blackboard systems became popular in artificial intelligence, where problems are large and complex. TIP 43: Use Blackboards to Coordinate Workflow. Chapter 6 - While You Are Coding Programming by Coincidence \u0026ldquo;We should avoid pro-gramming by coincidence—relying on luck and accidental successes—in favor of programming deliberately.” There are several reasons why not to program by coincidence: May not be really working but only looking like it is. May be an accidental boundary condition and not work all the times. Undocumented behaviour subject to change. Possibly slower. More error prone. \u0026ldquo;Assumptions that aren’t based on well-established facts are the bane of all projects.” TIP 44: Don’t Program by Coincidence To program deliberately you should: Be aware of what you are doing. Be aware of what you are going to do. Proceed from a plan. Don’t rely on accidents or assumptions. Assume the worse. Document your assumptions (e.g.: design by contract). Test your assumptions. Focus on the important parts. Don’t let existing code/functionality dictate what you are doing. Refactor if necessary. Algorithm Speed It’s important to estimate speed of algorithms when not linear. The O notation determines the upper bounds of algorithms. Because of this it does incur in some precision loss. The big O notation is also uses to model memory or other resources. You should keep in mind the big O notation and ask yourself what scale are you working on to understand what the impact will be. TIP 45: Estimate the Order of Your Algorithms. If you are unsure on the efficiency of your code then run it a few time with different inputs and plot the results. TIP 46: Test Your Estimates. Sometimes is not all about the efficiency: if the inputs are known small it could be better to have easier to write and debug code. Be wary of premature optimisations. Refactoring Building software is organic, much more like gardening than building constructions, but business people are much more comfortable with the latter metaphor. \u0026ldquo;Rewriting, reworking, and re-architecting code is collectively known as refactoring.” Don’t hesitate to refactor. Good reasons for refactoring: duplication, non-orthodoganl design, outdated knowledge, performance. Time pressure is often used as an excuse for not refactoring. TIP 47: Refactor Early, Refactor Often. Martin Fowler tips on refactoring: don’t add functionality while refactoring; Make sure you are covered by tests and run them often; Take short, deliberate steps. Code That’s Easy to Test \u0026ldquo;The term “Software IC” (Integrated Circuit) seems to have been invented in 1986 by Cox and Novobilski in their Objective-C book Object-Oriented Programming” and it refers to the practice of writing modular software that can be tested just like individual chips that are then composed together on a board. We can test against the contract. TIP 48: Design to Test Unit tests provide examples on how to use your code. Run the tests often. Use test harnesses (JUnit, xUnit, etc). Debugging may be necessary in production environment, in this case log files, hot keys sequences or web servers to reveal status messages may be the best option. Format log files correctly to help with parson and for readability. \u0026ldquo;Testing is more cultural than technical\u0026rdquo; TIP 49: Test Your Software, or Your Users Will Evil Wizards TIP 50: Don’t Use Wizard Code You Don’t Understand Developers routinely use things that don’t understand, but wizard’s code (boilerplate) is not abstracted away like a library or a processor mechanism, it’s interwoven with the developer code. Chapter 7 - Before the Project There is a fine line between specifying too much (analysis paralysis) and not enough (not being ready). The Requirements Pit \u0026ldquo;Requirements rarely lie on the surface.Normally, they’re buried deep beneath layers of assumptions, miscon-ceptions, and politics.\u0026rdquo; TIP 51: Don’t Gather Requirements—Dig for Them “A requirement is a statement of somethingthat needs to be accomplished” Document policies should be separated from requirements. E.g. only employee’s supervisors may see employee’s records should be defined as the need for access control in the requirements and specify who can access what(the policies/metadata/configuration) in another document. \u0026ldquo;It’s important to discover the underlying reason why users do a par-ticular thing, rather than just the way they currently do it. At the endof the day, your development has to solve their business problem, notjust meet their stated requirements. Documenting the reasons behind requirements will give your team invaluable information when makingdaily implementation decisions.” A simple technique to get the requirements right is to do the work of your future users. TIP 52: Work with a User to Think Like a User Don’t over-specify. Requirements are needs. TIP 53: Abstractions Live Longer than Details TIP 54: Use a Project Glossary Make the glossary easily available (e.g., web resource). Solving Impossible Puzzles TIP 55: Don’t Think Outside the Box—Find the Box Whenever faced with a puzzle that seems impossible ask yourself: \u0026ldquo;Is there an easier way? \u0026ldquo;Are you trying to solve the right problem, or have you been distracted by a peripheral technicality?\u0026rdquo; \u0026ldquo;Why is this thing a problem?\u0026rdquo; \u0026ldquo;What is it that’s making it so hard to solve?Does it have to be done this way? \u0026ldquo;Does it have to be done at all?\u0026rdquo; Not Until You’re Ready TIP 56: Listen to Nagging Doubts—Start When You’re Ready Listen to your instincts If insure if waiting for the right moment or procrastinating then start a prototype, then you’ll know to start if you fee like you are wasting your time. If prototyping is creating new questions and you encounter snags on the way then you know you weren’t ready. The Specification Trap \u0026ldquo;Program specification is the process of taking a requirement and reducing it down to the point where a programmer’s skill can take over.\u0026rdquo; The specification is a record for future developers and an agreements with the user, an implicit contact. Many designers find it difficult to stop specifying. Is naive to assume that the perfect specification can be achieved, and even if the client signs it off you can’t guarantee that it’s is what they actually need and they won’t want to change it. TIP 57: Some Things Are Better Done than Described Having a lose specification allows developers to work their way around certain problems. \u0026ldquo;spec- ification and implementation are simply different aspects of the same process—an attempt to capture and codify a requirement.\u0026rdquo; Over-specifying incurs in diminishing or even negative returns. Circles and Arrows TIP 58: Don’t Be a Slave to Formal Methods \u0026ldquo;Never underestimate the cost of adopting new tools and methods.\u0026rdquo; TIP 59: Expensive Tools Do Not Produce Better Designs Chapter 8 - Pragmatic Projects Pragmatic Teams \u0026ldquo;Teams as a whole should not tolerate broken windows” (see 1.2). Code quality shouldn’t be delegated to one or some members of the team, it should be everybody’s responsibility. The boiling frog problem is even more common in teams. The dilution of responsibilities makes it easier for the scope to increase and the time scales to decrease. Maybe appoint a person to be in charge of this. Communication is important for individuals as much as for teams, which should comunicate as one. It help to generate a branding for teams, to give them identity. A team member could be appointed as librarian to help with the duplication of documentation. It’s a mistake to organise teams based on jobs TIP 60: Organize Around Functionality, Not Job Functions \u0026ldquo;The project needs at least two “heads”—one technical, the other administrative.\u0026rdquo; \u0026ldquo;A great way to ensure both consistency and accuracy is to automate everything the team does.\u0026rdquo; Ubiquitous Automation \u0026ldquo;Manual procedures leave consistency up to chance; repeatabilityisn’t guaranteed, especially if aspects of the procedure are open to interpretation by different people.\u0026rdquo; TIP 61: Don’t Use Manual Procedures Compiling the project should be reliable and repeatable. Automation doesn’t only apply to code, but also administrative tasks and documentation. Ruthless Testing \u0026ldquo;Most developers hate testing.\u0026rdquo; TIP 62: Test Early. Test Often. Test Automatically. TIP 63 Coding Ain’t Done ’Til All the Tests Run Unit testing ensures the functionality of a self-contained unit of code. Integration testings verifies the units of code works well together. Validation and verification tests make sure you are building what the client wants Resource exhaustion, errors and recovery needs to be tested too. There are several resources that you can test the lack of: screen resolution, network bandwidth, disk bandwidth, system clock precision, etc. Performance testing include stress testing and load testing. Specialised hardware or software may be necessary. Usability testing are run by real users in real environments. Code quality can be partially tested by measuring cyclomatic complexity, inheritance fan-in and fan-out, response set (number of functions directly invokedby methods of the class) and class coupling ratios. Some of these can only be used by comparison to other pieces of code and so standard deviation is often used. Regression testing compares the outcome of the current test to previous ones or known values. E.g.: making sure bugs don’t resurface. Test data may be real-world one and be collected by competitors systems, or synthetic one that is generated to obtain a big quantity of it or test boundary conditions. GUI tests can be complicated to maintain if the interface is being worked on. In this situation having decoupled code help in reducing the scope of the GUI tests. TIP 64: Use Saboteurs to Test Your Testing Code coverage can help understand if enough have been tested. However, testing 100% of the code lines doesn’t mean perfect testing. TIP 65: Test State Coverage, Not Code Coverage Code should be tested as soon as any production code exists. Test should be run before checking the code in the source repository. When bugs are found a test should be written to avoid it resurfacing. TIP 66: Find Bugs Once It’s All Writing \u0026ldquo;Pragmatic Programmers embrace documentation as an integral part ofthe overall development process.\u0026rdquo; TIP 67: Treat English as Just Another Programming Language. TIP 68: Build Documentation In, Don’t Bolt It On. \u0026ldquo;Code should have comments,but too many comments can be just as bad as too few.\u0026rdquo; \u0026ldquo;Even worse than meaningless names are misleading names.\u0026rdquo; Don’t add to the comments information that can be determined by tools. Like usages, and revision history. Great Expectations A project is successful if it meets the expectations of the clients. TIP 69: Gently Exceed Your Users’ Expectations Surprise the users, in a good way. Pride and Prejudice TIP 70: Sign Your Work Take pride in your work but don’t become prejudiced of it in favour of your coworkers. Quick reference guide Care About Your Craft Why spend your life developing software unless you care about doing it well? Think! About Your Work Turn off the autopilot and take control. Constantly critique and appraise your work. Provide Options, Don’t Make Lame Excuses Instead of excuses, provide options. Don’t say it can’t be done; explain what can be done. Don’t Live with Broken Windows Fix bad designs, wrong decisions, and poor code when you see them. Be a Catalyst for Change You can’t force change on people. Instead, show them how the future might be and help them participate in creating it. Remember the Big Picture Don’t get so engrossed in the details that you forget to check what’s happening around you. Make Quality a Requirements Issue Involve your users in determining the project’s real quality requirements. Invest Regularly in Your Knowledge Portfolio Make learning a habit. Critically Analyze What You Read and Hear Don’t be swayed by vendors, media hype, or dogma. Analyze information in terms of you and your project. It’s Both What You Say and theWay You Say It There’s no point in having great ideas if you don’t communicate them effectively. DRY—Don’t Repeat Yourself Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. Make It Easy to Reuse If it’s easy to reuse, people will. Create an environment that supports reuse. Eliminate Effects Between Unrelated Things Design components that are self-contained, independent, and have a single, well-defined purpose. There Are No Final Decisions No decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change. Use Tracer Bullets to Find the Target Tracer bullets let you home in on your target by trying things and seeing how close they land. Prototype to Learn Prototyping is a learning experience. Its value lies not in the code you produce, but in the lessons you learn. Program Close to the Problem Domain Design and code in your user’s language. Estimate to Avoid Surprises Estimate before you start. You’ll spot potential problems up front. 19. Iterate the Schedule with the Code Use experience you gain as you implement to refine the project time scales. Keep Knowledge in Plain Text Plain text won’t become obsolete. It helps leverage your work and simplifies debugging and testing Use the Power of Command Shells Use the shell when graphical user interfaces don’t cut it. Use a Single Editor Well The editor should be an extension of your hand; make sure your editor is configurable, extensible, and programmable. Always Use Source Code Control Source code control is a time machine for your work—you can go back. Fix the Problem, Not the Blame It doesn’t really matter whether the bug is your fault or someone else’s—it is still your problem, and it still needs to be fixed. Don’t Panic When Debugging Take a deep breath and THINK! about what could be causing the bug. “select” Isn’t Broken It is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application. Don’t Assume It—Prove It Prove your assumptions in the actual environment— with real data and boundary conditions. Learn a Text Manipulation Language You spend a large part of each day working with text. Why not have the computer do some of it for you? Write Code That Writes Code Code generators increase your productivity and help avoid duplication. You Can’t Write Perfect Software Software can’t be perfect. Protect your code and users from the inevitable errors. Design with Contracts Use contracts to document and verify that code does no more and no less than it claims to do. Crash Early A dead program normally does a lot less damage than a crippled one. Use Assertions to Prevent the Impossible Assertions validate your assumptions. Use them to protect your code from an uncertain world. Use Exceptions for Exceptional Problems Exceptions can suffer from all the readability and maintainability problems of classic spaghetti code. Reserve exceptions for exceptional things. Finish What You Start Where possible, the routine or object that allocates a resource should be responsible for deallocating it. Minimize Coupling Between Modules Avoid coupling by writing “shy” code and applying the Law of Demeter. Configure, Don’t Integrate Implement technology choices for an application as configuration options, not through integration or engineering. Put Abstractions in Code, Details in Metadata Program for the general case, and put the specifics outside the compiled code base. Analyze Workflow to Improve Concurrency Exploit concurrency in your user’s workflow. Design Using Services Design in terms of services—independent, concurrent objects behind well-defined, consistent interfaces. Always Design for Concurrency Allow for concurrency, and you’ll design cleaner interfaces with fewer assumptions. Separate Views from Models Gain flexibility at low cost by designing your application in terms of models and views. Use Blackboards to Coordinate Workflow Use blackboards to coordinate disparate facts and agents, while maintaining independence and isolation among participants. Don’t Program by Coincidence Rely only on reliable things. Beware of accidental complexity, and don’t confuse a happy coincidence with a purposeful plan. Estimate the Order of Your Algorithms Get a feel for how long things are likely to take before you write code. Test Your Estimates Mathematical analysis of algorithms doesn’t tell you everything. Try timing your code in its target environment. Refactor Early, Refactor Often Just as you might weed and rearrange a garden rewrite, rework, and re-architect code when it needs it. Fix the root of the problem. Design to Test Start thinking about testing before you write a line of code. Test Your Software, or Your Users Will Test ruthlessly. Don’t make your users find bugs for you. Don’t UseWizard Code You Don’t Understand Wizards can generate reams of code. Make sure you understand all of it before you incorporate it into your project. Don’t Gather Requirements—Dig for Them Requirements rarely lie on the surface. They’re buried deep beneath layers of assumptions, misconceptions, and politics. Work with a User to Think Like a User It’s the best way to gain insight into how the system will really be used. Abstractions Live Longer than Details Invest in the abstraction, not the implementation. Abstractions can survive the barrage of changes from different implementations and new technologies. Use a Project Glossary Create and maintain a single source of all the specific terms and vocabulary for a project. Don’t Think Outside the Box—Find the Box When faced with an impossible problem, identify the real constraints. Ask yourself: “Does it have to be done this way? Does it have to be done at all?” Start When You’re Ready You’ve been building experience all your life. Don’t ignore niggling doubts. Some Things Are Better Done than Described Don’t fall into the specification spiral—at some point you need to start coding. Don’t Be a Slave to Formal Methods Don’t blindly adopt any technique without putting it into the context of your development practices and capabilities. Costly Tools Don’t Produce Better Designs Beware of vendor hype, industry dogma, and the aura of the price tag. Judge tools on their merits. Organize Teams Around Functionality Don’t separate designers from coders, testers from data modelers. Build teams the way you build code. Don’t Use Manual Procedures A shell script or batch file will execute the same instructions, in the same order, time after time. Test Early. Test Often. Test Automatically Tests that run with every build are much more effective than test plans that sit on a shelf. Coding Ain’t Done ’Til All the Tests Run ’Nuff said. Use Saboteurs to Test Your Testing Introduce bugs on purpose in a separate copy of the source to verify that testing will catch them. Test State Coverage, Not Code Coverage Identify and test significant program states. Just testing lines of code isn’t enough. Find Bugs Once Once a human tester finds a bug, it should be the last time a human tester finds that bug. Automatic tests should check for it from then on. English is Just a Programming Language Write documents as you would write code: honor the DRY principle, use metadata, MVC, automatic generation, and so on. Build Documentation In, Don’t Bolt It On Documentation created separately from code is less likely to be correct and up to date. Gently Exceed Your Users’ Expectations Come to understand your users’ expectations, then deliver just that little bit more. Sign Your Work Craftsmen of an earlier age were proud to sign their work. You should be, too. ","permalink":"https://stefano.chiodino.uk/posts/the-pragmatic-programmer-notes/","summary":"\u003cp\u003eWritten by Andrew Hunt and David Thomas. Originally published October 1999. 25th printing, 10th Feb version. 320 Pages. ISBN: 978-0-2016-1622-4. Publisher: Addison-Wesley.\u003c/p\u003e\n\u003cp\u003eThe book invites the reader to progress in whatever order, as reading from front to back is not necessary.\u003c/p\u003e\n\u003cp\u003eThroughout the book you are prompted to visit other parts to expand on an topic. At the end of each section you are sometimes prompted with challenges that make you reflect on what you just read.\u003c/p\u003e","title":"The Pragmatic Programmer - Notes"},{"content":"I was investigating if my controller was handling correctly post requests, when I noticed that it was being called twice.\nA quick look at the dev tools network panel showed there were indeed 2 requests, but the response size was different, and the second response preview was empty. According to Chrome the initiator of the request was some javascript at the bottom of the body.\nBaffled, I called the front end developer over, but we quickly proved that it wasn\u0026rsquo;t due to any javascript. The request was fired with javascript disabled, but now the initiator was index.html:infinity, infinity being the line of code where that happened. On my simpler example it actually shows the very last line of the html.\nWhen everything else fails: old style debugging So\u0026hellip;.we started taking elements off the page, until it stopped.:\nTurns out that style=\u0026quot;background-image: url('');\u0026quot; it\u0026rsquo;s interpreted as \u0026ldquo;the URL of the background image is an empty string, relative to the current URL\u0026rdquo;.\nYou can double check this by opening your tools and going to this example.\nInitiator with javascript Initiator without javascript What happened is that I don\u0026rsquo;t enforce uploading images in the CMS, but if none is selected the URL is just null or empty. Writing style=\u0026quot;background-image: url('@(Model.Image?.Url)');\u0026quot; is incorrect, the rule should not be in the style attribute if the URL is blank.\nThe solution is to write a variable for the content of the style attribute, something like:\nvar imageUrl = Model.Image?.Url; var style = imageUrl == null : string.Empty ? $\u0026#34;background-image: url(\u0026#39;{imageUrl}\u0026#39;);\u0026#34; Reference https://bugzilla.mozilla.org/show_bug.cgi?id=473528\n","permalink":"https://stefano.chiodino.uk/posts/welcome-to-the-internet-you-don-t-know-shit-part-1/","summary":"\u003cp\u003eI was investigating if my controller was handling correctly post requests, when I noticed that it was being called twice.\u003c/p\u003e\n\u003cp\u003eA quick look at the dev tools network panel showed there were indeed 2 requests, but the response size was different, and the second response preview was empty. According to Chrome the initiator of the request was some javascript at the bottom of the body.\u003c/p\u003e\n\u003cp\u003eBaffled, I called the front end developer over, but we quickly proved that it wasn\u0026rsquo;t due to any javascript. The request was fired with javascript disabled, but now the initiator was \u003ccode\u003eindex.html:infinity\u003c/code\u003e, infinity being the line of code where that happened. On my simpler example it actually shows the very last line of the html.\u003c/p\u003e","title":"Welcome to the Internet: You Don't Know Shit, Part 1"},{"content":"A reader of my post on how I use Hugo pointed out in the comments that it\u0026rsquo;s now possible to write online Hugo posts from Forestry.io. I\u0026rsquo;ve been playing with it and I\u0026rsquo;m currently using it to write this very post.\nAs far as writing online goes it\u0026rsquo;s a big improvement over scribe.io. I\u0026rsquo;m just not sure that\u0026rsquo;s enough to make me switch to online writing.\nI love the preview. Unfortunately, it\u0026rsquo;s not good enough as it doesn\u0026rsquo;t work with all Hugo\u0026rsquo;s shortcodes and custom ones either. What I would suggest instead is to have a test website. Forestry.io uses the development branch - you simply hook a new website under a test domain! Just make sure it\u0026rsquo;s not going to be indexed by search engines.\nForestry.io is not responsive or mobile friendly either, so keep that in mind if you wish to blog from your mobile.\nSomething I wish was also implemented is to be able to move files between folders. I organise them by year/month/day and it usually takes me more than a day to write a new blog post.\nThe lach of spel cheking when writin the post is very anoying. Not sure why but both Chrome standard spell checking and Chrome plugin Grammarly don\u0026rsquo;t work when writing the body of the post!\nIn general, it feels like yet another application designed for Jekyll, that works for Hugo as well.\nBy the time I finished writing this post I also noticed that it came out of beta! I\u0026rsquo;m very happy to notice that it still has a free version, with community support and for less than 10 users. I was a bit concerned I was being used as a guinea pig and wasting my time here :)\n","permalink":"https://stefano.chiodino.uk/posts/forestry-io/","summary":"\u003cp\u003eA reader of \u003ca href=\"/posts/hugo-host-and-deployment/\"\u003emy post on how I use Hugo\u003c/a\u003e pointed out in the comments that it\u0026rsquo;s now possible to write online Hugo posts from \u003ca href=\"https://forestry.io\"\u003eForestry.io\u003c/a\u003e. I\u0026rsquo;ve been playing with it and I\u0026rsquo;m currently using it to write this very post.\u003c/p\u003e\n\u003cp\u003eAs far as writing online goes it\u0026rsquo;s a big improvement over scribe.io. I\u0026rsquo;m just not sure that\u0026rsquo;s enough to make me switch to online writing.\u003c/p\u003e\n\u003cp\u003eI love the preview. Unfortunately, it\u0026rsquo;s not good enough as it doesn\u0026rsquo;t work with all Hugo\u0026rsquo;s shortcodes and custom ones either. What I would suggest instead is to have a test website. Forestry.io uses the development branch - you simply hook a new website under a test domain! Just make sure it\u0026rsquo;s not going to be indexed by search engines.\u003c/p\u003e","title":"Forestry.io"},{"content":"I was trying to delete all the passwords stored in google at Google passwords, way too many to do manually!\nCouldn\u0026rsquo;t find a solution online so here is my easy one:\nGo to Google passwords, sign in to your account. Open the development tools in your browser, usually with F12. I’ve used Chrome. Paste the following code in the console. // Gets all the elements to be clicked to delete the passwords. var a = document.getElementsByClassName(“dga”) // Click all the elements. for(i=0; i \u0026lt; a.length; i++){a[i].click();} ","permalink":"https://stefano.chiodino.uk/posts/delete-all-google-stored-passwords/","summary":"\u003cp\u003eI was trying to delete all the passwords stored in google at \u003ca href=\"https://passwords.google.com\"\u003eGoogle passwords\u003c/a\u003e, way too many to do manually!\u003c/p\u003e\n\u003cp\u003eCouldn\u0026rsquo;t find a solution online so here is my easy one:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eGo to \u003ca href=\"https://passwords.google.com\"\u003eGoogle passwords\u003c/a\u003e, sign in to your account.\u003c/li\u003e\n\u003cli\u003eOpen the development tools in your browser, usually with F12. I’ve used Chrome.\u003c/li\u003e\n\u003cli\u003ePaste the following code in the console.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Gets all the elements to be clicked to delete the passwords.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetElementsByClassName\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e“\u003c/span\u003e\u003cspan class=\"nx\"\u003edga\u003c/span\u003e\u003cspan class=\"err\"\u003e”\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Click all the elements.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"nx\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\u003cspan class=\"nx\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003eclick\u003c/span\u003e\u003cspan class=\"p\"\u003e();}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"Delete all google stored passwords"},{"content":"In this post I\u0026rsquo;ll show you how I write my posts, deploy them to the server, process them with Hugo and host them on my DigitalOcean server.\nI wanted this process to be as easy and quick as possible, with as few extra softwares and services as possible. There are a lot of solutions out there like Wercker but I didn\u0026rsquo;t want more things in my way.\nWriting Local I write the posts from IntelliJ IDEA, which is my IDE of choice. Screw Sublime, Atom and all the rest! It\u0026rsquo;s quite heavier but is worth it. You get spell checking, quite good live previews with the Multimarkdown plugin (shame the embedded HTML doesn\u0026rsquo;t render), git integration, and in general a powerful IDE.\nJust to be clear I like Sublime and Atom, but every time I use them there is something wrong. Right now the terminal in Atom doesn\u0026rsquo;t work for me. There is an open issue for this but in the meantime you get a blinking unmovable cursor staring at you.\nI feel that, since Hugo is quite new, the tools haven\u0026rsquo;t caught up with its popularity yet. Intellij is flexible enough to allow you to have shortcuts live templates for your shortcodes. E.g.:\n\u0026lt;template name=\u0026#34;.shortcode\u0026#34; value=\u0026#34;{{\u0026amp;lt; $SHORTCODE$ \u0026amp;gt;}}\u0026#34; description=\u0026#34;A Hugo shortcode\u0026#34; toReformat=\u0026#34;false\u0026#34; toShortenFQNames=\u0026#34;true\u0026#34;\u0026gt; \u0026lt;variable name=\u0026#34;SHORTCODE\u0026#34; expression=\u0026#34;\u0026#34; defaultValue=\u0026#34;\u0026#34; alwaysStopAt=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;context\u0026gt; \u0026lt;option name=\u0026#34;OTHER\u0026#34; value=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;/context\u0026gt; \u0026lt;/template\u0026gt; This allows me to type .s, press enter (if the live template .shortcode is selected), type the name of the shortcode and its parameters and press enter to keep typing without having to type too many symbols or having to move your cursor.\nI keep switching between IntelliJ and the localhost page on my browser, where my hugo server is showing how the end result will be (just launch \u0026ldquo;hugo server\u0026rdquo; from the root folder). If you have the page open you don\u0026rsquo;t even need to refresh it thanks to Hugo\u0026rsquo;s live reload feature (and don\u0026rsquo;t even have to save the file since IntelliJ does it when it loses focus). This is very quick to do, which is particularly nice when you want to make final tweaks to make sure your post will display as you want.\nOnline If you are using Github and want to write from your browser, or you are not at home, you can use prose.io. It\u0026rsquo;s a software developed for Jekyll, but works just fine with Hugo. You get some nice shortcuts to format your text with markdown in case you are not too familiar with it. It also allows you to upload images which are committed to your repo immediately. I don\u0026rsquo;t find it quite as powerful as IntelliJ but it\u0026rsquo;s a nice option.\nYou can have a look at my prose configuration to get you started. It\u0026rsquo;s important to know that prose.io can only generate content with yaml metadata. You will have to configure Hugo to do the same by adding MetaDataFormat: yaml.\nI\u0026rsquo;ve looked at many more free online content editor:\nsofish webhook contentful prismic stackedit dillinger I found them actually extremely good\u0026hellip;just not very compatible with Hugo.\nUnfortunately I couldn\u0026rsquo;t find any online resource to write and preview Hugo content, so editing content locally and preview it with Hugo server is still the best option for me. I reckon you could host a test environment to preview your draft, deploying with a different branch, by adding -buildDrafts to your hugo or hugo server commands.\nHopefully some tool that works perfectly with Hugo will come out soon. Spf13, the creator of Hugo, is thinking about creating one.\nDeployment I can deploy my website in 2 ways:\nPush you branch to the repo on the server. Push the master branch to the main repo. In my case this is on Github but can work with pretty much anything else. These both trigger a small script which I\u0026rsquo;ve adapted from this tutorial on Digitalocean.\n#!/bin/bash # Better be specific rather than using $HOME because it wouldn\u0026#39;t work with all users. GIT_REPO=/home/draga/go-web WORKING_DIRECTORY=$GIT_REPO/public PUBLIC_WWW=/home/draga/public_html BACKUP_WWW=/home/draga/backup_html set -e # Clean working dir. rm -rf $WORKING_DIRECTORY # Backup current website. Use -z if moving across network to save bandwidth. rsync -aq $PUBLIC_WWW/ $BACKUP_WWW # Restore backup if an error occurs from now on. trap \u0026#34;echo \u0026#39;A problem occurred. Reverting to backup.\u0026#39;; rsync -aq --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY\u0026#34; EXIT # fetch repo to make sure it\u0026#39;s up to date if working with remote webhook. cd $GIT_REPO git fetch git checkout origin/master # Build the website. GO HUGO! /usr/bin/hugo -s $GIT_REPO -d $WORKING_DIRECTORY # Mirror the output of Hugo to the directory where the website is hosted. # Use -c to copy only files that have changed to avoid messing with webhost caches. # Use -z if moving across network to save bandwidth. rsync -aqc --delete $WORKING_DIRECTORY/ $PUBLIC_WWW # Ask Google webmaster tools to parse your sitemap. curl https://google.com/webmasters/sitemaps/ping?sitemap=https://stefano.chiodino.uk/sitemap.xml curl https://www.bing.com/ping?sitemap=https%3A%2F%2Fstefano.chiodino.uk/sitemap.xml # Disable trap. trap - EXIT I used the method described in the tutorial above for a while, but it bothered me to push twice since I had to type the password for my ssh key (I\u0026rsquo;ve disabled the password access to the server and can now only be accessed with the key). Also what if I wasn\u0026rsquo;t home or wanted to use prose.io?\nSolution: git(hub) webhooks!\nThanks to github.com/adnanh/webhook, little software written in go, you can have you server listen on a port and execute a script when invoked.\nI currently have it connecting in https, with a secret key, and executing the script when the master branch is pushed.\nNow I can even use Github itself to edit my posts. Pretty neat!\nHosting Now this was the long fun part. I wanted it all so it took a lot of learning, hence the fun.\nI heard of nginx a lot and some research showed that it seems to be the go-to solution. Here are some, more performance related, details of how it performs for me: server load test.\nI\u0026rsquo;ve then enabled the pagespeed module which is very complex and heavy, but definitively worth it! The website now scores 100/100 in Google PageSpeed, both in mobile and desktop!\nI score 99/100 in GTmetrix just because there is a bug in the pagespeed module (1064) and the very header is added twice, and for some reason GTmetrix seems to think that is not there\u0026hellip;? Or maybe is because pagespeed seems to add it on subsequent reloads. Another small penalty is for the G analytics code being cached for just 2 hours, it\u0026rsquo;s out of my control and don\u0026rsquo;t think is worth self hosting it.\nYSlow seems to be mostly concerned of the lack of CDN.\nYou can find all the scripts that I\u0026rsquo;ve used to set up my server on github. They are ordered in the same way they are in the filesystem, so you should get the idea. There is a script to install nginx with the brotli and pagespeed module, directives to use webhook as a service, the entire nginx configuration, etc.\n","permalink":"https://stefano.chiodino.uk/posts/hugo-host-and-deployment/","summary":"\u003cp\u003eIn this post I\u0026rsquo;ll show you how I write my posts, deploy them to the server, process them with \u003ca href=\"https://gohugo.io\"\u003eHugo\u003c/a\u003e and host them on my \u003ca href=\"https://m.do.co/c/875cd23a5c97\"\u003eDigitalOcean\u003c/a\u003e server.\u003c/p\u003e\n\u003cp\u003eI wanted this process to be as easy and quick as possible, with as few extra softwares and services as possible. There are a lot of solutions out there like Wercker but I didn\u0026rsquo;t want more things in my way.\u003c/p\u003e\n\u003ch1 id=\"writing\"\u003eWriting\u003c/h1\u003e\n\u003ch2 id=\"local\"\u003eLocal\u003c/h2\u003e\n\u003cp\u003eI write the posts from IntelliJ IDEA, which is my IDE of choice. Screw Sublime, Atom and all the rest! It\u0026rsquo;s quite heavier but is worth it. You get spell checking, quite good live previews with the Multimarkdown plugin (shame the embedded HTML doesn\u0026rsquo;t render), git integration, and in general a powerful IDE.\u003c/p\u003e","title":"Hugo: write, deploy, host"},{"content":"I\u0026rsquo;ve recently tried Digitalocean hosting and decided to host this blog on it. I\u0026rsquo;m running a $5 / month server, or droplet as they call it, with 1 CPU, 512 MB of ram, 20 GB SSD and 1 TB of bandwidth. You even get $10 credit when you sign up, sweet!\nYou may look down on a $5 machine but I\u0026rsquo;ve found it to be more than enough for my need.\nI\u0026rsquo;m serving \u0026ldquo;static\u0026rdquo; content that has been generated by Hugo\nI recently ran some load testing at work for a newly launched website so I decided to test this $5 server. I\u0026rsquo;ve been using loader.io since its basic usage is free.\nThe test The server responds to a certain number of clients every second for a full minute.\nThe majority of the users must receive the page in \u0026lt; 5 secs. Only the html is loaded.\nPlain HTML 10.000 requests a second! (that is the maximum that loaded.io goes on a free plan)\nEnable strong HTTPS How strong you say?\nAs expected enabling https is taking its toll. The server can\u0026rsquo;t accommodate less than half of the requests, \u0026ldquo;just\u0026rdquo; 4.000.\nFull on PageSpeed on strong HTTPS I\u0026rsquo;ve then enabled Google\u0026rsquo;s PageSpeed module for Nginx and enabled every performance related filter!\nI\u0026rsquo;ve enabled 27 extra filters on top of the 34 enabled by default, leaving just 7 out that were just for compatibility or counterproductive, hell I\u0026rsquo;ve even enabled the filter to make the G analytics script async when it\u0026rsquo;s already implemented that way.\nResult: a quite dramatic 150 clients/sec 😀\nHere is the list of filters that I\u0026rsquo;ve enabled:\npagespeed EnableFilters responsive_images; pagespeed EnableFilters outline_css; pagespeed EnableFilters outline_javascript; pagespeed EnableFilters move_css_above_scripts; pagespeed EnableFilters move_css_to_head; pagespeed EnableFilters rewrite_style_attributes; pagespeed EnableFilters prioritize_critical_css; pagespeed EnableFilters make_google_analytics_async; pagespeed EnableFilters canonicalize_javascript_libraries; pagespeed EnableFilters inline_google_font_css; pagespeed EnableFilters local_storage_cache; pagespeed EnableFilters convert_to_webp_animated; pagespeed EnableFilters insert_image_dimensions; pagespeed EnableFilters inline_preview_images; pagespeed EnableFilters resize_mobile_images; pagespeed EnableFilters remove_comments; pagespeed EnableFilters collapse_whitespace; pagespeed EnableFilters elide_attributes; pagespeed EnableFilters extend_cache_pdfs; pagespeed EnableFilters sprite_images; pagespeed EnableFilters rewrite_domains; pagespeed EnableFilters trim_urls; pagespeed EnableFilters remove_quotes; pagespeed EnableFilters defer_javascript; pagespeed EnableFilters dedup_inlined_images; pagespeed EnableFilters lazyload_images; pagespeed EnableFilters insert_dns_prefetch; Brotli (max compression) Just add Accept-Encoding: br to loader.io request headers and\u0026hellip; 75 clients / sec. Not bad considering that I\u0026rsquo;ve enabled the maximum (11) level of compression!\n..and, if you are curious about the compression, my homepage file sizes are (method from Mozilla\u0026rsquo;s brotli post ):\nAlgorithm Size none 9508 gzip 3344 brotli 2732 ","permalink":"https://stefano.chiodino.uk/posts/server-load-test/","summary":"\u003cp\u003eI\u0026rsquo;ve recently tried \u003ca href=\"https://m.do.co/c/875cd23a5c97\" target=\"_blank\"\u003eDigitalocean\u003c/a\u003e hosting and decided to host this blog on it. I\u0026rsquo;m running a $5 / month server, or droplet as they call it, with 1 CPU, 512 MB of ram, 20 GB SSD and 1 TB of bandwidth. You even get $10 credit when you sign up, sweet!\u003c/p\u003e\n\u003cp\u003eYou may look down on a $5 machine but I\u0026rsquo;ve found it to be more than enough for my need.\u003c/p\u003e","title":"Server load test"}]