Friday, 31 July 2026

Understanding HTTP State Management

HTTP state management is covered in RFC6265.  

Python's request module however refers to its predecessor RFC2965 within the class DefaultCookiePolicy in cookiejar.py. Some programmers say the implementation is quite strict.

One difference in the RFCs is the use of Augmented Backus-Naur form (ABNF) in the latter, not used in the former. ABNF for specifications is formalised in RFC5234 (an Internet standard, proposed to be augmented by RFC7405).

Understanding HTTP Redirects

Introduction

If you want to program an HTTP request module (to make HTTP requests, to download web pages, or other data) there are a number of relevant concepts relating to HTTP that you must understand.

One of these concepts is HTTP redirects. What are they, why do they exist, and what a "reasonable" number of redirects looks like when sending an HTTP request to a server.

What is a redirect - technically speaking?

First the technical part. HTTP redirects occur when a server responds to a client request with the reply 3XX (status code). This is coupled with a location header of the URL it wants the client to load instead.

The browser or other HTTP client (which could be a Python program, for example) then follows the redirect, issuing a new request to the URL in the location header.

Why are they needed?

Examples:
301 Permanent redirect - e.g. for site reorganization, domain migration, SEO link preservation
Also temporary redirects - e.g. for load balancing
HTTP to HTTPS redirect

Redirects can be configure in Apache .htaccess and in nginx.

Pythons requests module allows by default 30 redirects.

PyCharm

PyCharm is an IDE for Python development from JetBrains. Copilot recommends this for large projects.

However to connect to WSL projects you need to have the JetBrains gateway installed.

Know your requirements well to understand if you really need such an overwhelming IDE.

Epigrams on Programming by Perlis: Seek Symmetry Everywhere

The echo of Alan Perlis' insights reverberate in computer science departments around the world, and immortalised in Epigrams on Programming, which he published in 1982. Here is a selection of his well-known aphorisms.

One man's constant is another man's variable.

Everything should be built top-down, except the first time.

Functions delay binding; data structures induce binding. Moral: structure data late in the programming process.

Syntactic sugar causes cancer of the semicolon.

If a program manipulates a large amount of data, it does so in a small number of ways.

Symmetry is a complexity-reducing concept (co-routines include subroutines); seek it everywhere.

A programming language is low level when its programs require attention to the irrelevant.

It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.

Get into a rut early: Do the same process the same way. Accumulate idioms. Standardize. The only difference (!) between Shakespeare and you was the size of his idiom list - not the size of his vocabulary.

If you have a procedure with 10 parameters, you probably missed some.

Recursion is the root of computation since it trades description for time.

If two people write exactly the same program, each should be put into microcode and then they certainly won't be the same.

In the long run every program becomes rococo - then rubble.

Every program has (at least) two purposes: the one for which it was written, and another for which it wasn't.

A language that doesn't affect the way you think about programming, is not worth knowing.

Wherever there is modularity there is potential for misunderstanding: Hiding information implies a need to check communication.

Optimization hinders evolution.

A good system can't have a weak command language.

To understand a program you must become both the machine and the program.

One can only display complex information in the mind. Like seeing, movement or flow or alteration of view is more important than the static picture, no matter how lovely.

Once you understand how to write a program get someone else to write it.

Around computers it is difficult to find the correct unit of time to measure progress. Some cathedrals took a century to complete. Can you imagine the grandeur and scope of a program that would take as long?

In programming, everything we do is a special case of something more general - and often we know it too quickly.

Simplicity does not precede complexity, but follows it.

Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis.

Everyone can be taught to sculpt: Michelangelo would have to be taught not to. So it is with great programmers.

The most important computer is the one that rages in our skulls and ever seeks that satisfactory external emulator. The standardization of real computers would be a disaster - and so it probably won't happen.

Some programming languages manage to absorb change, but withstand progress.

There are two ways to write error-free programs; only the third one works.

In software systems it is often the early bird that makes the worm.

Sometimes I think the only universal in the computing field is the fetch-execute cycle.

The goal of computation is the emulation of our synthetic abilities, not the understanding of our analytic ones.

Like punning, progamming is a play on words.

As Will Rogers would have said, "There is no such thing as a free variable".

Giving up on assembly language was the apple in our Garden of Eden.

When we understand knowledge-based systems it will be as before - except our fingertips will have been singed.

A LISP programmer knowns the value of everything, but the cost of nothing.

Software is under a constant tension. Being symbolic it is arbitrarily perfectible; but also it is arbitrarily changeable.

It is easier to change the specification to fit the program than vice versa. 

In seeking the unattainable, simplicity only gets in the way.

In programming, as in everything else, to be in error is to be reborn.

When we write programs that "learn", it turns out that we do and they don't.

Often it is the means that justify the ends: Goals advance technique and technique survives even when goal structures crumble.

Is it possible that software is not like anything else, that it is meant to be discarded: that the whole point is to see it as a soap bubble?

Because of its vitality, the computing field is always in desperate need of new cliches: Banality soothes our nervers.

Prolonged contact with the computer turns mathematicians into clerks and vice versa.

In computing, turning the obvious into the useful is a living definition of the word frustration.
We are on the verge: Today our program proved Fermat's next-to-last theorem.

Motto for a reseach laboratory: What we work on today, others will first think of tomorrow.

Computation has made the tree flower.

The computer is the ultimate polluter : its feces are indistinguishable from the food it produces.

When someone says "I want a programming language in which I need only say what I wish done," give him a lollipop.

Interfaces keep things tidy, but don't accelerate growth: Functions do.

Don't have good ideas if you aren't willing to be responsible for them.

Computers don't introduce order anywhere as much as they expose opportunities.

In man-machine symbiosis, it is man who must adjust: The machines can't.

The proof of a system's value is its existence.

You can't communicate complexity, only an awareness of it.

Within a computer natural language is unnatural.

Most people find the concept of programming obvious, but the doing impossible.

#116

Use of Mathematical Induction in Proofs of Program Correctness

Robert Floyd introduced MI as a systematic method to prove the correctness of computer programs in his 1967 paper "Assigning Meanings to Programs", written at the then Carnegie Institute of Technology, supported by DARPA.

This directly inspired Tony Hoare's axiomatic semantics and the development of Hoare logic (also known as Floyd-Hoare logic).

Floyd acknowledges gestation of these ideas by Perlis and Gorm, albeit in unpublished papers.

Thursday, 30 July 2026

Mathematics in VS Code with Lean

Formalizing mathematics is now possible in VS Code with Lean. See the manual here. Extension here.

Lean functionality is exposed in the UI via the universal quantifier at the top right of VS code.

Consider copying the MIL folder, containing key examples, so you can tinker with the example code.

MIL = Mathematics in Lean.

When you download the MIL, you will see a flurry of activity in your Output Console in VS Code. This will include reams of stuff relating to "Fetching Mathlib build artifact cache" and thousands of file downloads.

You will also see the incantation "lake build" which is the primary build command in the Lean build system.

Advice on how to work through the MIL textbook from the official website - "working through the exercises is central to the experience".

Note: when reading Lean files in VS code turn off Unicode character highlighting (Control-, to get into settings, and update Text Editor settings).

kdb+ - An Intro

kdb+ is a high-performance time series database and analytics engine powered by a vector language q. It has been in existence for over 30 years.

It uses columnar storage for efficient querying. For example, if you have temperature readings, taken at 5 minute intervals, you can pull out the whole vector of temperatures in a single query (you are pulling the full time series vector as opposed to a reading from a time series).

If you have corresponding humidity readings, you can do a similar query.

This avoids reading entire rows even if only one field is needed. Typical relational databases query cross-sectionally.

Wednesday, 29 July 2026

Open Source - and Goldman Sachs??

Goldman Sachs has open sourced some of its code.

The Lean FRO Year 3 Roadmap

Changes to Lean - as articulated by Lean FRO's Y3 roadmap.  

Some items will for sure be done, some may be pushed to Y4.

All roadmap content can be found here.

While we are there, let's say thank you to the Lean Team.

The Draw Tab in Word

The Draw tab in the Word ribbon is a great feature - but it may be turned off by default.

To turn it on do the following:

1.    File
2.   Options
3.   Customize Ribbon
4.   Select Draw

This will enable you to use a freeform marker in your Word doc.

Theorem Proving in Lean - What Makes Dependent Type Theory Dependent?

This precis is based on the Lean Manual, Section 2.8.

Tuesday, 28 July 2026

Zulip

Zulip is an open source chat platform to help distributed teams communicate effectively. The Lean community used Zulip to collaborate.

Lean Ecosystem Decoded

elan - package manager for Lean. elan can be used inside VS code and will manage all versions of Lean on your system

Lake - the standard project structure and build system used in Lean

mathlib4 - the math library for LEAN

mathlib4 can be found here. It contains both programmatic infrastructure and mathematics.

Friday, 24 July 2026

Theorem Proving in Lean - Basics of Dependent Type Theory

The master guide is here.

DTT and its Specific Variant for Lean

Dependent type theory (DTT) allows you to express complex mathematical assertions and reason about them in a "natural and uniform" way. 

Lean is based on a version of DTT called the Calculus of Constructions, with a "countable hierarchy of non-cumulative inverses and inductive types". This sounds complex. 

The following section explains this.

First, let's talk Simple Type Theory

In "type theory" every expression has a specific type. e.g. the expression x+0 may denote a natural number in a specific context. In another context, it may be a floating point number, of a particular precision.

In Lean, a natural number is an arbitrary precision unsigned integer.

Our use of the arbitrary precision (unsigned) integer, reflects the unnatural way of thinking about counting numbers from a computing perspective. In computing, we think of the object, but also the memory it occupies - so we speak of 16 bit integers, 32 bit integers and so on - a nod to the physical limitations of computers. n-bit integers where n is not predefined underlies this concept of arbitrary precision.

An arbitrary-precision integer can grow to any number of bits, limited only by available memory. 

This differs from so-called fixed-width integers (8-, 32-, 64- bit).  

A variable-length array of digits/bits are used so it can represent arbitrarily large integers without overflow. (Analogies include - BigInt in Java, or System.Numerics.BigInteger in C#).

Defining Contants in Lean with the def keyword

Let's define some constants in Lean.

/- Define some constants. -/
def  m:  Nat := 1   --m is a natural number
def  n :  Nat := 0
def  b1: Bool := true  --b1 is a Boolean
def  b2: Bool := false

Now check their types using: #check m;  #check n; #check n+0 etc. You can also run some "evals" in Lean: #eval  5*4; #eval m+2 etc.

The def keyword introduces new constant symbols to the working environment. The #check command asks Lean to report their types. The #eval command asks Lean to evaluate the given expression.

Composing New Types from Existing Ones

What makes simple type theory powerful is you can build new types out of others.

For example, if a and b are types, a->b denote the type of functions from a to b, a × b denotes the type of pairs consisting of an element of type a and element of type b.

Note on use of Unicode: (From the Lean Manual): "The judicious use of Unicode improves legibility, and all modern editors have great support for it. In the Lean standard library, you often see Greek letters to denote types, and the Unicode symbol → as a more compact version of ->."

Theorem Proving in Lean - Three Definitions to Get Started

This is an abridged account of Theorem Proving in Lean capturing only the SSPs, or super salient points.

Here are some three starting definitions essential for understanding this topic:

Formal verification - using logical and computational methods to establish claims that are expressed in precise mathematical terms. Example claims - mathematical theorem /hypothesis, claims that pieces of hardware or software, network protocols, security protocols - do what they say they actually do.  The process is "describe your system in mathematical terms" ,then use "theorem proving" to establish truth.

Automated theorem proving - focused on "finding". The "ATP" toolkit includes: resolution theorem provers, tableau theorem provers, fast satisfiability solvers to provide means of establishing validity of formulas in propositional and first-order logic.  Computer algebra systems may be used in concert to carry out mathematical computations.  

Automated reasoning - differs; not as "cast iron" as theorem proving. Automated reasoning is a superset of automated theorem proving, which includes imprecise techniques such as heuristic search and fuzzy logic.





Thursday, 23 July 2026

The Lean Programming Language

The Lean Programming language is being used to create a new proof of Fermat's Last Theorem. Some lecture notes from London's Imperial College set the scene.

Theoretical Foundation (DTT)

Dependent type theory (DTT) is the theoretical foundation of Lean (the link provided takes you into the Lean manual and gives a brief intro to the theory) which bears "categorical semantics".

Getting Started with Lean

Who created Lean

Lean was created by Brazilian computer scientist Leonardo de Moura, in 2013, when he worked in Microsoft Research (where he worked for 16 years). 

Leonardo is now Senior Principal Applied Scientist at AWS, where he works in the Automated Reasoning Group.  This group does a lot of work in Provable Security and Software Assurance.

Lean is available under the Apache 2.0 license.

ngrams, ngrams everywhere

An n-gram is a continuous sequence of n items - words, letters or symbols - from text or speech, used to analyze patterns and predict sequences in language.

Suppose we choose the items of our n-gram as "words". We then have the following taxonomy:

  • unigram - consisting of a single word e.g. design
  • bigram - consisting of two words e.g. design experiments
  • trigram - e.g. design of experiments
Google has a great ngram viewer to see the frequency of certain ngrams in books throughout the ages.

Wednesday, 22 July 2026

mTLS - building machine to machine trust

What is mTLS? 

mTLS is also known as mutual TLS, after the ubiquitous security protocol. It is used in environments where machine-to-machine trust really matters.

Where in general is mTLS used? Where specifically is mTLS used? Did someone say "Kubernetes service mesh"? I think so! 

It's not generally used for public websites, but inside serious enterprise systems, it's a standard way to guarantee only authenticated services speak to each other.

Examples in modern infrastructure include: Kubernetes service meshes (Istio, Linkerd), API gateways, internal microservices, banking and trading and zero-trust networks.

Is mTLS a standard?

It's a section in TLS standard.

Root Certificates

In cryptography, a root certificate is a public key certificate that identifies a root certificate authority (CA).

Examples of certificate authorities (CAs) include SwissSign.

Root certificates are self-signed and forms the basis of an X.509-based public key infrastructure (PKI). Recall the X.509 is the ITU standard for defining the format of a public key certificate.

Worth reading also is RFC5280 which covers X.509 certificates and CRLs (certificate revocation lists).

Certificate Validation with Certifi in Python

The Python certifi package provides Mozilla's "carefully curated collection" of Root Certificates to validate the trustworthiness of SSL certificates while verifying the identify of TLS hosts. 

It has been extracted from the Requests project.

Monday, 20 July 2026

Parity between Azure and AWS

It is worthwhile to maintain knowledge parity between Azure and AWS. 

If you use a cool thing in Azure, chances are the same functionality exists in AWS (e.g. managed kubernetes service - known as AKS or EKS in respective clouds) and so you should know how to do same cool thing in AWS.

Cloud economics may dictate future decisions.

A Nod to AWS EKS

AWS EKS (Elastic Kubernetes Service) is a fully managed Kubernetes service provided by AWS. 

EKS simplifies deployment and management of containerized applications using Kubernetes. Users need not manage the Kubernetes control plane or nodes manually.

Jargon warning: 

The Kubernetes control plane is the central management utility of a Kubernetes cluster. 

It maintains cluster state, making decisions about the cluster and responding to cluster events. It is made up of several key components that work together.

AWS basically runs the control plane for you.

There are a number of use cases suggested by AWS.

Copliot Studio and Cost Analysis

Copilot Studio is a Microsoft product for building and managing AI agents. 

It has a corresponding licensing guide enabling you to estimate costs of building and running agents with it. At time of writing the licensing guide has been updated in July 2026.

Saturday, 18 July 2026

Revisiting Port 443

Port 443 is primarily known for handling HTTPS traffic over TCP, enabling secure communication between browsers and servers.  

It can be used with UDP in specific scenarios like QUIC (for lower latency secure communications) and HTTP/3.

When diagnosing why an HTTPS connection is failing, an in depth knowledge of port 443 is needed.






Visual Studio Community July 2026 Release

See the status of GitHub Copilot from the Visual Studio IDE. Built-in .NET and Azure skills are introduced.

Agent Skills Introduced by Anthropic

Anthropic introduced agent skills which have now been embraced by other vendors too e.g. Microsoft.

Agent skills are a standardized way to extend agent capabilities with specialized knowledge and workflows.  It consists of a folder containing a SKILL.md file.  This contains metadata and instructions for the agent to do its task.

Other stuff can be bundled with the skill as well, as follows.

agents-new-skill/ ├── SKILL.md # Required: metadata + instructions ├── scripts/ # Optional: executable code ├── references/ # Optional: documentation ├── assets/ # Optional: templates, resources └── ... # Any additional files or directories

The PEM Format

PEM (Privacy Enhanced Mail) is a format used for transmitting cryptographic keys, certificates and other data.  

PEM structure consists of a text file in Base64 encoded data format (a binary-to-text encoding consisting of 64 printable characters - the idea is you can push binary data into a communication channel that only supports text). Base64 is famous for its use in attachments, since SMTP in its original form was designed to support 7-bit ASCII characters only.

An alternative to PEM in Java contexts is DER (Distinguished Encoding Rules) used for X.509 certificates and private keys.

Busting Certificate Issues in Ubuntu

Suppose you are running a data pipeline on Linux/Ubuntu that consumes data from the web. You get a RuntimeError: "SSL certificate verification failed".  What do you investigate?

Verifying the ca-certificates package and updating /etc/ssl/certs

 sudo apt-get install -y ca-certificates

installs the ca-certificates package (the -y means "say yes to all prompts").

This software processes certificates in PEM format.

With this installed, new certificates can be added to /usr/local/share/ca-certificates.  

The trust store can then be updated with:

sudo update-ca-certificates

You can then check if the certificate has been added.

ls /etc/ssl/certs | grep local-ca



Programming as Play

Shade Zahrai has noted that "play changes your brain". 

Stress drops (cortisol down, dopamine up) when something feels low-stakes and playful.

Daily light-hearted play can train your brain to get comfortable with taking risks, exploring and trying new stuff. It builds a sense of agency, a belief that action can make a difference.  

This concept is also explored in the context of programming specifically in an article on "Hunting the Wiley Hacker" which covers the joy of Linux.

Friday, 17 July 2026

A Scorecard for the AI Age

Is a very nice article by Sarah Friar, CFO of OpenAI, on measuring value from AI.  But how to measure "AI", or do we create measures across every AI vendor/model pair to work out value per segment?

More on Data Validation in Pydantic

Pydantic Validation is the validation layer of the OpenAI SDK, the Google ADK, the Anthropic SDK, LangChain and others.

Pydantic uses Rust under the hood. This makes it faster than say, something implemented directly in Python.

How are the Python and Rust pieces glued together?

The key is that the validation layer is compiled in Rust (pydantic-core).  Data parsing, validation and in general, any perf-critical operations, are done here. Py03 is used to create bindings in Python.

While there is no need to use the Rust code directly, for reference it can be found in GitHub here.

But what does this validation actually entail?  What's the use case?

How does it work?

Type hints (PEP 484) are one of the tools used in Python validation (GvR himself h as co-authored that PEP).  Type hints enable integration with various static typing tools (like mypy) and IDEs (like VSCode).

The Type hints PEP also references PEP 3107 for function annotations (written by Collin Winter and Tony Lownds).

Classical Reinforcement Learning and the Reward Signal

As a prelim to understanding RLHF, it pays to understand classical reinforcement learning, which has been studied under many different guises within computer science and more traditional engineering.

This is concerned with how an agent should take actions in a dynamic environment in order to maximise a reward signal.




Back to LLM Basics - What is RLHF

RLHF is a core part of how large language models learn. 

It stands for reinforcement learning with human feedback.  Idea is you train models to align with human preferences.

A core input is data from human annotators as an input into the learning process.

The algorithm now widely used in RLHF was pioneered by OpenAI (InstructGPT). The idea is you align the model with human intent. Alignment with human intent is what makes the model (more) useful.

Tuesday, 14 July 2026

Document Intelligence Infrastructure

Article covers GraphRAG and an agentic approach as a path to document intelligence,

GPT-5.6 Sol - Preview

Sol is OpenAI's strongest model yet.

It has a robust safety stack, including protections for higher-risk activity and repeated misuse.

A limited preview is being done with trusted partners first.

Sunday, 12 July 2026

Codex is now the ChatGPT App

Inside the app it says "Powered by Codex and OWL". Codex is the coding agent, OWL is the Chromium-based environment that provides the "runtime shell" for Codex.

OpenCV in Python

pip install opencv-python

More on OpenCV on opencv.org.

Saturday, 11 July 2026

Reverse Debugging

Not all debuggers are created equal. Some allow reverse debugging, some do not.

gdb does
pdb does not

pdb is a forward only debugger. Once a statement runs, its side-effects (e.g. variable changes, I/O etc.) are permanent unless you restart.

History of .NET Core

The evolution of ideas is something very interesting. In this respect, the evolution of ideas within .NET Core is worth reflecting on. This article from June 2019 mentions Maestro, which deals with one specific challenge in the development of .NET Core.

The Debugger Class in .NET

The Debugger class in System.Diagnostics is implemented in Debugger.cs.  Its purpose is to allow communication with the debugger.

This is the class that lets you do a "hard debug" but typing Debugger.Break(), which signals a breakpoint to an attached debugger.

Debugger.Launch() is similarly aggresive. It launches and attaches to a debugger to the process.


Friday, 10 July 2026

Python Debugging: "SSL Certificate Verification Failed"

Ever seen this:

RuntimeError: Failed to fetch (insert_dataset_of_choice) data: SSL Certificate Verification Failed

This may happen in code that was previoulsy working. It can be caused by outdated or missing CA certificates. 

AI - New Ideas Every Day

There are literally new ideas every day in AI. Every day.

New commercial R&D, published and waiting to be read, every day.

GitHub's Agentic Workflows in the Crosshairs of GitLost

Noma Security has publicised GitLost, a technique to get GitHub Agentic Workflows to spill private repository data.

The exploit is aimed at organizations with both public and private GitHub repositories, and relies on prompt injection.

Specifically, it uses indirect prompt injection  where malicious instructions are injected into seemingly regular requests.

GitHub's Agentic Workflows introduce LLMs into GitHub Actions, which is how the exploit is enabled.

Anthropic's Interpretability Research

This is journalled here. The goal is to understand how LLMs actually work internally.

Claude's "Access Consciousness"& Rise of the "J-Space"

Anthropic's Claude model series has claimed "access consciousness" via the J-Space.

The Claim of the "J Space"; And the Parallel with Global Workspace Theory of Neuroscience

This claim has been presented as "A global workspace in language models" described at a high level here, and deep-dived in the paper  Verbalizable Representations Form a Global Workspace in Language Models (July 6, 2026, Wes Gurnee, Nicholas Sonofriew, Jack Lindsey et al). 

From the paper - it is clear that the analysis identifies "data structures of the mind" - where we replace with "mind" with "model" to get a window in on the model's thinking:

"we observe that language models maintain a privileged set of internal representations, available for report, modulation, and flexible internal reasoning, atop a much larger volume of automatic processing. We identify these representations using a new interpretability technique, which surfaces the concepts a model is poised to verbalize at any point in its processing".

What is interesting is the discovery of this so-called "J-Space" but also the interpretability technique. It offers a new way to "commune" with LLMs.

The phenomenon of "access consciousness" is described in the paper, a concept from behavioural and brain science. This is introduced as a purely functional notion - it's purported purpose is utilitarian, and not linked to subjective experience (sometimes called phenomenal consciousness).

Neuroscience has a global workspace theory where a "data structure" can be posted to the brain's "working set area" for use in reasoning and reporting.

The Evidence

The paper poses the question whether functional properties of a global workspace have emerged in LLMs.  It portrays the LLM's thinking as a plethora of vector representations, some constituting low-level bookkeeping and some embodying higher level ideas like "Golden Gate Bridge" or even emotions.  If such a workspace were to exist, we would expect a subtset of vectors to be prominently and preferentially present in the LLM's memory.

The Test for Presence

Verbal report - when asked what it is thinking about, LLM names concepts from its workspace




Thursday, 9 July 2026

What is Pylance?

Pylance is the component that enables Visual Studio Code to provide IntelliSense for Python. 

It is underpinned by Microsoft's Pyright type checker (open source static type checker for Python). Read more about Pyright from the official website.

Wednesday, 8 July 2026

Navigating OpenClaw Architecture

The best place to start is by reading architecture.md in the docs/concepts subdirectory.

Then move on to the other concepts (not all equally weighted in importance) than read the source code.

Tuesday, 7 July 2026

Data Rates Rule...OK!

So git clone is busy "Receiving objects" but it's taking time...what data rate is underlying this operation?

Data rates are measured using a variety of standardised conventions.  

They are usually multiples of bits per second (bit/s) or bytes per second (B/s).  bit and Byte are ISQ symbols (International System of Quantities).

Residential Internet speeds are often measured in Megabits per second (Mbit/s - often abbreviated Mbps - as you will see in the Windows Network Speed Test application).  1 Mbps is 1000 kilo bits per second, or 1000 kbit/s or 1000 kbps).

There is also the Mibit/s convention - which stands for mebibits per second (or MiB/s).

This is 2^20 bits per second, or 1,048,576. Just over a million bits per second, basically.

External Dependencies Are the Root of All Evil

Open source software is great except when it isn't.

Update all the dependencies for a new cool software and older software (using older versions of those co-dependencies) suddenly breaks.  

In Windows, we used to call it "DLL Hell" but it has its manifestations in Linux too.

Then it's a cycle of repair and debugging.

Debugging Python - Module Versions

You may get errors in Python programs when you update external module dependencies, as the newer versions may have added some breaking changes - e.g. stronger validation or security checks. 

You can validate the version of the module you are using if __version__ is exposed by the module. To do this, try the following, using the module name required (urllib3 used here as an example):

python
import urllib3
print( urllib3.__version___)