This is a valid Atom 1.0 feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
[help]
<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="http://reinout.vanrees.org/" xml:lang="en"> <link rel="self" href="http://reinout.vanrees.org/weblog/atom.xml" /> <link href="http://reinout.vanrees.org/weblog/" rel="alternate" type="text/html" /> <div xmlns="http://www.w3.org/1999/xhtml"> <a href="http://www.atomenabled.org/feedvalidator/check.cgi?url=http%3A%2F%2Freinout.vanrees.org%2Fweblog%2Fatom.xml"> <img title="Validate my Atom feed" width="88" height="31" src="http://www.atomenabled.org/feedvalidator/images/valid-atom.png" alt="[Valid Atom]" border="0px" /> </a> <p> <span> This is an Atom formatted XML site feed. It is intended to be viewed in a Newsreader or syndicated to another site. Please visit </span> <a href="http://www.atomenabled.org/">Atom Enabled</a> <span> for more info. </span> </p> </div> <title type="html">Reinout van Rees' weblog</title> <subtitle>Python, grok, books, history, faith, etc.</subtitle> <updated>2009-04-04T21:44:00+01:00</updated> <id>urn:syndication:a55644db8591c020bd38852775819a9a</id> <entry> <title>Pycon NL: keynote: how not to get fooled by your data while AI engineering - Sofie van Landeghem</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/8-fooled-data-ai.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/8-fooled-data-ai.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T14:50:00+01:00</updated> <category term="python" /> <category term="pycon" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>(Sofie helps maintain FastAPI, Typer and spaCy; this talk is all about AI).</p><p>Sofie started with an example of a chatbot getting confused about the actual winner ofan F1 race after disqualification of the winner. So you need to have a domain expert onboard who can double-check the data and the results.</p><p>Let's say you want your chatbot output to link to Wikipedia for important terms. That'sactually a hard task, as it has to do normalization of terms, differentiating betweenHamilton-the-driver, Hamilton-the-town, Hamilton-the-founding-father and more.</p><p>There's a measure for quality of output that's called an "F-score". She used some AImodel to find the correct page and got a 79.2% F-score. How good or bad is it?</p><p>For this, you can try to determine a reasonable bottom line. "Guessing already means50%" is what you might think. No, there are 7 million Wikipedia pages, so randomguessing gives 0% F-score. Let's pick all the pages which actually mention the word"Hamilton". If we then look at more words like "Alexander Hamilton" or "Lewis Hamilton",we can reason that a basic non-AI regular approach should get 78% at least, so the AImodel's 79.2% isn't impressive.</p><p>The highest reachable quality depends on the data itself and what peopleexpect. "Hamilton won at Spa", do you expect Spa to point at the town or at the circuit?The room voted 60/40, so even the best answer itself can't be 100% correct :-)</p><p>A tip: if you get a bad result, investigate the training data to see if you can spotsome structural problem (which you can then fix). Especially if you have your ownannotated data. In her example, some of the annotators annotated circuit names<em>including</em> the "GP" or "grand prix" name ("Monaco GP") and others just the town name("Spa").</p><p>Some more tips:</p><ul class="simple"><li>Ensure your label scheme is consistent.</li><li>Draft clear annotation guidelines.</li><li>Measure inter-annotator agreement (IAA). So measure how much your annotators agree onterms. An article on F1 and politics: how many annotate it as politics and how many asF1?</li><li>Consider reframing your task/guidelines if the IAA is low.</li><li>Model uncertainty in your annotation workflow.</li><li>Identify structural data errors.</li><li>Apply to truly unseen data to measure your model's performance.</li><li>Make sure you climb the right hill.</li></ul><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-8.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-8.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: just over the border in Germany, westayed two days in Passau. View from the 'Oberhaus' castle on three rivers combining,with visibly different colors. From the left, the small, dark 'Ilz'. The big,drab-colored one in the middle is the 'Donau' (so 'schöne blaue Donau' should be takenwith a grain of salt). From the right, also big, the much lighter 'Inn' (lots of granite sediment from the Alps, here).</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: workshop: measuring and elevating quality in engineering practice - Daniele Procida</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/7-measuring-elevating-quality.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/7-measuring-elevating-quality.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T13:55:00+01:00</updated> <category term="python" /> <category term="pycon" /> <category term="django" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>Daniele works as director of engineering at Canonical (the company behindUbuntu). What he wants to talk about today is how to <strong>define, measure and elevateengineering quality at scale</strong>. That's his job. He needs to influence/change that in anorganization with a thousand technical people in dozens of teams with 100+projects. They ideally must converge on the standards of quality <em>he</em> has defined <em>andthere's only one of me</em>. <strong>Engineering people are opinionated people</strong> :-)</p><p>Your personal charm and charisma wears thin after a while: there needs to be a differentway. So: how can you get 1000+ to do what you want, the way you want. Ideally somewhatwillingly? You cannot <em>make</em> people do it. You'll have to be really enthousiastic aboutit.</p><p>He suggests three things:</p><ul class="simple"><li><strong>Principle</strong>. Description of quality as objective conditions, allowing it to be definedand measured.</li><li><strong>Tool</strong>. A simple dashboard, that reinforces your vision of quality and reflects it backto your teams. Daniele focuses on documentation, and showed a dashboard/spreadsheetthat showed the documentation status/progress of various projects. You can do the samefor "security" for instance.</li><li><strong>Method</strong>. A way of drawing your teams into your vision, so that they actively want toparticipate in.</li></ul><p>It being a workshop, we worked through a few examples. Someone mentioned "improved testcoverage in our software".</p><ul class="simple"><li>Describe your aim(s). What do you want. What is the background documentation. What isyour reason.</li><li>You need objectives on various levels. "Started", "first results", "mature". And youcan have those levels for each of your aims/categories. Start small and startspecific.<ul><li><strong>Started</strong>. "The team understands the significance of automated testing". "We havecoverage information about tests".</li><li><strong>First results</strong>. "There is a significant increase in test coverage". Note:"significant" means you have something to talk about. You can be reasonable on theone hand, but you can also call out low numbers. Human-sized words with value, like"significant", help internalize it. More than a number like "25%" would ever do. Youdon't want to check off the box "25%", you want to be able to claim that your teamnow has significant test coverage!</li><li><strong>Mature</strong>. Let's keep it simple with "100% test coverage".</li></ul></li><li>Measure the level projects are at at the moment. Show it in a dashboard. He used aGoogle spreadsheet previously, now it is a Django website. He'll make it aworld-public website soon. So it is visible for everybody. This helps draw teams intoit.</li></ul><p>Why does this work with human beings?</p><ul class="simple"><li><strong>Peer pressure</strong>. People see their peers doing the right thing. People want to be seendoing the right thing.</li><li><strong>Objectification</strong>. The contract and the results are described objectively. Theconditions and evidence stand <em>outside</em> you: it is not personal anymore, so it is nota threat.</li></ul><p>Humans are funny creatures. As soon as they believe in something, it will carry themover many bumps in the road.</p><p>People love to see their work recognized. So if you maintain a spreadsheet with all theprojects' results and progress, you won't have to ask them for an update: they will bugyou if the spreadsheet hasn't been updated in a while. They really want to see the workthey've put in!</p><p>You can get a positive feedback loop. If the work you need to do is clear, if the valueis clear and if there is recognition, you'll want to do it almost automatically. And ifyou do it, you mention it in presentations and discussions with others. Then the othersare automatically more motivated to work on it, too.</p><p>Giving kids a sticker when they do something successfully really helps. It also worksfor hard-core programmers and team managers!</p><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-7.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-7.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: just over the border in Germany,Passau has a nice cathedral.</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: kedro, lessons from maintaining an open source framework - Merel Theisen</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/6-kedro-maintaining-framework.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/6-kedro-maintaining-framework.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T12:31:00+01:00</updated> <category term="python" /> <category term="pycon" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>Full title: <em>leading kedro: lessons from maintaining an open source python framework</em>.</p><p>Merel is the tech lead of the python open source framework <a class="reference external" href="https://kedro.org/">kedro</a>.</p><p>What is open source? Ok, the source code is publicly available for anyone to use, modifyand share. But it is also a concept of sharing. Developing together. "Peerproduction". It also means sharing of technical information and documentation. In the1990s the actual term "open source" was coined. Also, an important milestone: Github waslaunched in 2008, greatly easing open source development.</p><p>Kedro is a python toolbox that applies software engineering principles to data sciencecode, making it easier to go from prototype to production. Started in 2017, it was opensourced in 2019. (Note: Kedro has now been donated to the Linux foundation). This madeit much easier to collaborate with others outside the original company (Quantumblack).</p><p>Open source also means <strong>maintenance challenges</strong>. It is not just code. Code is thesimple part. How to attract contributors? How to get good quality contributions? What toaccept/reject? How to balance quick wins with the long term vision of the project? Howto make contributors come back?</p><p>What lessons did they learn?</p><ul class="simple"><li>Importance of contributor guidance. They themselves had high standards with goodprogramming practices. How much can you ask from new contributors? They noticed theyneeded to improve their documentation a lot. And they had to improve their tooling. Ifyou want well-formatted code, you need easy tools to do the formatting, forinstance. And you need to actually <em>document</em> your formatting guidelines :-)</li><li>Response time is important. Response time for issues, pull requests and support. Ifyou don't get a timely answer, you'll lose interest as contributor. Also: tickets needto be polished and made clearer so that new contributors can help fixing them.</li><li>Sharing pain points is a contribution, too. More contributors and users automaticallymean more feature requests. But you don't want your project to become a Frankensteinmonster... A configuration file, for instance, can quickly become too clutteredbecause of all the options. Sometimes you need to evolve the architecture to deal withcommon problems. Users will tell you what they want, but perhaps it can be solveddifferently.</li><li>The importance of finding contribution models that fit. Perhaps a plugin mechanism fornew functionality? Perhaps a section of the code marked "community" without theregular project's guarantees about maintenance and longevity?</li><li>Be patient and kind. "Open source" means "people". Code is the easy part, people addcomplexity. Maintainers can be defensive and contributors can be demanding.</li></ul><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-6.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-6.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: Neufelden has a dam+reservoir, thewater travels downstream by underground pipe to the hydropower plant. At this point thepipe comes to the surface and crosses the river on a concrete construction. Nearby, thehighest road bridge in this region also crosses.</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: don't panic, a developer's guide to security - Sebastiaan Zeeff</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/5-developer-guide-security.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/5-developer-guide-security.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T11:58:00+01:00</updated> <category term="python" /> <category term="pycon" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>He showed a drawing of <a class="reference external" href="https://en.wikipedia.org/wiki/Cornelis_Jol">Cornelis "wooden leg" Jol</a>, a pirate from the 17th century fromSebastiaan's hometown. Why is he a pirate? He dresses like one, has a wooden leg,murders people like pirate and even has a parrot, so he's probably a pirate. For pythonprogrammers used to duck typing, this is familiar.</p><p>The 17th century, the Netherlands were economically wealthy. And had a big sea-faringempire. But they wanted a way to expand their might without paying forit. So... privatization to the rescue. You give pirates a <em>vrijbrief</em>, a governmentletter saying they've got some kind of "permission" from the Dutch government to rob andpillage and kill everybody as long it aren't Dutch people and ships. <strong>A privateer</strong>.Soit looks like a pirate and behaves like a pirate, but it isn't technically a realpirate.</p><p>Now on to today. There are a lot of cyber threats. Often state-sponsored. You <em>might</em> havea false sense of security in working for a relatively small company instead of for ajuicy government target. But... privateers are back! Lots of hacking companies havecoverage of governments - as long as they hack other countries. And hacking smallcompanies can also be profitable.</p><p>"I care about security". <strong>Do you really?</strong> What do real security people think? Theythink developers don't really pay much attention to it. Eye-roll at best, disinterest atworst. Basically, "it is somebody else's problem".</p><p>What you need is a <strong>security culture</strong>. A buy-in at every level. You can draw ananalogy with <em>safety culture</em> at physically dangerous companies like petrochemical. So:you as developer, should argue for security with your boss. You are a developer, so youhave a duty to speak up. Just like a generic employee at a chemical plant has the dutyto speak when seeing something risky.</p><p>You don't have to become a security export (on top of everything else), but you do haveto pay attention. Here are some pointers:</p><ul class="simple"><li>"Shift left". A term meaning you have to do it earlier rather than later. Don't try tosecure your app just before shipping, but take it into account from thebeginning. <strong>Defense in depth</strong>.</li><li>"Swiss cheese model". You have multiple layers in your setup. Every layer only needsone hole for the total to be penetrated.</li><li>Learn secure design principles. "Deny by default", "fail securely", "avoid security byobscurity", "minimize your attack surface", etc. <strong>Deny by default</strong> is a problem inthe python world. We're beginner-friendly, so often everything is open...</li><li>Adopt mature security practices. Ignore ISO 27001, that's too hard to understand. Lookat <a class="reference external" href="https://owasp.org/">OWASP</a> instead. OWASP DevSecOps maturity model ("pin yourartifacts", for instance).</li><li>Know common vulnerabilities. Look at the popular "top 10" lists. Today, SQL injection<em>still</em> makes victims...</li></ul><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-5.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-5.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: center of Neufelden, nicely restoredand beautifully painted.</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: tooling with purpose - Aris Nivortis</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/4-tooling-with-purpose.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/4-tooling-with-purpose.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T10:30:00+01:00</updated> <category term="python" /> <category term="pycon" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>Full title: <em>tooling with purpose: making smart choices as you build</em>.</p><p>Aris uses python and data to answers research questions about everything under theground (as geophysicist).</p><p>As a programmer you have to make lots of choices. Python environment, core projecttooling, project-specific tooling, etc.</p><p>First: <strong>python environment</strong> management: pyenv/venv/pip, poetry, uv. And conda/pixi forthe scientific python world. A show of hands showed <tt class="docutils literal">uv</tt> to be real popular.</p><p>Now core <strong>project tooling</strong>. Which project structure? Do you use atemplate/cookiecutter for it? Subdirectories? A testing framework? Pytest is thedefault, start with that. (He mentioned "doctests" becoming very popular: that surprisedme, as they were popular before 2010 and started to be considered old and deprecatedafter 2010. I'll need to investigate a bit more).</p><p>Linting and type checking? Start with <tt class="docutils literal">ruff</tt> for formatting/checking. Mypy is thestandard type checker, but pyright/vscode and pyre are options. And the new <tt class="docutils literal">ty</tt> isalpha, but looks promising.</p><p>Also, part of the core tooling: do you document your code? At least a README.</p><p>For <strong>domain specific tooling</strong> there are <em>so many choices</em>. It is easy to getlost. What to use for data storage? Web/API? Visualization tools. Scientific libraries.</p><p>Choose wisely! With great power comes great responsibility, but with great power alsocomes the <em>burden of decision-making</em>. Try to standardize. Enforce policies. Try to keepit simple.</p><p>Be aware of over-engineering. Over-engineering often comes with goodintentions. And... sometimes complexity <em>is</em> the right path. As an example, look atdatabase choices. You might wonder between SQL or a no-sql database and whether you needto shard your database. But often a simple sqlite database file is fast enough!</p><p>Configuration management: start with a simple <tt class="docutils literal">os.getenv()</tt> and grab settings fromenvironment variables. Only start using .toml files when that no longer fits your usecase.</p><p>Web/api: start simple. You probably don't need authentication from the start if it isjust a quick prototype. Get something useful working, first. Once it works, you canstart working on deployment or a nicer frontend.</p><p>Async code is often said to be faster. But debugging is time-consuming and hard. Errorhandling is different. It only really pays off when you have many, many concurrentoperations. Profile your code before you start switching to async. It won't speed upCPU-bound code.</p><p>Logging: just start using with the built-in logging module. Basic logging is better thanno logging. Don't start the Perfect Fancy Logging Setup until you have the basicsrunning.</p><p>Testing is good and recommended, but don't go overboard. Don't "mock" everything to get100% coverage. Those kinds of tests break often. And often the tests test the mockinstead of your actual code. <strong>Aim for the same amount of test code compared to youractual code</strong>.</p><p>Some closing comments:</p><ul class="simple"><li>Sometimes simple choices are better.</li><li>Don't let decision=making slow you down. Start making prototypes.</li><li>One-size-fits-all solutions don't exist. Evaluate for your use case.</li><li>If you are an experienced developer, help your colleagues. They have to make lots ofchoices.</li><li>Early-career developer? Luckily a lot of choices are already made for you due tocompany policy or because the project you're working on already made most choices foryou :-)</li></ul><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-4.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-4.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: Neufelden station. From a 1991 traintrip. I remembered the valley as being beautiful. As we now do our family holidays bytrain, I knew where to go as soon as Austria was chosen as destination.</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: from flask to fastapi - William Lacerda</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/3-from-flask-to-fastapi.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/3-from-flask-to-fastapi.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T09:50:00+01:00</updated> <category term="python" /> <category term="pycon" /> <category term="django" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>Full title: <em>from flask to fastapi: why and how we made the switch</em>.</p><p>He works at "polarsteps", a travel app. Especially a travel app that will be used inareas with really bad internet connectivity. So performance is top of mind.</p><p>They used flask for a long time. Flask 2 added async, but it was still WSGI-bound. Theyreally needed the async scaling possibility for their 4 million monthly users. Typehinting was also a big wish item for improved reliability.</p><p>They switched to fastapi:</p><ul class="simple"><li>True async support. It is ASGI-native</li><li>Typing and validation with pydantic. Pydantic validates requests and responses. Typehints help a lot.</li><li>Native auto-generated docs (openapi). Built-in swagger helps for the frontend team.</li></ul><p>This meant they gave up some things that Flask provided:</p><ul class="simple"><li>Flask has a mature ecosystem. So they left a big community + handy heap ofstackoverflow answers + lots of ready-made plugins behind.</li><li>Integrated command-line dev tools. Flask is handy there.</li><li>Simplicity, especially for new devs.</li></ul><p>They did a gradual migration. So they needed to build a custom fastapi middleware thatcould support both worlds. And some api versioning to keep the two code bases apart. Ittook <strong>a lot of time</strong> to port everything over.</p><p>The middleware was key. Completely async in fastapi. Every request came through here. Ifneeded, a request would be routed to Flask via wsgi, if possible it would go to the newfastapi part of the code.</p><p>For the migration, they <strong>made a dashboard</strong> of all the endpoints and the trafficvolume. They migrated high-traffic APIs first: early infra validation. Attention toimprovements by checking if the queries were faster. Lots of monitoring of bothperformance and errors.</p><p>Some lessons learned:</p><ul class="simple"><li>Async adds complexity, but pays off at scale. They started the process with 4 millionusers, now they're at 20.</li><li>Pydantic typing catches errors early.</li><li>Versioned middleware made incremental delivery safe.</li><li>Data-driven prioritization (=the dashboard) beats a big-bang rewrite.</li><li>AI helps, but hallucinates too much on complex APIs.</li></ul><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-3.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-3.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: the beautiful 'große Mühl' rivervalley.</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: typing your python code like a ninja - Thiago Bellini Ribeiro</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/2-typing-python.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/2-typing-python.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T09:15:00+01:00</updated> <category term="python" /> <category term="pycon" /> <category term="django" /> <content type="html">< -> T: ... # Same, but restricted to two typesdef something[T: str|int](x: T) -> T: ...</pre><p>Generic classes can be handy for, for instance, django:</p><pre class="literal-block">class ModelManager[T: Model]: def __init__(self, model_class: type[T]) -> None: .... def get(self, pk: int) -> T: ...</pre><p>Type narrowing. Sometimes you accept a broad range of items, but if you return True, itmeans the input is of a specific type:</p><pre class="literal-block">from typing import TypeGuard def is_user(obj: Any) -> TypeGuard[User]: .... def something(obj: Any): if is_user(obj): # From here on, typing knows obj is a User</pre><p>Generic <tt class="docutils literal">**kwargs</tt> are a challenge, but there's support for it:</p><pre class="literal-block">from typing import TypedDict, Required, Unpack class SomethingArgs(TypedDict, total-False): usernanme: Required(str) age: int def something(**kwargs: Unpack[SomethingArgs]): ...</pre><p>If you return "self" from some class method, you run into problems with subclasses, asnormally the method says it returns the parent class. You can use <tt class="docutils literal">from typing importSelf` and return the type ``Self</tt> instead.</p><p><em>Nice talk, I learned quite a few new tricks!</em></p><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-2.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-2.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: church of Neufelden seen on the topof the hill.</em></p></div> ]]> </content> </entry> <entry> <title>Pycon NL: programming, past and future - Steven Pemberton</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/10/16/1-programming-past-future.html" /> <id>http://reinout.vanrees.org/weblog/2025/10/16/1-programming-past-future.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-10-16T00:00:00+01:00</published> <updated>2025-10-16T08:11:00+01:00</updated> <category term="python" /> <category term="pycon" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/10/16/index.html">my summaries</a> ofthe <a class="reference external" href="https://pycon-nl.org/">Pycon NL one-day conference</a> in Utrecht, NL).</p><p>(Note: I've heard a keynote by Steven <a class="reference external" href="https://reinout.vanrees.org/weblog/2016/05/13/8_future_of_programming.html">at pygrunn 2016</a>.)</p><p>Steven is in the <a class="reference external" href="https://www.youtube.com/watch?v=GfH4QL4VqJ0">python documentary</a>, heco-designed the <tt class="docutils literal">abc</tt> programming language that was the predecessor to python. ABC wasa research project that was designed for the programmer's needs. He also was the firstuser of the open internet in Europe in November 1988, as the CWI at the university hadthe first 64kbps connection in Europe. Co-designer of html, css, xhtml, rdf, etc.</p><p>1988, that's 37 years ago. But only about 30 years earlier, the first municipality(Norwich, UK) got a computer. 21 huge crates. It ran continuously for 10 years. A modernRaspberry pi would take 5 minutes to do the same work!</p><p>Those early computers were expensive: an hour of programming time was a year's salaryfor a programmer. So, early programming languages were designed to optimize for thecomputer. Nowadays, it is the other way around: computers are almost free and programmersare expensive. This hasn't really had an effect on the way we program.</p><p>He's been working on <strong>declarative</strong> programming languages. One of the declarativesystems is <strong>xforms</strong>, an xml-based declarative system for defining applications. It isa w3c standard, but you rarely see it mentioned. But quite some companies and governmentorganisations use it, like the Dutch weather service (KNMI).</p><p>The NHS (UK nationwide health service) had a "Lorenzo" system for UK patient recordsthat cost billions of pounds, took 10 years to build and basically failed. Severalhospitals (and now hospitals in Ukraine!) use an xforms-system written in three years bya single programmer. Runs, if needed, on a Raspberry pi.</p><p>He thinks declarative programming allows programmers to be at least ten times moreproductive. He thinks, eventually everyone will program declaratively: fewer errors,more time, more productivity. (And there's a <a class="reference external" href="http://declarative.amsterdam">small conference in Amsterdam</a> in November).</p><img alt="https://reinout.vanrees.org/images/2025/austria-vacation-1.jpeg" src="https://reinout.vanrees.org/images/2025/austria-vacation-1.jpeg" /><p><em>Unrelated photo from our 2025 holiday in Austria: in Vienna/Wien I visited the militarymuseum. This is the car in which archduke Franz Ferdinand was shot in Sarajevo in1914.</em></p></div> ]]> </content> </entry> <entry> <title>Leiden python meetup: memory graph - Bas Terwijn</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/09/04/3-memory-graph.html" /> <id>http://reinout.vanrees.org/weblog/2025/09/04/3-memory-graph.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-09-04T00:00:00+01:00</published> <updated>2025-09-04T20:07:00+01:00</updated> <category term="pun" /> <category term="python" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/09/04/index.html">my summaries</a> ofthe <a class="reference external" href="https://www.meetup.com/python-leiden-user-group/events/308921156/">fifth Python meetup</a> in Leiden, NL).</p><p>Full title of the talk: memory graph: <strong>teaching tool</strong> and <strong>debugging aid</strong> in contextof references, mutable data types, and shallow and deep copy.</p><p><a class="reference external" href="https://github.com/bterwijn/memory_graph">memory_graph</a> is a python debugging aid andteaching tool. It is a modern version of <em>python tutor</em>. (There is an <a class="reference external" href="https://memory-graph.com/#breakpoints=8&continues=1&timestep=1.0&play">online demo</a>)</p><p>Python has two categories of types:</p><ul class="simple"><li>Immutable types: bool, int, float, str, tuple, etcetera. They cannot be mutated, sowhen a value is changed, a copy is made. If you add an item to a tuple, you get a<strong>new</strong> tuple with the extra item.</li><li>Mutable types: dicts, lists. You can change the values without the actual dict/listchanging. You can add items to a list and you still have the same list object.</li></ul><p>When you want an actual copy of a mutable type, you need to use <tt class="docutils literal">import copy</tt> and<tt class="docutils literal">copy.copy(your_list)</tt>. And <tt class="docutils literal">copy.deepcopy()</tt>.</p><ul class="simple"><li><tt class="docutils literal">list2 = list1</tt> is an assignment.</li><li><tt class="docutils literal">list2 = copy.copy(list1)</tt> gives you a second, separate, list object, but it pointsat the same values inside it as list1.</li><li><tt class="docutils literal">list2 = copy.deepcopy(list1)</tt> gives you a second, separate, list object <em>and</em>separate copies of the values inside it.</li></ul><p>Watch out with the <tt class="docutils literal">list2 = list1</tt> assignment. When you add an item to list2, it isalso "added" to list1 as it is the same.</p><p>He had a couple of simple exercises for us, which were amusingly hard :-)</p><p>Apart from the web online demo, there are also integrations for jupyter notebooks andlots of IDEs. Here's an animated gif from the github repo:</p><img alt="https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/vscode_copying.gif" src="https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/vscode_copying.gif" /></div> ]]> </content> </entry> <entry> <title>Leiden python meetup: HTMX - Jan Murre</title> <link rel="alternate" type="text/html" href="http://reinout.vanrees.org/weblog/2025/09/04/2-htmx.html" /> <id>http://reinout.vanrees.org/weblog/2025/09/04/2-htmx.html</id> <author> <name>Reinout van Rees</name> </author> <published>2025-09-04T00:00:00+01:00</published> <updated>2025-09-05T07:48:00+01:00</updated> <category term="pun" /> <category term="python" /> <category term="django" /> <content type="html"><![CDATA[ <div class="document"><p>(One of <a class="reference external" href="https://reinout.vanrees.org/weblog/2025/09/04/index.html">my summaries</a> ofthe <a class="reference external" href="https://www.meetup.com/python-leiden-user-group/events/308921156/">fifth Python meetup</a> in Leiden, NL).</p><p>The person who invented <a class="reference external" href="https://htmx.org/">htmx</a> (Carson Gross) always begins with<strong>hypermedia</strong>. <em>Hypermedia is a media that includes non-linear branching from onelocation in the media to another, via hyperlinks.</em> HTML is hypermedia, the world's mostsuccesful hypertext.</p><p>Another important term: <a class="reference external" href="https://en.wikipedia.org/wiki/HATEOAS">HATEOAS</a>, <em>hypermediaas the engine of application state</em>. With hypermedia, state is on the server. So not ina javascript frontend. With traditional <em>single page apps</em> that you see nowadays, youonly read some json and the frontend needs to know what to do with it. Lots of logic ison the client. And you get "javascript fatigue".</p><p>With hypermedia, you have server-side rendering. Minimal javascript. Progressiveenhancement. SEO friendly. And... accessible by default. The content you get includesthe behaviour (like a link to delete an item).</p><p>HTMX extends HTML with modern interactivity using simple attributes. You can targetspecific elements on your page for an update, so you don't need to get a full pagerefresh. And you can use any http verb (get/post/put/delete/patch). And you're notlimited to forms and links: any element can trigger a request.</p><p>Some attribute examples:</p><ul class="simple"><li><tt class="docutils literal"><span class="pre">hx-get</span></tt> issues a GET request to the server when you click on the element.</li><li><tt class="docutils literal"><span class="pre">hx-post</span></tt>, same with POST.</li><li><tt class="docutils literal"><span class="pre">hx-target</span></tt>, what you get back from your get/post, where do you want to place it?</li><li><tt class="docutils literal"><span class="pre">hx-swap</span></tt>: just replace part of the page.</li><li><tt class="docutils literal"><span class="pre">hx-trigger</span></tt>: when to do the request. Based on a click or based on a timer, forinstance.</li></ul><p>An advantage of HTMX is <strong>maintainability</strong>. Complexity is way lower than a <em>single pageapp</em>. Familiar patterns and regular server-side logic. Much simpler. Accessible(provided you put in some effort).</p><p>He showed a nice example with a generated list, a search field and a form. Nice: extravalidation on one of the form fields via a <tt class="docutils literal"><span class="pre">hx-post</span></tt> and a <tt class="docutils literal"><span class="pre">hx-trigger="on-blur"</span></tt>.</p><p>Nice trick for <tt class="docutils literal"><span class="pre">hx-target</span></tt>: you can give it the value of <tt class="docutils literal">"closest<span class="pre">.some-css-class"</span></tt>, then it finds the closes enclosing element with that class.</p><p>Other niceties: <tt class="docutils literal"><span class="pre">hx-indicator</span></tt> enables a spinner upon a POST and disables it once thePOST succeeds. <tt class="docutils literal"><div <span class="pre">hx-boost="true"></span></tt> around your content tells HTMX to replace yourwhole page's content with the new page, the result is the same as normally, only withoutthe temporary flicker when loading the page.</p><p>HTMX is great for:</p><ul class="simple"><li>CRUD applications.</li><li>Content-heavy sites.</li><li>Forms and validation.</li><li>Server-side rendered apps.</li><li>Progressive enhancement.</li><li>Moderate interactivity.</li></ul><p>You can read a book about HTMX here: <a class="reference external" href="https://hypermedia.systems/">https://hypermedia.systems/</a></p><p>In response to a question: the author considers htmx to be <strong>complete andfinished</strong>. What works now should work in 20 years. So it will rarely change (unlikesomething like react that changes all the time).</p></div> ]]> </content> </entry> </feed>If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid Atom 1.0" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.feedvalidator.org/check.cgi?url=http%3A//reinout.vanrees.org/weblog/atom.xml