Mark Dufour: A (biased) Pure Python Performance Comparison

The following is a performance comparison of several (pure) Python implementations, for a large part of the Shed Skinexample set. I left out some of the examples, that would result in an unfair comparison (mostly because of randomization), or that were too interactive to easily measure. Obviously this comparison is very biased, and probably unfair in some way to the other projects (though I've tried to be fair, for example by letting PyPy stabilize before measuring).

This first plot shows the speedups versus CPython 3.10, for CPython 3.14, Nuitka, Pypy and Shed Skin.

Shed Skin is able to speed up the examples by an average factor of about 29 times (not percent, times :)), while PyPy is able to speed up the examples by an average factor of about 16 times. Given that PyPy has its hands tied behind its back trying to support unrestricted Python code, and was not optimized specifically for these examples (that I am aware of), that is actually still quite an impressive result.

As for the few cases where PyPy performs better than Shed Skin, this appears to be mainly because of PyPy being able to optimize away heap allocations for short-lived objects (in many cases, custom Vector(x,y,z) instances). In a few cases also, the STL unordered_map that Shed Skin uses to implement dictionaries appears to perform poorly compared to more modern implementations. Of course it is possible for Shed Skin to improve in these areas with future releases.

Note that some of the examples can run even faster with Shed Skin by providing --nowrap/--nobounds options, which disable wrap-around/bounds-checking respectively. I'm not sure if PyPy has any options to make it run faster, at the cost of certain features (in the distant past there was talk of RPython - does that still exist?).

As the CPython 3.14 and Nuitka results are a bit hard to see in the above plot, here is the same plot but with a logarithmic y-scale:

CPython 3.14 is about 60% faster on average for these examples than CPython 3.10, which to me is actually very promising for the future. While Nuitka outperforms CPython 3.10 by about 30% on average, unfortunately it cannot match the improvements in CPython since.

If there are any CS students out there who would like to help improve Shed Skin, please let me know. I think especially memory optimizations (where PyPy still seems to have an edge) would be a great topic for a Master's Thesis!

http://shed-skin.blogspot.com/2025/12/a-biased-pure-python-performance.html

"Michael Kennedy's Thoughts on Technology": DevOps Python Supply Chain Security

Image

In my last article, “Python Supply Chain Security Made Easy” I talked about how to automatepip-auditso you don’t accidentally ship malicious Python packages to production. While there was defense in depth with uv’s delayed installs, there wasn’t much safety beyond that for developers themselves on their machines.

This follow up fixes that so even dev machines stay safe.

Defending your dev machine

My recommendation is instead of installing directly into a local virtual environment and then running pip-audit, create a dedicated Docker image meant for testing dependencies with pip-audit in isolation.

Our workflow can go like this.

First, we update your local dependencies file:

This will update the requirements.txt file, or tweak the command to update your uv.lock file, but it don’t install anything.

Second, run a command that uses this new requirements file inside of a temporary docker container to install the requirements and run pip-audit on them.

Third, only if that pip-audit test succeeds, install the updated requirements into your local venv.

The pip-audit docker image

What do we use for our Docker testing image? There are of course a million ways to do this. Here’s one optimized for building Python packages that deeply leverages uv’s and pip-audit’s caching to make subsequent runs much, much faster.

Create a Dockerfile with this content:

This installs a bunch of Linux libraries used for edge-case builds of Python packages. It takes a moment, but you only need to build the image once. Then you’ll run it again and again. If you want to use a newer version of Python later, change the version inuv venv --python 3.14 /venv. Even then on rebuilds, the apt-get steps are reused from cache.

Next you build with a fixed tag so you can create aliases to run using this image:

Finally, we need to run the container with a few bells and whistles. Add caching via a volume so subsequent runs are very fast:-v pip-audit-cache:/root/.cache. And map a volume so whatever working directory you are in will find the local requirements.txt:-v \"\$(pwd)/requirements.txt:/workspace/requirements.txt:ro\"

Here is the alias to add to your.bashrcor.zshrcaccomplishing this:

That’s it! Once you reload your shell, all you have to do is type ispip-audit-projwhen you’re in the root of your project that contains your requirements.txt file. You should see something like this below. Slow the first time, fast afterwards.

Image

Protecting Docker in production too

Let’s handle one more situation while we are at it. You’re running your Python appINDocker. Part of the Docker build configures the image and installs your dependencies. We can add a pip-audit check there too:

Conclusion

There you have it. Two birds, one Docker stone for both. Our first Dockerfile built a reusable Docker image namedpipauditdockerto run isolated tests against a requirements file. This second one demonstrates how we can make ourdocker/docker compose buildcompletely fail if there is a bad dependency saving us from letting it slip into production.

Cheers
Michael

https://mkennedy.codes/posts/devops-python-supply-chain-security/

"Michael Kennedy's Thoughts on Technology": DevOps Python Supply Chain Security

Image

In my last article, “Python Supply Chain Security Made Easy” I talked about how to automatepip-auditso you don’t accidentally ship malicious Python packages to production. While there was defense in depth with uv’s delayed installs, there wasn’t much safety beyond that for developers themselves on their machines.

This follow up fixes that so even dev machines stay safe.

Defending your dev machine

My recommendation is instead of installing directly into a local virtual environment and then running pipaudit, create a dedicated Docker image meant for testing dependencies with pip-audit in isolation.

Our workflow can go like this.

First, we update your local dependencies file:

This will update the requirements.txt file, or tweak the command to update your uv.lock file, but it don’t install anything.

Second, run a command that uses this new requirements file inside of a temporary docker container to install the requirements and run pip-audit on them.

Third, only if that pip-audit test succeeds, install the updated requirements into your local venv.

The pip-audit docker image

What do we use for our Docker testing image? There are of course a million ways to do this. Here’s one optimized for building Python packages that deeply leverages uv’s and pip-audit’s caching to make subsequent runs much, much faster.

Create a Dockerfile with this content:

This installs a bunch of Linux libraries used for edge-case builds of Python packages. It takes a moment, but you only need to build the image once. Then you’ll run it again and again. If you want to use a newer version of Python later, change the version inuv venv --python 3.14 /venv. Even then on rebuilds, the apt-get steps are reused from cache.

Next you build with a fixed tag so you can create aliases to run using this image:

Finally, we need to run the container with a few bells and whistles. Add caching via a volume so subsequent runs are very fast:-v pip-audit-cache:/root/.cache. And map a volume so whatever working directory you are in will find the local requirements.txt:-v \"\$(pwd)/requirements.txt:/workspace/requirements.txt:ro\"

Here is the alias to add to your.bashrcor.zshrcaccomplishing this:

That’s it! Once you reload your shell, all you have to do is type ispip-audit-projwhen you’re in the root of your project that contains your requirements.txt file. You should see something like this below. Slow the first time, fast afterwards.

Image

Protecting Docker in production too

Let’s handle one more situation while we are at it. You’re running your Python appINDocker. Part of the Docker build configures the image and installs your dependencies. We can add a pip-audit check there too:

Conclusion

There you have it. Two birds, one Docker stone for both. Our first Dockerfile built a reusable Docker image namedpipauditdockerto run isolated tests against a requirements file. This second one demonstrates how we can make ourdocker/docker compose buildcompletely fail if there is a bad dependency saving us from letting it slip into production.

Cheers
Michael

https://mkennedy.codes/posts/devops-python-supply-chain-security/

Seth Michael Larson: Getting started with Playdate on Ubuntu 🟨

Getting started with Playdate on Ubuntu

Here's what I did to quickly get started with a Playdate development environment on my Ubuntu 24.04 laptop:

  • Unbox the Playdate and start charging the console so it's charged enough for the next steps involving the console.
  • Create aPlaydate account.
  • Download the SDK. For Linux you need to extract to your desired directory (I chose~/PlaydateSDK) and run the setup script (sudo ~/PlaydateSDK/setup.sh).
  • Add the SDKbintoPATHandPLAYDATE_SDK_PATHenvironment variables to your~/.bashrc.
  • Start the simulator (PlaydateSimulator) and register the simulator to your Playdate account when prompted.
  • Turn on the console and play the startup tutorial. Connect to Wi-Fi and let the console update.
  • When prompted by the console, register the console to your Playdate account.
  • Downloadand install VSCode. I used the.debinstaller for Ubuntu.
  • Disable all AI features in VSCode by adding"chat.disableAIFeatures": trueto yoursettings.json.
  • Copy the.vscodedirectory from thisPlaydate template project. The author of this template, SquidGod, hasmultiple video guidesabout Playdate development.
  • Select "Extensions" in VSCode and install the "Lua" and "Playdate Debug" extensions.
  • Create two directories:sourceandbuilds. Within thesourcedirectory create a file calledmain.lua. This file will be the entry-point into your Playdate application.

That's it, your Playdate development environment should be ready to use.

“Hello, world” on the Playdate

Withinsource/main.luaput the following Lua code:

Try building and running this with the simulatorCtrl+Shift+B. You should see our "Hello world" message in the simulator.

Running “Hello, world” on real hardware

Next is getting your game running on an actual Playdate console. Connect the Playdate to your computer using the USB cable and make sure the console is awake.

Start your game in the simulator (Ctrl+Shift+B) and then once the simulator starts selectDevice>Upload Game to Devicein the menus or use the hotkeyCtrl+U.

Uploading the game to the Playdate console takes a few seconds, so be patient. The console will show a message like “Sharing DATA segment with USB. Will reboot when ejected”. You can select the "Home" button in the Playdate console menu to stop the game.

Making a network request

One of my initial hesitations with buying a Playdate was that it didn't originally ship with network connectivity within games, despite supporting Wi-Fi. This is no longer the case, as this year Playdate OS 2.7added support for HTTP and TCP networking.

So immediately after my "Hello world" game, I wanted to try this new feature. I created the following small application that sends an HTTP request after pressing theAbutton:

First I tried running this program with a local HTTP server onlocalhost:8080withuseHttpsset tofalseand was able to capture this HTTP request using Wireshark:

0000 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1.. 0010 48 6f 73 74 3a 20 6c 6f 63 61 6c 68 6f 73 74 0d Host: localhost. 0020 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 50 6c 61 .User-Agent: Pla 0030 79 64 61 74 65 2f 53 69 6d 0d 0a 43 6f 6e 6e 65 ydate/Sim..Conne 0040 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 0d 0a 0d 0a ction: close....

So we can see that Playdate HTTP requests are quite minimal, only sending aHost,User-AgentandConnection: closeheader by default. Keep-Alive and other headers can be optionally configured. TheUser-Agentfor the Playdate simulator wasPlaydate/Sim.

I then tested on real hardware and targeting my own website:sethmlarson.dev:443withuseHttpsset totrue. This resulted in the same request being sent, with aUser-AgentofPlaydate/3.0.2. There's no-doubt lots of experimentation ahead for what's possible with a networked Playdate. That's all for now,happy cranking!


Thanks for keeping RSS alive! ♥

https://sethmlarson.dev/getting-started-with-playdate-on-ubuntu?utm_campaign=rss

Seth Michael Larson: Blind Carbon Copy (BCC) for SMS

Have you ever wanted the power of emailBlind Carbon Copy(BCC), but for SMS? I've wanted this functionality myself for parties and organizing, specifically without needing to use a third-party service. This script automates the difficult parts of drafting and sending a text message to many recipients withSMS URLsand QR codes.

Draft your message, choose your recipients, and then scan-and-send all the QR codes until you're done. Save your command for later to follow-up in different groups.

Source code

Copy-and-paste the following source code into a file namedsms-bcc, make the file executable (chmod a+x sms-bcc) and you're ready to start using the script. Requires Python and theqrcodepackage(pip install qrcode) to run. This script is licensed MIT.

Source code forsms-bccscript

How to use

Export your contacts from your phone to a vCard file (.vcf). For iPhones this is done within the contacts app: long-press-and-hold “All Contacts” and select “Export”. This will create a.vcffile that you can transfer to your computer.

Now run thesms-bccscript with--contactsfor the.vcffile, draft a message in a file and pass with the--messageoption, and choose your recipients by their name with the--recipientsoption.

./sms-bcc \ --contacts contacts.vcf \ --recipients Alex,Bob Charlie \ --message ./message.txt

This will draft the message to two groups: "You, Alex, and Bob" and "You and Charlie". Note how spaces delimit groups of recipients and commas (,) delimit recipient names within a group.

After running this script, a series of QR codes using thesms://URL scheme will be generated one after another. Scan the QR code to load the message and recipient into your phone, then you can optionally send the message or skip, then pressEnterto generate the next QR code.

The--recipientsoption uses a simple string-contains operation, so I recommend having full names in your contacts to avoid excessive duplicates. You can pass a name with a leading hyphen/minus (-) character to exclude a name from the list of recipients. The below invocation will match people named "Alex" without matching "Alexander":

./sms-bcc --recipients Alex,-Alexander

If you have a spouse or partner that you want to include in every recipient group, use the--always-recipientsoption:

./sms-bcc \ --contacts contacts.vcf \ --recipients Bob Charlie,Dave \ --always-recipients Alex \ --message ./message.txt

This will draft the message for "You, Alex, and Bob" and "You, Alex, Charlie, and Dave".

🎄Merry Christmas and happy organizing!🎄

Changelog

  • 2025.12.26: Better handling for many different telephone number formats such as(555) 555-555. Added inline script metadata to header.
  • 2025.12.25: Initial release.

Thanks for keeping RSS alive! ♥

https://sethmlarson.dev/sms-bcc?utm_campaign=rss

Seth Michael Larson: Blind Carbon Copy (BCC) for SMS

Have you ever wanted the power of emailBlind Carbon Copy(BCC), but for SMS? I've wanted this functionality myself for parties and organizing, specifically without needing to use a third-party service. This script automates the difficult parts of drafting and sending a text message to many recipients withSMS URLsand QR codes.

Draft your message, choose your recipients, and then scan-and-send all the QR codes until you're done. Save your command for later to follow-up in different groups.

Source code

Copy-and-paste the following source code into a file namedsms-bcc, make the file executable (chmod a+x sms-bcc) and you're ready to start using the script. Requires Python and theqrcodepackage(pip install qrcode) to run. This script is licensed MIT.

Source code forsms-bccscript

How to use

Export your contacts from your phone to a vCard file (.vcf). For iPhones this is done within the contacts app: long-press-and-hold “All Contacts” and select “Export”. This will create a.vcffile that you can transfer to your computer.

Now run thesms-bccscript with--contactsfor the.vcffile, draft a message in a file and pass with the--messageoption, and choose your recipients by their name with the--recipientsoption.

./sms-bcc \ --contacts contacts.vcf \ --recipients Alex,Bob Charlie \ --message ./message.txt

This will draft the message to two groups: "You, Alex, and Bob" and "You and Charlie". Note how spaces delimit groups of recipients and commas (,) delimit recipient names within a group.

After running this script, a series of QR codes using thesms://URL scheme will be generated one after another. Scan the QR code to load the message and recipient into your phone, then you can optionally send the message or skip, then pressEnterto generate the next QR code.

The--recipientsoption uses a simple string-contains operation, so I recommend having full names in your contacts to avoid excessive duplicates. You can pass a name with a leading hyphen/minus (-) character to exclude a name from the list of recipients. The below invocation will match people named "Alex" without matching "Alexander":

./sms-bcc --recipients Alex,-Alexander

If you have a spouse or partner that you want to include in every recipient group, use the--always-recipientsoption:

./sms-bcc \ --contacts contacts.vcf \ --recipients Bob Charlie,Dave \ --always-recipients Alex \ --message ./message.txt

This will draft the message for "You, Alex, and Bob" and "You, Alex, Charlie, and Dave".

🎄Merry Christmas and happy organizing!🎄


Thanks for keeping RSS alive! ♥

https://sethmlarson.dev/sms-bcc?utm_campaign=rss

Real Python: Quiz: LlamaIndex in Python: A RAG Guide With Examples

In this quiz, you’ll test your understanding of theLlamaIndex in Python: A RAG Guide With Examplestutorial.

By working through this quiz, you’ll revisit how to create and persist an index to disk, review how to reload it, and see why persistence improves performance, lowers costs, saves time, and keeps results consistent.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days.>> Click here to learn more and see examples]

https://realpython.com/quizzes/llamaindex-examples/

Reuven Lerner: Reuven’s 2025 in review

Can you believe that 2025 is almost over? It was full of big events for me, and yet it also whizzed past at breakneck speed.

And so, before we start 2026, I want to share a whole bunch of updates on what I’ve done over the last 12 months — and where I plan to go in 2026, as well.

LernerPython

The biggest thing for me this year was the newLernerPython site. This site supports functionality that was previously impossible — and because it’s mine, it also allows me to fix problems and customize things more easily. I look forward to extending and customizing it even more in the coming months. Thanks to everyone who sent me bug reports about the site and course content during this transition period.

Among other things, the site automatically integrates with our private Discord server, which is our hub for not only questions and discussions, but also calendar invites to live Zoom sessions. It’s also where I save recordings from our Zoom meetings.

The site is also integrated withBamboo Weekly, ensuring that LernerPython+data members get a complimentary subscription without the need for manual intervention.

In 2025, I held live office hours on Zoom nearly every month for Python subscribers, and separate office hours nearly every month for Pandas subscribers. I really enjoy those sessions! Keep bringing your questions, thoughts, and stories.

I also held special, members-only lectures just about every month. These ranged in topic from the Unix shell to Marimo to dataclasses to concurrency. Thanks to those of you who attended, and especially those who suggested lecture topics. Recordings from these sessions are in the “meeting recordings” channels on Discord.

This year marked my start as a preferred partner with thePython Institute, a certification agency for Python. Members of LernerPython get discounts on their exams, making it easier (I hope!) to get good jobs in the Python world. In 2026, I plan to start a special monthly session of office hours to help you prepare for these exams.

With the newLernerPython.comnow ready, I’ll record some new courses in 2026, as well as re-record some of the older, existing ones.

I’ll also bump up visibility of myPersonal Python Coaching program, for people who just want an hour of my time for strategy, code review, or a clearer understanding of Python, Git, and Pandas topics.

Intensive training — PythonDAB and HOPPy

My best, longest, and most intensive course isPythonDAB, the Python Data Analytics Bootcamp. Over four months, participants learn Python, Git, and Pandas, meeting twice each week, solving exercises, and digging into the nuts and bolts of Python and Pandas. Cohort 8 started earlier this month, and the sessions are (as always) full of insightful questions and comments. I expect to open PythonDAB 9 in late May or early June of 2026 — and if you think it’s a good fit for you, I hope that you’ll apply, or at least ask me about it!

This year marked the start of a new class:HOPPy, Hands-on Projects in Python. HOPPy is about learning through doing, building a project that’s meaningful to you — but within the general theme of that specific HOPPy cohort. People created some amazing applications, from a communications system for heatlh clinics to a personal blood-pressure monitor to a bank status summarizer.

HOPPy is open (for an additional fee) to LernerPython members, and is included in the price for PythonDAB participants. I will be running 4-5 HOPPy cohorts in 2026, including one in January about data dashboards. More info is coming soon — but if you’ve always wanted to learn more in a mentored environment, and as a bonus add a new product to your personal portfolio, then HOPPy is just what you’re looking for.

Corporate training

I gave a good deal oftraining classes at companiesin 2025, including at Apple, Arm, Cisco, Intel, and Sandisk. (I also gave a number of online classes for O’Reilly’s platform.) These range from “Python for non-programmers” to intro and advanced Python, to intro Pandas, to my “Python Practice Workshop” and “Pandas Practice Workshop” one-day courses.

If your team wants to level up its Python skills, let’s chat! I’d love to hear more about your team’s needs, and what kind of custom class would work best for you.

A number of companies also joined LernerPython using myteam membershipfeature, allowing a manager to control the allocation of seats.

Conferences

I can’t get enough of Python conferences, which combine serious learning with friendly people. This year, I attended a number of conferences in person:

  • At PyCon US in Pittsburgh, I had a booth advertising my training programs, gave a tutorial on comprehensions, and also gave a talk aboutPyArrow’s future in the Pandas library. I also gave a talk aboutAI and learning at PyCon’s education summit.
  • At Euro Python in Prague, I gave a tutorial called, “Let’s write a dictionary,” which dug into how Python’s dictionaries work by creating one. My talk, “What = does in Python,” was fun to both research and talk. I also volunteered for the second year in a row, introducing speakers at several sessions.
  • I attended PyCon Taiwan for the second time, giving both a tutorial and a talk(“What does = do?”)there, as well. I can’t say enough positive things about Taiwan, and the Python community there is really delightful. I sponsored PyCon TW as well, and brought my two daughters with me to staff the booth and help me there. (Also, we got a chance to tour Taiwan together, which I highly recommend!)
  • I was invited to give a keynote address atPyCon India in Bangalore. This was my second time in India, and both the country and the conference lived up to all of my expectations. In addition to my talk, about the future of coding and learning in an AI-dominated world, I also attended many interesting talks, ate delicious food, and had some business meetings that I hope will give me many reasons to return to India in the future.
  • I sponsored PyData Tel Aviv in November, and also gave atalk about Marimo notebooks. Not only was this conference fun and interesting, but the organizers required that every speaker give a practice run of their talk two weeks before the conference took place. This was a huge boost to the quality of the talks, and I encourage every conference organizer to adopt this practice.

I also spoke at a number of online user groups, meetups, and regional conferences, including Python Ho (in Ghana) and the Marimo user community.

If you run a user group or conference, and would like to have me speak, please don’t hesitate to reach out!

I’ve already signed the contract to sponsor PyCon US 2026 in Long Beach, and I’ve submitted several talk and tutorial proposals. I hope to see you there!

Books

When I finished Pandas Workout last year, I wasn’t sure if I really wanted to write another book. So of course, I found myself working ontwobooks this year:

  • The second edition ofPython Workout, with 200 exercises to improve your Python fluency, is now out! It has been updated to include the latest versions of Python, as well as discussion of such tools as “uv”. Plus, I changed a few exercises with better, more appropriate ones. Thanks to everyone at Manning, my publisher, for the support in getting this over the finish line.
  • I’m currently writing a totally new book for O’Reilly, “AI-assisted Python for non-programmers.” The book, as the title indicates, introduces Python to people with little or no programming experience. The book doesn’t ask the AI to write code, but instead to provide you with challenges that improve on the exercises in the book. The book will be ready in October of 2026, but you can already see it in early release on the O’Reilly platform.

Newsletters

As you might know, I publish three weekly newsletters:

  • Better Developers, with a new Python article each week. I wrote 40 new issues this year, on topics ranging from argparse to uv.
  • Bamboo Weekly, with new Pandas puzzles every Wednesday and solutions every Thursday. I’m proud to say that I published BW every single week this year — 52 new sets of questions and solutions! I switched from Jupyter toMarimofor my BW notebooks, and share them with paid subscribers via the collaborative “Molab” system.
  • Trainer Weekly, about the career of being an independent trainer. I published 39 new issues this year.

This year, I published a new, free e-mail course about uv, called “uv crash course,” taken from some recent editions of Better Developers. You can check it out athttps://uvCrashCourse.com.

If you’re enjoying one or more of my newsletters, please tell others about them and encourage them to subscribe!

And if there are specific topics you would like me to cover? I’m always happy to hear from readers.

YouTube and social media

I’ve been especially active on YouTube this year, athttps://YouTube.com/reuvenlerner, with about 60 new videos published about Python, Pandas, Git, Jupyter, and Marimo.

My most recent addition is a newplaylist about Pandas 3. I’m adding new videos every day, and hope to get a good collection in place before Pandas 3 is released in the near future.

I also put the entire “Python for non-programmers” course (15 videos) and “Ace Python Interviews” course (50 videos) on my YouTube channel.

I’ve mainly been posting toBlueskyandLinkedIn, but I’ll often mirror postings to X (aka Twitter), Threads, and Fosstodon.

My blog has taken a back seat to other channels over the last few years, but I did find some reasons to post in 2025. Among my more interesting postings:

Podcasts

I believe that I only appeared on two podcasts this year — and both were episodes of Talk Python! I appeared on episode 503 in April, about PyArrow and Pandas (https://talkpython.fm/episodes/show/503/the-pyarrow-revolution), and more recently appeared on a panel discussion reviewing the year in Python news (https://www.youtube.com/watch?v=PfRCbeOrUd8) .

Several personal notes, and a request

The last two years have been difficult in Israel. I’m relieved that the war with Hamas (and related conflicts with Hezbollah, Yemen, and Iran) are largely over. And I hope that we can now work to bring about peace, prosperity, freedom, and coexistence between Israelis and our neighbors, most especially the Palestinians.

The missile alerts and attacks, which regularly woke us up for the better part of two years, and which caused untold death, injury, and destruction, were one of the more terrifying periods I’ve ever lived through. Of course, I know that things were also bad for many Palestinian civilians.

My family donates to Israeli organizations that promote the rule of law, democracy, religious pluralism, and peacemaking with our neighbors — and while it’s easy to give up hope that things will improve, I refuse to do so. We can and should try to make a difference in the world, even if it’s just a small one.

I appreciate the very large, warm outpouring of care and support that I received throughout the last two years from so many of you. It really means a lot.

Beyond Israel, I’ve been watching developments in the US with concern. In particular, it’s quite upsetting to see the wholescale destruction of science, engineering, and medical research in the US. As a regular consumer of US government data (for Bamboo Weekly), the degree to which that data is no longer considered the most reliable and nonpartisan in the world is a grave disappointment — and a professional frustration.

If you’re reading this, then the Trump administration’s policies have affected you, too: The Python Software Foundation recently turned down a $1.5 million grant for increased Python security. That’s because the grant required the PSF give up its efforts to make Python available to everyone, no matter who they are.

If you’ve gotten $100 of value out of Python in the last year, then I ask that youjoin the PSF as a paid member. If even 5 percent of Python users were to join the PSF, that would reduce or eliminate Python’s dependence on any one government or organization, and allow it to concentrate on its goals. Joining the PSF also give you the right to vote in annual elections, which means choosing the people who will set Python’s priorities over the coming years.

Thanks again for your subscriptions, support, friendly notes, and bug reports. I look forward to a new year of learning even more new things, of meeting more interesting, smart people, serving your learning needs, and to helping make our world just a bit friendlier, closer, and peaceful.

Best wishes for a great 2026!

Reuven

The postReuven’s 2025 in reviewappeared first onReuven Lerner.

https://lerner.co.il/2025/12/23/reuvens-2025-in-review/

Real Python: Reading User Input From the Keyboard With Python

You may often want to make your Python programs more interactive by responding dynamically to input from the user. Learning how to read user input from the keyboard unlocks exciting possibilities and can make your code far more useful.

The ability to gather input from the keyboard with Python allows you to build programs that can respond uniquely based on the preferences, decisions, or data provided by different users. By fetching input and assigning it to variables, your code can react to adjustable conditions rather than just executing static logic flows. This personalizes programs to individual users.

Theinput()function is the simplest way to get keyboard data from the user in Python. When called, it asks the user for input with a prompt that you specify, and it waits for the user to type a response and press theEnterkey before continuing. This response string is returned byinput()so you can save it to a variable or use it directly.

Using only Python, you can start building interactive programs that accept customizable data from the user right within the terminal. Taking user input is an essential skill that unlocks more dynamic Python coding and allows you to elevate simple scripts into personalized applications.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days.>> Click here to learn more and see examples]

https://realpython.com/courses/reading-user-input-from-keyboard/