5  Course introduction

You are about to learn programming at a moment when an AI can do that too. That does not make it less worthwhile to learn. In fact, as you will see in this course, exploiting the abilities of AI’s just makes your new programming skills go a much longer way towards producing amazing things.

You will learn Python by writing small programs and watching them run. Alongside that you will learn how to specify what you want the AI do do and how to verify that what comes back is what you wanted it do. As your programming abilities grow, you will be able to safely hand more and more work over to the AI.

What the course is for

By the end of the semester you should be able to look at a problem from your own field, decide what smaller problems it breaks into, say what each of those smaller pieces must do, and check whether each piece does exactly that. Some of those pieces will be code you write yourself, and some of them will be code you instructed the AI to write. In either case, it is always you who decides whether the code is correct, and the goal of the course is to make you capable of that decision.

The hard part of programming is not learning what each piece of code does. The hard part is how putting pieces together produce a program that does what you want it to. It is a separate skill that only comes from doing it many times. The first five weeks introduce the individual building blocks it takes to build any program (literally), and the rest of the course trains your ability to decompose a problem into smaller parts, compose which parts of your program will handle each task, and then implement and test each part separately. You will have ample opportunity to train these skills in programming projects, and gradually learn how to hand some of them to the AI.

How the material teaches

The book strives to show what things do before worrying about what they are called. You will often be asked to write or run come code and only then be told how and why it works. A name attached to something you have already made work sticks better. Almost every exercise asks you to predict what will happen before you run the code. Decide what you think will appear on the screen, write it down, tell your dog, or just say it out loud. The gap between your prediction and the result is the only reliable way to know what you do not yet understand. Just running the code and rationalizing the result will only give you passive (Python) language skills. You will only learn to recognize a correct result when given to you, and now how to produce one yourself.

Underneath all of it is a way of reading code that the course calls substitution and reduction. It is a simple method that lets you break down complicated code step by step using the simple rules for the basic building blocks of Python. If you can do these steps in your head, in order, for any piece of code, then you can read code. With practice, you will eventually be able to think and express yourself in code. Several of the tools we use in this course are made to show you how the actual these substitution and reduction steps so you can compare them against the ones you predicted.

Learning with the AI

An AI assistant is available from week one and lives in your browser, in Microsoft 365 Copilot. It includes a Study and Learn agent that guides your reasoning rather than just handing you an answer. You cannot use any other AI in any other place, especially not in your code editor (VScode). Keeping the AI apart from everything else will help you use it consciously and deliberately: using it becomes a decision you make rather than something that happens to your code while you are typing. As the course progresses, you will do exercises that train using the AI in different roles. Each exercise is labelled with a badge that licenses the ways in which you can use AI. The badge sits on its own line just below the exercise heading, set smaller than the surrounding text, and it is a link. Click it and you land on the description of that badge below, which tells you what you can ask the AI for, and what you must to do with whatever comes back. Exercises where you cannot use the AI in any way are labelled with the SOLO badge. Each badge expands the way you can use the AI (think of them as belts in karate). Here they are in the order the course grants them:

AI: Explainer · AI: Comparer · AI: Drafter · AI: Collaborator · AI: Developer

Reading about each badge below, do not be alarmed if they refer to concepts or terminology you do not yet know. You will by the time you get to them in the course.

SOLO

The assistant is closed. Not open and unconsulted. Closed.

This is the only badge that takes something away, and it is the one that carries the most weight. A SOLO exercise means the browser tab is shut, you are not rereading an answer from earlier, and you are not reaching for a hint you half remember from a chat this morning. You type, you predict, you run, you fix.

Among other things SOLO exercises lets you test yourself. If you can do it alone, you have learned the thing, and if you cannot, you are better off the sooner you find out. Doing a SOLO exercise with help does not get you in trouble, but it robs you of the only way to find out. Roughly three quarters of the exercises in this book are SOLO. That is the course working as designed rather than an oversight waiting to be corrected.

AI: Explainer

Ask it what something that already exists means, in whatever shape that takes. Then run the thing and see.

The first level, and the safest, because you are not asking the assistant to produce anything. Three variants live here, and all three share the same shape: you put something in front of it that already exists, and you check what comes back.

The plainest variant is asking about some thing. You hand it something that is already exists, a traceback, a line of code you did not write, a word in the documentation you do not know, and you ask what it means. Ask it in the shape of a question about a specific object: what does this error message mean?, pasting the whole traceback, or what does 'ATG' in dna do here? Do not ask why doesn’t my code work?. That is a request for a fix disguised as a question. If the answer is longer than the thing you asked about, try to make your question more specific.

A second variant is asking for translation, in either direction. Paste a line of code into the AI and ask for one plain English sentence describing what it does. Or describe a small operation in English, go through the string and count how many of the characters are G or C, and ask for the corresponding Python code. Going from code to English, translate the line yourself first, before you read the assistant’s sentence, then compare the two and decide which is more precise about what actually happens. Going from English to code, read every line of what comes back and test it by running it on an input where you already know the answer. A sentence you cannot write yourself is a piece of code you do not yet understand.

A third variant is asking for more examples of something you almost understand: give me three more examples of slicing a string with a negative step, or show me the same dictionary lookup written for three different kinds of key. Make sure you still predict what each example prints before you run it. You can also ask for illustrations of something you have already met but is are unsure about. Do not ask about something you have not been taught yet. That how you fall behind while feeling productive.

An explanation, a translation, an example are all predictions about what the code does, and you have a machine that settles predictions: run the line, or put it through %%steps and watch it reduce. When the explanation and the code behavior agree, you have learned something. When they do not and you know why, you have learned even more (something that may go in your logbook).

AI: Comparer

Two versions, one judgment, and the judgment is yours.

Now the AI assistant argues and you decide. You have a working function; you ask for a second way of writing it, or maybe you show it two versions you already have and ask what the trade-offs are. What comes back is an argument, and arguments are useful. Ask it to be specific: which of these two is easier to read, and point at the lines that make the difference, rather than which is better. A general question gets a general answer, and a general answer about code is almost always flattering to whichever version was mentioned last. Then decide for yourself and write down one sentence saying why, naming the reason. E.g., “this one is shorter but hides the empty-sequence case”, or “that one repeats itself but I can see what it does without thinking”. If you cannot write that sentence, you have not compared the two versions, you have only read about them. And run both versions on the same inputs. Two functions that look equivalent may not be.

AI: Drafter

It writes a small piece. You read every line, and a test decides.

This is the first level that produces small pieces of code you intend to keep. The ordinary order is: specify, draft, read, test. Specify first, say what the function is called, what it takes, what it returns, and what it should do on the corner-case awkward inputs, because a request with no specification has nothing to be right or wrong about. Draft second. Read third, every line, and if there is a line you cannot explain, you do not own it yet and the fix is to ask AI: Explainer questions about that line until you do. Test fourth, and let the test decide rather than your impression of how the code looks. Keep the piece small. A function that fits in your screen is a function whose bugs you can find. Longer functions are usually worth breaking into several smaller ones.

Some exercises at this level may ask you to provide your specification as a series of tests that the correct function should pass. You write the assert statements first, from your own understanding of what the function must do, including the decisions nobody else can make for you. What should the is_gc_rich function return when passed a DNA strand that is exactly half GC? What it should do with an empty strand? Then you ask the AI to implement it in plain English, without showing it your tests. Showing it the tests may be tempting, but not doing so is the most important part. Code written against a visible test suite may blindly satisfy the tests but not generalize as intended. Code written against a description and only then validated by tests it never saw is being genuinely checked. Do this once, throw the implementation away, ask for a second version, and watch whether the unchanged tests still pass. That is the thing this discipline is really teaching: the implementation is replaceable and the specification is not.

AI: Collaborator

You provide the plan. It contributes one piece or opinion at a time.

Here the assistant works on something with you rather than for you, but the division of labour strict: you plan how the larger problem should decompose into subproblems solved by individual functions. The AI offers opinions on the plan for you to accept/reject and then implements one function at a time. Do the planning with the assistant closed. Describe what arguments each function takes and it returns. Give two or three examples of concrete values returned by each function given real concrete arguments. Only then open the browser, show it the plan, and ask narrow questions: is there a case my examples do not cover?, or is there a function I have not named?. Do not say write this for me (you get to do that at AI: Developer). Whatever it suggests, write down accept or reject and one line of reason for each (maybe in your logbook). That explicit recording ensures that you are, in fact, collaborating and not being led. Failure at this level is not bad code. It is a plan that drifted into being the AI assistant’s plan while you were blindly agreeing with one thing at a time.

AI: Developer

Hand over the whole job, against criteria you wrote before you asked. With great powers comes great responsibility

You give a goal and a specification and get back something whole, which you then check. Write the acceptance criteria first, in a file, before you send a single prompt. What must the thing do, on what inputs, producing what, and what would count as it having failed? Criteria written afterwards are not criteria; they are a description of whatever you got. When the result does not meet them, do not send this doesn’t work, fix it, say which criterion failed, on which input, with what output, and what you expected instead. Vague reports get vague repairs. Two rules keep this level honest. If the loop has not converged in two rounds of that, take the keyboard back and write the piece yourself, because a third round is almost always slower than doing it. And before you keep anything, close the assistant and explain the most-delegated function in it, line by line, out loud or in writing. You cannot own a result you cannot explain, and by the end of this course owning the result is the entire job.

The logbook

Once a week you write one entry in a logbook you keep all term. An entry records something the assistant got right, something it got wrong, and how you knew which was which. It takes a few minutes and it is the single best record of your own development that the course produces, because by week twelve you will be reading week-two entries where you could not tell a plausible answer from a correct one, and the difference will be visible on the page.

The projects, and who writes what

From week six to week thirteen the course has eight weekly projects, each one treating a problem relevant to molecular biology or bioinformatics. Every project has three parts, and it helps to name them separately because the course moves them between hands at different times. The decomposition is the list of functions the project consists of, with what arguments each one takes and what each one returns. The tests are the code that decides whether a function does what it is supposed to. The bodies are the actual lines inside each function. In the first project all three parts start in familiar places. The decomposition is given to you, the tests are given to you, and you write the bodies. Over the following weeks each part changes hands on its own schedule, and once a part has moved it does not move back.

Bodies: Produced by you -> Produced by AI. In week seven you nominate one function and let the assistant draft it, then test what comes back. In week eight it drafts again, but only after you have written a test for the function yourself, which is the point at which the order of operations becomes the lesson: the check exists before the code exists. From week nine the assistant does more of the routine work, the glue between your code and a library, while you keep the parts that carry the actual biology.

Tests: Given to you -> Produced by you. Week eight ships you every test but one, and you write the missing one. Week nine ships half. By week eleven you get a single end-to-end test that says whether the whole thing works, and nothing that tells you which part is broken. By week twelve you get none, and what you can check is what you thought to check.

Decomposition: Given to you -> Produced by you -> Produced by AI. The decomposition moves last, because it is the hardest of the three. Through week nine the full list of functions is given. In week ten most of it is given and you name two pieces yourself. In week eleven you get only the top-level function and decide everything under it. In week twelve you get the goal and the data. In week thirteen you formulate the problem, build it, and only afterward see how we would have broken it up, which is the closest thing the course has to a final examination of the skill it is actually teaching.

Two rules keep this from becoming unfair. A project never asks for anything the notes have not already taught, and it asks for it the week after they taught it, so there is always a week between meeting an idea and having to use it under your own direction. And each transfer happens once. A part that has become yours stays yours, so the ground never shifts back under you.

Knowledge is not obsolete, its a super-power

There is a fear worth addressing directly, which is that learning to program is pointless now that a machine can do it. The opposite is closer to the truth, and the reason is arithmetic. What you can safely get out of an assistant is limited twice over by what you know: once by your ability to ask for the right thing, and again by your ability to tell whether what came back is right. Both limits are your own knowledge, so it makes some sense to say that the value of an AI is “the square of what you know”. Every new thing you learn is now worth more than it used to be, because it pays you twice, once directly and once by unlocking AI assistance that you can use without danger.

Exercise 5-1

SOLO

Make a file called logbook.md somewhere you will find it again, and write the first entry today, before you have used the assistant for anything in this course. Write down what you currently expect it to be good at, what you expect it to be bad at, and how you imagine you would tell the difference. You will read this again in week fourteen. Nobody else will, so make it truthful rather than impressive.