An argument for learning Python, programming, and how to think like a programmer in the age of artificial intelligence
We have reached an interesting point in the history of computing.
For approximately seventy years, we have been teaching human beings to write increasingly elaborate instructions for machines. We invented programming languages, argued about them, built entire professions around knowing the difference between one and another, and occasionally came to blows over whether a curly brace belonged at the end of a line or on the next one.
Now we have machines that can write those instructions themselves.
Not just little ones, either. You can ask an artificial intelligence to build a web application, analyze a database, convert a spreadsheet into something useful, or write a Python program that would have taken a competent developer most of an afternoon. Sometimes it will do it in thirty seconds. Sometimes it will even work.
And the obvious question, the one that ought to be asked by anyone contemplating spending the next several months learning to program, is this:
Why the fuck should I bother?
It’s a reasonable question. In fact, it’s a considerably more reasonable question than most of the ones people have been asking about artificial intelligence lately.
If a machine can write code faster than you can, knows more programming languages than you will ever learn, and doesn’t need coffee breaks, sick leave, or a therapist after a six-hour meeting about changing the color of a button, why invest the effort?
Why learn Python when you can just tell an AI what you want?
I have an answer.
But first, I want to concede something.
The machines are getting very, very good.
I’m not going to insult your intelligence by claiming that artificial intelligence is merely a glorified autocomplete, or that it will never understand the subtle artistry involved in persuading a computer to do something useful. A sufficiently capable AI can write, inspect, test, and revise software. It can navigate documentation that would take a human weeks to digest. It can recognize patterns across programming languages and libraries that no single programmer has ever had reason to study.
There are still things humans do better, particularly when projects become large, messy, poorly documented, or dependent on knowing what the organization actually intended. But I wouldn’t recommend betting your career on the assumption that those particular advantages will last forever.
For the sake of argument, let’s suppose the machines win.
Let’s suppose that, five or ten years from now, an AI really can produce better code than any human programmer, faster, cheaper, and with fewer defects.
Would learning to program become pointless?
No.
Because writing code was never the most important part of programming.
It was merely the part you could see.
Consider an ordinary business problem.
A company has a few hundred customers, thousands of invoices, and an accounting system that was installed before some of its employees were born. Management wants a report identifying which customers should have their accounts frozen for nonpayment.
Simple enough.
An invoice becomes seriously overdue after 120 days. If a customer has even one invoice in that category, the customer gets flagged. Management also wants to know which customers owe more than $100,000 in total, regardless of how old the individual invoices are.
Now hand that assignment to an AI.
It might write you an excellent Python program. It might use pandas, connect to the database, group the invoices by customer, calculate the aging buckets, and produce a handsome dashboard featuring several shades of corporate blue that nobody actually requested.
It might even include a little red icon next to customers whose accounts ought to be frozen.
Lovely.
Except you haven’t told it whether the aging calculation uses the invoice date or the due date.
You haven’t explained whether unapplied payments count against the balance.
You haven’t mentioned that the accounting system already maintains an account-freeze flag, somewhere, in a table nobody can find because the vendor documentation was evidently written by a man who died in 1998.
And perhaps most importantly, you haven’t said whether a customer with $110,000 in outstanding invoices and $20,000 in credits should be treated as owing $110,000 or $90,000.
The AI can make assumptions. It can ask questions. A good one will probably ask several.
But somebody still has to answer them.
And somebody has to recognize when the questions themselves are wrong.
This is programming.
Not the Python. Not the database connection. Not the delightful little red icon.
The act of converting a vague human desire into a precise description of what must happen, under what circumstances, and why.
People have been doing that since long before electronic computers existed. Civil engineers do it when designing bridges. Accountants do it when reconciling books. Machinists do it when translating a drawing into something that can actually be manufactured. An architect must understand the distinction between a room that looks delightful on paper and one whose ceiling will remain attached to the building.
The programmer’s particular contribution was learning to express these intentions in a form so unambiguous that a machine could execute them.
That’s a valuable skill even when the machine does the translating.
Especially then.
Because the faster a machine can produce an answer, the faster it can produce the wrong answer.
And unlike a human employee, who might eventually become suspicious after manually processing four hundred invoices that all seem to belong to the same dead customer, an automated system can cheerfully process four million of them before lunch.
Computers have always been exceptionally good at making mistakes at scale.
Artificial intelligence has merely given them a more conversational way of getting started.
There is a distinction I want you to understand.
Knowing how to write code is not the same thing as knowing how to program.
For much of the industry’s history, the two were effectively inseparable.
If you wanted to make a computer do something, you had to learn a language the computer could understand. You needed to know about variables, functions, loops, conditions, and data structures. You had to understand why a piece of text that looked like a number was not necessarily a number, why dates are among the nastiest little bastards in software development, and why the computer insisted that a file which was plainly sitting right there did not exist.
You also had to learn the punctuation.
God help you, the punctuation.
Entire careers have been spent discovering that somebody put a comma where a semicolon belonged, or forgot a closing parenthesis, or used a variable named `customer` in one place and `customers` in another.
Python became popular partly because it dispensed with some of this ceremonial nonsense.
It looks reasonably close to ordinary written instructions. Its syntax is comparatively clean. It has libraries for working with files, databases, websites, statistics, scientific instruments, and approximately every variety of human foolishness that can be represented as data.
It is not perfect. No programming language is. A Python programmer can still spend a perfectly miserable afternoon discovering that a function returned `None` when everyone involved had rather hoped for something else.
But Python is an unusually good language for learning how programs are constructed.
And that, rather than memorizing its syntax, is the reason I think you should learn it.
Let’s return to those invoices.
Suppose I tell you that a customer must be flagged if any invoice is more than 120 days old.
What does `any` mean?
It means that finding one qualifying invoice is enough. The other invoices don’t matter for that particular decision.
Now suppose I tell you that another flag must be applied if the customer’s total outstanding balance exceeds $100,000.
What does `total` mean?
It means that every qualifying balance must be included, not merely the largest invoice, or the invoices in the oldest aging bucket.
We’ve just described two different computational operations.
One asks whether a condition is true for at least one member of a collection. The other aggregates values across the collection and compares the result with a threshold.
You can express both operations in Python. You can express them in SQL, JavaScript, C#, or a dozen other languages. You can probably persuade an AI to implement them before you’ve finished your coffee.
But first you have to understand that they are different operations.
And you have to recognize the error if the AI decides, for reasons known only to itself, that a customer with three overdue invoices should be frozen only if all three are more than 120 days old.
That’s a perfectly plausible mistake.
It’s also the sort of mistake that can cost a company a great deal of money while producing a report that looks entirely professional.
The crucial skill is knowing enough about programming to say, “No, that’s wrong, and here is a case that proves it.”
Consider a customer with one invoice that’s 130 days old and another that’s only five days old.
Should the customer be frozen?
Yes.
If the program says no, the program is wrong.
You don’t need to type a single line of Python to construct that test.
But understanding programming helps you recognize that the test is necessary, that it isolates a particular rule, and that the result must be checked independently of the code that produced it.
This last point is important.
If you ask an AI to write a program, and then ask the same AI whether its program is correct, you haven’t necessarily conducted an independent review.
You may have merely persuaded your original suspect to write the police report.
Now, you might reasonably object that future artificial intelligence will be sophisticated enough to handle all of this.
It will interview stakeholders, clarify requirements, construct test cases, identify ambiguities, and investigate the accounting system. It will discover the hidden freeze flag. It will even notice that the customer identifiers changed formats after a merger in 2017, which is more than the last three contractors managed.
Fine.
Let’s grant it all of that.
Who decides what the company is trying to accomplish?
Who decides whether freezing a customer’s account is an appropriate response to a disputed invoice?
Who decides whether a report should include medical records, personal addresses, or other information the people reading it have no legitimate reason to possess?
Who decides whether the system should be allowed to change the accounting database, or whether it should only report what it finds?
And who is responsible when the system does something nobody intended?
These are not questions of typing speed.
They are questions of authority, judgment, responsibility, and consequences.
You can automate a decision process. You can delegate it. You can even construct a system that identifies and resolves many of its own ambiguities.
But automation doesn’t make the consequences disappear.
It merely changes who must understand them.
Imagine being offered a powerful new piece of industrial equipment.
The manufacturer assures you that it can operate autonomously, detect obstructions, compensate for mistakes, and outperform the best human operator.
Very impressive.
Would you like it installed in your basement?
Before answering, you might want to know what the machine does, what it’s connected to, whether it has an emergency stop, and precisely what happens if somebody presses the wrong button.
If it turns out to be a refrigerator, perhaps we’re being overly cautious.
If it turns out to be a machine that excavates foundations, I’d suggest taking a closer look at the basement walls.
Artificial intelligence makes software extraordinarily cheap to produce.
It does not make software harmless.
In fact, by reducing the cost of creating complex systems, it makes it easier for people who have no idea what they’re doing to create systems with consequences they don’t understand.
We’ve already spent decades proving that this is possible without artificial intelligence.
I have considerable confidence in humanity’s ability to make it worse.
There’s another reason to learn programming, and this one has less to do with employment than with independence.
Computers increasingly mediate almost every part of ordinary life.
Your money moves through software. Your medical records live in software. Your employer evaluates your performance using software. Your government decides whether you qualify for services using software. Your photographs, correspondence, personal history, and increasingly your very ability to establish your identity are stored in systems you do not control.
Most people interact with these systems through interfaces designed to show them only what the institution wants them to see.
A button. A form. A dashboard. A pleasant little message explaining that your request could not be processed at this time.
Have you ever encountered a website that insists some obviously correct information is invalid?
Of course you have.
Perhaps it demands a telephone number in a format that doesn’t accommodate your country. Perhaps it refuses your name because the developer didn’t anticipate the existence of an apostrophe. Perhaps it insists that your address doesn’t exist, despite the inconvenient fact that you’re standing in the building while filling out the form.
To the person who doesn’t understand software, this can feel like an authority declaring a fact about reality.
To someone with programming experience, it’s more likely to look like a validation rule written by a developer who made an assumption that doesn’t apply to you.
That’s an important distinction.
The computer doesn’t necessarily know something you don’t.
Sometimes it has simply been instructed to believe something stupid.
A person who understands programming can recognize the difference between a limitation of reality and a limitation of somebody else’s software.
They may not be able to fix the system. They may not even have permission to inspect it.
But they know enough to ask what the system actually measures, what assumptions went into its design, and whether its conclusions follow from its inputs.
That’s not merely a technical skill.
It’s a form of literacy.
For centuries, learning to read meant acquiring the ability to examine written claims for yourself rather than depending entirely on someone else to interpret them.
Learning mathematics gave people tools for recognizing when a merchant’s figures didn’t add up.
Programming offers something similar for a world increasingly governed by machines.
It teaches you to ask not merely what a system says, but what operations would have to occur for the system to say it.
And when the answer seems suspicious, it gives you a way to investigate.
Sometimes with a small Python script.
Sometimes with nothing more sophisticated than a carefully constructed question.
I suspect some readers will object that I’m making programming sound like philosophy.
Well, yes.
It turns out that computers are exceptionally good instruments for discovering how much of your thinking consists of assumptions you never bothered to examine.
Tell a human assistant to send a reminder to everyone who hasn’t paid their invoice, and they’ll probably understand that you don’t mean customers whose payment arrived ten minutes ago.
Tell a computer to do the same thing, and you must account for that possibility.
You must decide what counts as paid.
You must decide whether the payment has to clear.
You must decide what to do when an invoice has been partially paid.
You must decide whether the reminder goes to the person who placed the order, the accounting department, or the poor bastard whose email address appears in a field labeled `Contact`.
You must decide what happens when the email bounces.
And you must decide whether the program should send four increasingly hostile reminders because somebody scheduled it to run every fifteen minutes.
None of these questions is especially difficult in isolation.
The trouble is that real problems contain hundreds of them.
Human beings survive ordinary life by making reasonable assumptions and correcting each other when those assumptions fail.
Computers survive by being indifferent to the results.
Programming forces you to examine the assumptions.
It makes you distinguish between what you meant, what you said, and what the machine was actually instructed to do.
An AI can help with that examination. A good one can be a remarkably useful partner in identifying possibilities you missed.
But if you don’t understand the difference between requirements, implementation, and testing, you’re going to have a difficult time knowing whether its suggestions are useful.
And you’ll have an even harder time discovering why something went wrong.
Consider the familiar complaint that the computer has suddenly stopped working.
What does that mean?
Does the machine have power? Is the operating system running? Can it reach the network? Can it resolve a hostname? Can it establish a connection to the server? Is the server answering? Is the application answering? Is the application returning the expected data?
These are distinct questions.
The ability to separate them is a form of computational thinking.
When a web application fails, I don’t begin by contemplating the universe and asking why technology hates me.
Well, perhaps briefly.
Then I start determining which assumptions I can eliminate.
There was a time when a SharePoint farm I was responsible for experienced a particularly nasty failure. The apparent problem involved a large, complicated collection of enterprise software. The actual culprit turned out to be a rogue web server under somebody’s desk, quietly participating in a system it had no business participating in.
It wasn’t the sort of problem you solved by typing faster.
It was the sort you solved by following evidence until the system’s actual behavior stopped resembling anybody’s understanding of how it was supposed to work.
An AI might be very good at that investigation.
But the lesson remains the same.
The documentation lies.
Or, more precisely, documentation describes what somebody believed the system was doing, at some point in its history.
The system itself may have other ideas.
Learning to program teaches you how to interrogate those ideas.
Let’s talk about jobs.
Because I don’t want to pretend that this is merely a delightful intellectual exercise in which everyone becomes wiser, richer, and better at solving problems while nobody loses their livelihood.
Artificial intelligence is going to change the economics of software development.
It already has.
Some kinds of programming work will become less valuable. Some jobs will disappear. Some tasks that once justified hiring a specialist will be performed by a manager with an AI subscription and a sufficiently specific request.
And some employers will discover that they can now produce vastly more software without employing proportionately more developers.
There will also be new opportunities, but I distrust anyone who assures displaced workers that the market will naturally provide them with better employment if they simply embrace the future.
History offers little support for the proposition that technological progress distributes its benefits fairly or politely.
You can be entirely correct about a technology’s long-term value to society and still be the person whose rent comes due before those benefits arrive.
So I won’t promise you that learning Python guarantees a job.
It doesn’t.
Neither does learning medicine, law, accounting, or how to repair a diesel engine.
What I will argue is that the ability to understand, direct, and evaluate computational work will be valuable across a much wider range of occupations than traditional software development ever occupied.
Suppose you’re a scientist.
You may no longer need to write the software that processes your measurements, but you still need to understand what happens when missing observations are discarded, how uncertainties propagate, and why the statistical method suggested by your AI may not answer the question you’re asking.
Suppose you’re an accountant.
You might ask an AI to reconcile thousands of transactions, but you need to know what constitutes a match, when two similar entries are unrelated, and how to construct an independent check against the totals.
Suppose you’re a journalist.
You may use an AI to extract information from public records, but you need enough technical literacy to recognize duplicate entries, corrupted dates, and the difference between a database reporting zero incidents and a database containing no records of incidents.
Suppose you’re a nurse, a mechanic, a teacher, a small-business owner, or the person who has somehow become responsible for the family computer because you were foolish enough to fix the printer once.
Programming knowledge gives you another set of tools for understanding and changing the systems around you.
You don’t have to become a professional developer.
You don’t even have to become particularly good at writing code.
You need to become good enough at understanding programs to know what they can do, what they actually did, and what would constitute proof that they did it correctly.
That is a very different educational objective from producing another generation of people who can recite the syntax of a `for` loop from memory.
And it is considerably more interesting.
Which brings us back to Python.
Why Python, specifically?
Why not simply teach people how to talk to artificial intelligence?
Because communicating with an AI is useful, but it isn’t a substitute for understanding the thing you’re asking it to create.
You can instruct an AI to generate a Python script without knowing Python.
You can also instruct a carpenter to build a staircase without understanding the difference between a riser and a tread.
Most of the time, a competent carpenter will save you from your ignorance.
But if you’re responsible for approving the design, you’d probably prefer to understand enough about stairs to recognize one that ends three feet short of the second floor.
Python gives you an accessible way to learn the machinery of computation.
You can start with a small program that reads a file and counts how many records it contains.
Then you can ask it to identify duplicates.
Then you can ask it to group records by date, calculate totals, and flag exceptions.
You can make a prediction about what the program should produce, run it, and compare the results.
When the result surprises you, you can investigate.
Perhaps your data contains a date written in an unexpected format. Perhaps two records have different capitalization. Perhaps an empty field was interpreted as zero, or the program treated the string `”100″` as something other than the number 100.
Congratulations.
You’ve encountered the fundamental problem of software engineering.
The computer did something.
Now you need to understand why.
An AI can help you write the code, explain what it does, identify possible errors, and suggest ways to test it.
In fact, I think using AI while learning Python is an excellent idea.
Ask it questions. Challenge its explanations. Have it produce examples. Ask it to show you two different ways to solve a problem, then explain why one might be preferable.
And when it gives you an answer that looks suspicious, don’t just ask it to reassure you.
Construct a test.
Try changing one input.
Try providing something it didn’t expect.
Try an empty file, a missing column, a negative number, or a date from last year.
See what breaks.
If you have never written a program before, this may be the first time you’ve had the opportunity to experiment directly with the logic governing a machine.
And thanks to AI, you can do it without spending three hours hunting down a missing parenthesis.
I consider that progress.
Not because the machine has eliminated the need to learn, but because it has removed some of the obstacles that made learning unnecessarily unpleasant.
The important thing is that you should not become merely a passenger.
If the AI does everything and you understand nothing, you haven’t acquired a skill.
You’ve acquired a dependency.
There is nothing inherently wrong with depending on tools. Civilization is largely an elaborate arrangement in which people depend on tools, specialists, and infrastructure they do not personally understand.
I don’t know how to manufacture a modern microprocessor, and I have no particular ambition to start.
But dependency becomes dangerous when you can no longer evaluate what you are being told, particularly when the person or machine telling you has no responsibility for the consequences.
Learning Python is one way to avoid that condition.
It allows you to become a participant in the process rather than merely the person waiting for the output.
There’s an old tendency in technology to confuse mastery of a tool with mastery of the work performed using it.
People who know every feature of a word processor are not necessarily good writers.
People who know every function in a spreadsheet are not necessarily good accountants.
And people who can write astonishingly clever code are not necessarily good at solving the problems for which that code was written.
The cleverness can even become a liability.
I’ve encountered software that was so impressively engineered that nobody could explain why it existed.
Somewhere inside it was a business problem, presumably.
Possibly still alive.
Artificial intelligence is going to make that kind of technical cleverness abundant.
We will have access to increasingly powerful tools that can construct complicated systems almost as easily as previous generations assembled spreadsheets.
And that will make the ability to distinguish a useful solution from an elaborate mistake more important, not less.
The valuable human contribution may be the person who recognizes that the expensive new application is unnecessary because the problem can be solved by changing one business rule.
Or the person who notices that a proposed automation would remove a safeguard that exists for a very good reason.
Or the person who asks why the company is collecting information it has no legitimate reason to possess.
Or the person who realizes that the AI has produced exactly what management requested, and that management requested something profoundly stupid.
These are not glamorous accomplishments.
They don’t produce spectacular demonstrations.
Nobody invites you onto a stage to announce that you saved the organization two million dollars by persuading it not to build something.
But they are valuable.
In some cases, much more valuable than the software itself.
And programming literacy makes you better equipped to achieve them.
I think we are approaching a change in what it means to be a programmer.
For most of my professional life, the programmer was the person who knew how to communicate with the machine.
That required specialized knowledge because the machine was astonishingly literal, frequently unhelpful, and generally incapable of understanding what you intended unless you expressed it in precisely the right way.
Artificial intelligence is changing that relationship.
The machine is increasingly capable of understanding ordinary language, inferring intentions, asking questions, and constructing its own technical solutions.
The barrier between intention and implementation is becoming thinner.
But the barrier between intention and *good judgment* remains.
And the more implementation becomes automatic, the more attention we ought to pay to everything that happens before and after it.
What problem are we solving?
Whose problem is it?
What are we assuming?
What information do we need?
What should happen when something goes wrong?
How will we recognize success?
Who is allowed to change the system?
Who bears the consequences?
These questions are not merely the preliminaries to programming.
They’re the substance of it.
The code was how we communicated the answers.
If the machine can now write the code, wonderful.
That frees us to spend more time on the part that mattered in the first place.
It does not absolve us of understanding what we’re doing.
And it certainly doesn’t mean that the people who understand these systems have become obsolete.
So here’s what I would tell someone considering learning Python today.
Don’t learn it because you expect to outrun an AI at producing code.
You probably won’t.
Don’t learn it because somebody promised that six weeks of tutorials will transform you into an indispensable software engineer.
It won’t.
And don’t learn it because you imagine that the future will reward people for memorizing syntax that a machine can generate perfectly well on request.
Learn it because programming teaches you how to take an idea apart, discover what it actually requires, and reconstruct it as a series of operations whose results can be observed and tested.
Learn it because the world is full of systems making decisions about you, and understanding how such systems work gives you a better chance of recognizing when they’re wrong.
Learn it because being able to construct a small experiment is more useful than having to accept an authoritative-looking answer on faith.
Learn it because the difference between I think this should work and I can demonstrate that it works is one of the most important distinctions in engineering.
Learn it because artificial intelligence will give you access to increasingly powerful computational tools, and understanding programming will help you use those tools without surrendering your judgment to them.
And learn it because there’s something deeply satisfying about looking at an annoying, repetitive problem, understanding its structure, and teaching a machine to make it go away.
Even if another machine writes the instructions.
Especially if another machine writes the instructions.
For the first time in computing history, someone with an idea and a little programming literacy may be able to build useful software without first becoming an expert in the tedious mechanics of constructing it.
Think about that.
We spent decades trying to make computers easier for people to program.
Now we’re approaching a world where computers can do much of the programming for us.
That isn’t the death of programming.
It’s the removal of a gate that stood between many people and the ability to make computers useful.
Of course, opening a gate doesn’t tell you where the road goes.
You’ll still need to decide that.
And if the road leads straight over a cliff, I’d rather have somebody along who understands the difference between a successful compilation and a successful outcome.
The AI can drive.
It can probably drive better than I can. I don’t even have a license. ^_^
But before we turn it loose, somebody ought to know where we’re going, whether the bridge is still there, and who the hell authorized the route.
That’s why you should learn Python.
Not so you can compete with the machine.
So you can understand what you’re asking it to do.
And, when necessary, tell it to stop.
Epilogue:
At the time of this writing, our new business venture, Colossus Foundry, is barely 2 weeks old. We don’t even have a website I can point you to yet. Our Python Reforged course-ware is barely out the gate. Module Zero is basically just setting up the Py environment, and I need to rewrite the lessons before they put someone to sleep – while somehow still making the instructions easy to follow.
I wrote this essay because I needed to answer the question why? As in “why am I going through all the trouble to make a free six-week course in Python?” and also “Why should I make the effort to learn about Python if I can just vibe-code everything?”
At some level, the answer is that we need to pay our mortgage and buy groceries. So, I want to be recognized for my technical skill, so we can find and win clients.
But, at it’s heart, the answer is that AI cannot answer that question why? — yet. When it finally can, we’d best damn well be prepared to understand its answer.

