> Autoformatting: Boon to readability. Not present by default

Is this not an IDE feature opposed to a language one? PyCharm does have auto-formatting (can be configured to run on save) and PEP8 lints.

> Complex API: Asking students to depend on pandas/numpy offline/online documentation is unthinkable

> Library cognitive overload: pandas and numpy are basically DSLs, each with their own programming paradigm

There's maybe some complexity inherent in vectorized manipulation of many-dimensional tensors, but I'm not aware of many languages/libraries that handle this more naturally than Python with NumPy does; maybe MatLab? Would be interested to see code sample comparisons on this.

Once you've learned NumPy though, the same API can be used across PyTorch, TensorFlow, CuPy, Numba, JAX, etc. which is very handy.

> No user types [...] One must depend on the dict and list types [...]

The author may have criticisms of (data)classes, but it can't be claimed that they don't exist.

> There are 7 ways of calling the open function [in Python, ... Python's documentation] has a table of characters to denote different ways of formulating a very important argument to open. For context on why this is "complex": compare this with Go's approach [... where] the documentation does not exceed a paragraph.

Assuming 7 ways refers to the mode argument, these are: read, write (truncating), append, create, update (read + write), text, and binary (https://i.imgur.com/Aavl6uJ.png). Not really anything particularly scary or obscure.

It's true that the Go documentation is shorter here, but that's because it just says "It opens the named file with specified flag (O_RDONLY etc.)", and doesn't even link to the available list, which is: O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, O_CREATE, O_EXCL, O_SYNC, O_TRUNC - similar to Python.

> Due to this inconsistency in the language, it is dangerous to teach indexing as it exists in the world since this would mean students slip up

Python ranges are consistently inclusive of the start and exclusive of the end (i.e. [0, 5) is [0, 1, 2, 3, 4]). May not match some people's mental model, but it is consistent within itself as far as I'm aware.

> Python has "global" variables (module level variables) and global (when using keyword) variables

The `global x` keyword within a function is just to indicate the function will assign to the (pre-existing) global `x` variable. i.e.:

x = 1
def count_up():
global x
x += 1

> A module-level variable is "read-only" when it's not a primitive type (string, int, float)

I'm not sure what the author means by this. Trivially you can do something like:

g_list = []
g_list.append("foo")

> Looping: `for`, `while`, `enumerate`, `range`, `zip`, etc. Just so many ways to do the same thing.

> While vs. for. Having two distinct keywords for doing the same thing (iterating)

Python having just `for` and `while` for loop statements is relatively frugal - those are ubiquitous in pretty much all imperative programming languages, often alongside `do while` and `foreach` (well, really it's the regular C-style `for` that Python does not have).

The functions `enumerate()`, `range()` and `zip()` are again all common in some form or another, because they serve useful and distinct purposes.

-----

I think one thing that makes Python a useful teaching language is ability to progressively introduce concepts. You don't want a language that forces frontloading many concepts before being able to get going, but you do want those features available when the time comes to demonstrate them.

For instance, in my opinion lack of inheritance is a good design decision on Go/Rust's part and makes them a better language, but not necessarily a better pedagogical tool - because inheritance is still present in many other popular languages and so needs teaching at some point.