Turing to Python: Six Foundations of Computer Science

Computer science has a reputation for being the study of "computers," but the field's first-century arc has actually been the slow turning of one abstract idea into hardware: if you give a machine a finite rule table and an unlimited supply of memory, what sorts of tasks can it actually do? This tutorial walks from Alan Turing's 1936 paper-form model to a small runnable Python snippet, and opens every black box it meets along the way. We will start with arithmetic versus non-arithmetic computation and the four components of a Turing machine. Then we will see how the stored-program idea turned the abstract model into a working computer. We will unpack how integers and floats actually live inside memory as patterns of bits. We will look at why storage is layered into a pyramid rather than a single uniform pool. We will open the CPU and watch a RISC-V instruction run through its five-step fetch-decode-execute cycle. Finally we will close the loop by writing the smallest Python program that uses sequence, selection, and iteration, and predict its output.

The arc is what makes the chapters cohere. By the end you should be able to point at any line of Python and trace it back to the same fetch-decode-execute loop, the same memory pyramid, and the same handful of bit patterns that earlier chapters introduced.

What counts as computation, and how the Turing model runs it

"Computation" looks intuitive until you try to define it. A definition that has held up since 1936 treats computation as the mechanical application of a finite list of rules over a sequence of symbols. To get there concretely, take two operations on the same input list [4, 8, 15, 16, 23, 42]:

  • Sum (arithmetic): 4 + 8 + 15 + 16 + 23 + 42 = 108.
  • Sort descending (non-arithmetic): the result is the same six numbers reordered as [42, 23, 16, 15, 8, 4].

Addition is "arithmetic" because it folds the list to a single number through fixed rules of arithmetic. Sorting is "non-arithmetic" because the answer has the same structure as the input — six ordered symbols — and reaching it requires comparison rather than arithmetic folding. Both are computations, and both can be carried out by a machine.

Mechanical predecessors of the modern computer, including the Chinese suanpan (算盘), already encoded this idea physically. Each rod holds a single digit (a "cell"), and beads pushed against the beam carry out arithmetic step by step. The arrangement below the rods (6 3 0 2 7 1 5 4 0 8) is exactly a column of cells holding a column of digits, mirroring the structure of a modern memory array.

The chinese suanpan, with ten rods above and a row of values written below each rod.

Caption: A 10-rod suanpan. Each rod holds a single digit; the row of digits below the rods is the digits column. The structure is one cell per symbol, a pattern a memory array still uses today.

The suanpan makes "arithmetic computation done by a physical device" concrete: every operation reads two symbols, applies a rule, and writes a new symbol. Alan Turing's 1936 paper formalised exactly this kind of rule-following for any computable task, and the resulting model is called the Turing model or Turing machine (图灵机).

Four components, one rule at a time

A Turing machine has four pieces, and listing them is enough to describe the model. The Kleene 1952 schematic in the Wikipedia article shows all three structural pieces:

The Turing-machine structural schematic, after Kleene 1952.

Caption: A finite stretch of tape (the row of squares), one read/write head attached to the leftmost cell, and one state label q4 above the cell the head is currently on. The "finite stretch" is a fragment of an infinite tape.

Concretely, the four components are:

  1. The tape (纸带). An unbounded sequence of cells, each cell holding one symbol from a finite alphabet. A blank symbol marks "no value here."
  2. The read/write head (读写头). A movable reader/writer that sits under exactly one cell at a time, reads its symbol, writes back (possibly a different symbol), then moves one cell left, right, or stays put.
  3. The state register (状态寄存器). One of finitely many states the machine is in right now. A special start state is the first state.
  4. The finite table of rules (有限规则表). For every (state, symbol) pair, the table says: write which symbol, move which way, and enter which state next. Each row is a transition rule (转移规则), often written in the 5-tuple form (q_i, S_j, S_k, L/R/N, q_m) — current state, symbol read, symbol written, head movement, next state.

A function is Turing-computable (图灵可计算) if its value can be computed by some Turing machine.

Walking one transition rule step by step

The single most useful exercise here is the slide-9 worked example from the lecture deck. Tape initially contains the two symbols "10", the head is on the left cell, and the state is A. Two rules are given:

  • Rule 1: State A + read "1" → write "0", move right, enter state B.
  • Rule 2: State B + read "0" → write "1", move left, enter state A.

Step 1: state A, read "1". Rule 1 fires. The head writes "0" into the left cell, moves one step right, and the new state is B. The tape is now "00," and the head is on the right cell.

Step 2: state B, read "0". Rule 2 fires. The head writes "1" into the right cell, moves one step left, and the new state is A. The tape is now "01," and the head is back on the left cell.

The answer is 01 (option B). On the state diagram, the same path corresponds to two arrowed transitions between nodes A and B.

A state transition diagram for a 4-state machine.

Caption: Four circular nodes A, B, C, H with arrows between them. H is drawn as a double circle, the convention for an accepting/halt state. Each edge label has the form <scanned>/<behaviour>: for example, A → B is labelled 0/P,R, meaning "if the head reads 0, print 1 and move right."

This is the smallest unit of computation in the Turing model: a single table row selecting what to do next given what the machine is doing now and what it sees. Stack many of these rows into the table and the machine can compute anything computable.

Turing completeness

A system is Turing-complete (图灵完备) if it can simulate a Turing machine, given enough time and enough memory. The bar is high: the system must let the user write programs that run any algorithm. The lecture-deck examples (Python, Java, C++, PowerPoint, Minecraft's Redstone) are widely cited in slide-deck and community sources as Turing-complete, even though the Turing-machine Wikipedia article itself does not enumerate them — it confirms the category by noting that nearly all programming languages are Turing-complete if the limitations of finite memory are ignored (with Conway's Game of Life as a worked example, and ANSI C as a notable exception because the size of pointer types is observable inside the language, so memory is bounded). The programs running on a laptop or a smartphone likewise pass the test in the limit of unbounded virtual memory, even though the physical hardware is strictly finite-state. This is the formal reason every modern computer (and a fair number of unexpected ones) feels like a "real" computer to its userTuring machine.

The takeaway: computation has a formal shape, namely a finite rule table acting on a finite alphabet, and Turing completeness is the line separating "can run any program" from "can only run a fixed sequence."

How a stored-program computer replaced the patch-cord plugboard

The Turing machine's rule table is part of the machine, just as much as the tape and the head are. That setup is fine for a thought experiment, but it makes changing programs hard: you have to rebuild the table. ENIAC (Electronic Numerical Integrator and Computer), completed in 1945 at the University of Pennsylvania's Moore School, ran into exactly this problem. ENIAC was Turing-complete and could solve a large class of numerical problems, but programming it required physically rewiring a plugboard and resetting three portable function tables containing 1,200 ten-way switches each. Mapping a new problem onto ENIAC usually took weeks; once planned, physical setup took days. Until April 1948, that was the only way to give ENIAC a new programENIAC.

The U.S. Army photo taken at the Ballistic Research Laboratory's building 328 (about 1947–1955) shows two operators doing exactly that work in front of ENIAC's switch-and-cable panels:

Two ENIAC operators working in front of the plugboard panels.

Caption: Glenn A. Beck (background) and Betty Snyder (foreground) programming ENIAC at the Ballistic Research Laboratory's building 328, c. 1947–1955. The machine's program is being set as a physical wiring job, not a data file.

Around 1944–1945, Eckert and Mauchly's design for the successor machine, the EDVAC, took the abstract idea one step further; John von Neumann, consulting for the Moore School, sat in on the meetings and wrote the ideas up as the 1945 First Draft of a Report on the EDVAC, which circulated widely. Eckert's design used mercury delay-line memory to hold both program and data in the same physical memory. The transition rule "the program is data" is the small change that made a real computer possible. The Manchester Baby ran the first stored program on this architecture in June 1948ENIAC.

The Von Neumann 5-block diagram

The Von Neumann model (冯·诺依曼模型) is what you get when you draw a stored-program computer as boxes and wires:

The canonical 5-block Von Neumann architecture diagram.

Caption: A CPU split into a Control Unit and an ALU, a separate Memory block, and Input/Output on either side. The arrows show data and control movement; the single Memory block is the entire storage story for now.

The arrangement is:

  1. ALU (Arithmetic Logic Unit 算术逻辑单元). Performs arithmetic and logic operations on data.
  2. Control Unit (控制单元). Sequences those operations. It is the rule dispatcher of the architecture.
  3. Memory (存储器). A single addressable read/write memory that stores both data and programs.
  4. Input. Brings data in from outside.
  5. Output. Sends results back out.

The single Memory block is the visual punchline: this is what "stored-program computer" means in hardware. Both the program and the data it manipulates live in the same memory, addressed the same way, treated as bit patterns. The Wikipedia article makes the point explicit: "A stored-program computer uses the same underlying mechanism to encode both program instructions and data as opposed to designs which use a mechanism such as discrete plugboard wiring or fixed control circuitry"Von Neumann architecture.

The Nand2Tetris course materials picture the same idea with the program and data drawn as explicit sub-blocks of memory:

Hack-style Von Neumann diagram with program and data as memory sub-blocks.

Caption: A green "computer system" block. Inside, Memory contains two sub-blocks ("program" and "data"), and the CPU contains an ALU. Input and Output sit on either side. Hack uses this kind of layout, but with the program and data memories physically separated.

The slide-deck's lecture notes call this the "stored-program concept," and it is the answer to ENIAC's plugboard problem. Once the program is data, changing the program is just writing a different bit pattern into the same memory, no rewiring required. Once the program can be loaded into memory, the same hardware can run any program you give it.

Five generations of electronic computers

The slide deck groups electronic computers into five generations based on the underlying switching technology:

  • 1st generation (1950–1959). Bulky vacuum tubes as electronic switches.
  • 2nd generation (1959–1965). Transistors replaced vacuum tubes; size and cost dropped.
  • 3rd generation (1965–1975). Integrated circuits further reduced size and cost.
  • 4th generation (1975–1985). Microcomputers appeared, with the Altair 8800 microcomputer in 1975 as an early example.
  • 5th generation (1985–1995 and after). Clusters, vector processors, workstations, minicomputers, laptops and palmtops; after 1995, HPC advances with supercomputers, multi-core PCs, and GPGPU.

ENIAC sits at the head of the first generation because it is the first programmable, electronic, general-purpose digital computerENIAC.

The takeaway: a modern computer is a Turing machine whose rule table is no longer hard-wired. Both the program and the data sit in the same addressable memory, and changing the program is now just writing a different bit pattern into that memory.

How a 32-bit word encodes any number — 2's complement and IEEE 754

Inside that single Memory block, every value the computer stores, whether integer, fractional, or string, is a fixed-width bit pattern. The rules for translating those bit patterns back into useful numbers are the second major thread of this tutorial.

For small numbers, binary and hexadecimal are just alternate spellings of familiar decimal values. The 16-row table below spells out decimal 0–15 against their binary and hex forms:

Decimal-Binary-Hex conversion table for values 0 through 15.

Caption: Three columns: Decimal, Binary, Hex. Each row maps a small integer to its 4-bit binary form and hexadecimal label. The table is just a quick cross-reference.

Treating the bit pattern as a 2-digit-decimal number, like 108 = 64 + 32 + 8 + 4 = 2^6 + 2^5 + 2^3 + 2^2, gives 8-bit unsigned numbers a range from 0 to 255. Two's complement (补码 2's complement) extends the same fixed-width pattern to signed numbers, and the version you already know is exactly right: the highest bit (MSB) is the sign bit, and 8-bit two's-complement numbers span [-128, +127] — asymmetric, because the value +0 merges with -0 and one extra negative slot is freed. Patterson and Hennessy's Computer Organization and Design (RISC-V edition) explains why this works in one phrase: two's complement exists because it lets one adder circuit handle both signed and unsigned addition; treat the k-bit pattern as an element of the cyclic group Z/2^k and negation becomes reflection through the 0/-2^(k-1) axisTwo's complement.

The asymmetric range, geometrically

Looking at the cyclic ring in the figure below makes the asymmetry precise. The outer (white) ring gives the unsigned reading of each 4-bit pattern, running 0, 1, 2, ..., 15 around the circle. The middle (orange) ring is ones'-complement, the older convention. The inner (teal) ring is two's-complement, the convention every modern machine uses.

Cyclic depiction of unsigned, ones'-complement, and two's-complement.

Caption: A circle of 16 4-bit patterns. The outer white ring shows unsigned values 0–15 clockwise; the teal ring shows the two's-complement reading of the same 16 patterns, where -8 occupies the geometric slot for what unsigned would call "8."

The visual clue is the teal ring's extra negative slot: -8 occupies the position that the unsigned ring calls 8, and -8 is the geometric invariant under negation (it is its own negation in 4-bit two's complement). The reader's point that 8-bit two's complement spans [-128, +127] rather than a symmetric [-127, +127] is the same idea, but one bit wider: there is no way to give +0 its own slot and keep both halves symmetric, so the positive side gives up one value to the negative sideTwo's complement.

This geometry is the reason a quiz answer in the slide deck says "128 cannot be represented in 8-bit two's complement": 128 would require a positive +0 and a +128, but two's complement has only one zero and 127 numbers above it.

IEEE 754: a 32-bit word that means a real number

Integers are not enough; scientific and engineering programs need fractions. The IEEE 754 standard (in its 2019 edition) gives every modern computer a deterministic way to encode a real number in a fixed-width bit pattern. The single-precision format, called binary32, packs 32 bits as:

  • 1 sign bit (blue in the figure).
  • 8 exponent bits (green).
  • 23 fraction (significand) bits (red).

The exponent is stored with a bias of +127. That is, an exponent of 0 in the encoded word actually represents -127 mathematically, and an exponent of 28 would be stored as 28 + 127 = 155 = 1001 1011₂. The bias trick lets the comparator hardware treat the smallest exponent (00000000) as a special "subnormal/zero" marker and the largest (11111111) as ±∞/NaN without needing an extra bit.

A 32-bit IEEE 754 single-precision word, split into sign / exponent / fraction.

Caption: A 32-bit word split into three coloured segments: 1 blue sign bit, 8 green exponent bits, 23 red fraction bits. The bit pattern shown corresponds to 0.15625.

The slide-deck walkthrough uses the speed of light c ≈ 0.2998 × 10⁹ (a 4-significant-figure teaching approximation of the SI-defined value c = 299,792,458 m/s) to make the same encoding concrete. To encode a number near 3 × 10⁸ in binary32, find the binary exponent e so that the value lies in [2^e, 2^(e+1)); for c ≈ 3 × 10⁸ that exponent is e = 28, since 2^28 ≈ 2.68 × 10⁸ < 3 × 10⁸ < 2^29 ≈ 5.37 × 10⁸. The encoded word then stores three fields: S = 0 (positive), E = 28 + 127 = 155 = 1001 1011₂ (the stored exponent with bias), and F = the first 23 bits of the mantissa after the implicit leading 1. Only novelty vs. a textbook floating-point example is that the signed bit and the biased exponent are split into dedicated fields rather than glued onto the significandIEEE 754.

BF16 (a 16-bit truncated form popular in machine-learning chips such as Google TPU v2 and modern GPUs) keeps the same 1+8 bits for sign and exponent and trims the fraction to just 7 bits; that exchange gives up precision in exchange for half the storage footprint, which is the right trade-off for many matrix-multiplication workloadsIEEE 754.

The takeaway: every number a computer touches, positive, negative, or fractional, is a fixed-width bit pattern. Two's complement lets one adder circuit handle signed and unsigned arithmetic at once, and IEEE 754 lets one 32-bit word hold a fractional value by splitting it into sign, exponent-with-bias, and fraction.

Why storage is a pyramid — the memory hierarchy

A typical 2026 computer has registers that answer in a fraction of a nanosecond, hard disks that answer in milliseconds, and tape libraries that answer in minutes. No single memory technology wins on speed, capacity, and cost-per-bit simultaneously, so a real computer is built out of multiple layers. Each layer is the cheapest technology that meets its specific latency and capacity requirement, and caching moves data up or down the pyramid depending on whether it is being used.

The trade-off is the punchline before any picture. As the slide deck phrases it on slide 29, "Higher speed comes with lower capacity and higher price per capacity" — designing memory hierarchically is how engineers square that circle.

Six layers, top to bottom

The canonical 6-layer memory pyramid visualises every layer as a trapezoid, narrowing from the broadest, slowest, cheapest base to the smallest, fastest, most-expensive tip:

Canonical 6-layer computer memory hierarchy.

Caption: A 6-tier trapezoid. Top tier: processor registers (very fast, very expensive, smallest capacity). Tier 2: processor cache (very fast, very expensive, small). Tier 3: random access memory (fast, affordable). Tier 4: flash/USB memory (slower, cheap). Tier 5: hard drives (slow, very cheap). Tier 6: tape backup (very slow, affordable, largest capacity).

The slide deck's own version has the same six layers in the same order, with a slightly different label set that maps onto what the audience already knows from the earlier chapters:

  • Register (寄存器) — top.
  • Cache inside core: L1 cache (SRAM).
  • Cache outside core: L2 cache (SRAM).
  • DRAM (动态随机存取存储器).
  • Local Disk.
  • Remote Storage — bottom.

Both pyramids show the same hierarchy. The slide-deck version uses a more accessible set of labels tied to the rest of the course; the Wikipedia version pins the trade-off labels (fast/small/expensive ↔ slow/large/cheap) explicitly. The Engineering reality is that the cache tier is itself multi-layered (L1 instruction, L1 data, L2, L3, sometimes L4) on a real chip, even though the simple pyramids collapse it into one band. An image like the AMD Bulldozer hwloc topology shows what those sublevels look like on real hardware: nested rectangles L1i / L1d / L2 / L3 on a multi-core server. Treat that image as a secondary view that explains why the cache trapezoid is thicker on a real chip than the simple pyramid suggests.

Primary vs secondary, and the cache principle

The hierarchy breaks cleanly into two functional kinds. Primary storage is volatile, byte-addressable, and close to the CPU: registers, cache, and main memory (DRAM). Secondary storage is non-volatile and block-addressable: SSDs, hard drives, and tape. The slide deck's chapter-2 slide 53 makes the round distinction: "Disks are I/O, NOT Memory — the computer can run with the disk removed (if everything is in RAM)." That is, secondary storage sits off the addressable side of the memory bus. The Memory block in the Von Neumann diagram only covers primary storage; the disk is on a different bus, accessed through I/O.

Caching is what makes the layered system feel like a single fast memory. Hot data (frequently used) moves up to faster layers; cold data (rarely used) sinks down to slower, larger layers. The previous bullet's image (the primary-vs-secondary diagram from the slide deck) lays out exactly this split: registers, cache, and RAM form the "Primary Storage" box, hard disk sits in a separate "Secondary Storage" box below.

Latencies, briefly

Concrete latency numbers are worth a sentence because they make the layered design feel inevitable. Wikipedia's memory-hierarchy article cites AMD Zen-4 figures that span roughly ten orders of magnitude: register (~0.25 ns) → L1 (~1 ns) → L2 (~3.5 ns) → L3 (~12 ns) → DRAM (~80 ns) → NVMe SSD (~0.2 ms) → HDD (~4 ms) → spun-down disk array (~25 s) → tape library (minutes). Latencies of this scale mean that without caching, every CPU cycle would burn waiting for data. The numbers drift as hardware generations change, so quote them as snapshots rather than rulesMemory hierarchy.

The takeaway: a modern computer has registers, cache, RAM, and disk not because engineers couldn't pick one, but because each layer is the cheapest technology that meets a specific latency and capacity requirement. Caching is what keeps the slow layers from being felt.

Inside the CPU — datapath, control, and the fetch-decode-execute dance

Open the Processor box from chapter 2's Von Neumann diagram and you find two cooperating halves. The control unit plays the rule table from chapter 1; the datapath plays the ALU and the registers. Together they execute the smallest unit of work a real CPU actually does: a single instruction.

A modern CPU does not literally have a single shared bus; the canonical diagram was simplified to fit on one page. The streamlined evolution shows how the 5-block picture reduces in practice, with CPU, memory, and I/O devices sharing one system bus. For our purposes the precise bus picture matters less than the conceptual split.

Control versus datapath

A manufacturing-line metaphor makes the split concrete. The datapath is the factory floor: ALU, registers, buses, the equipment that physically moves and transforms data. The control unit is the production planner: given a decoded instruction, it decides which datapath operations fire this clock cycle and which registers load new values. This pairing runs through every modern CPU designComputer Organization and Design.

The slide deck names the same two halves:

  • Control (控制): the hardware component that decides what each piece of the datapath should do.
  • Datapath (数据通路): the hardware necessary to perform the operations required by the processor.

The slide deck connects the two with a worked example: given the RISC-V instruction addi t0, x0, 6, the control unit identifies "this is an add-immediate operation, source register is x0, immediate field is 6, destination register is t0." The datapath then routes "the contents of register x0" and "the constant 6" to the ALU's two input ports, lets the ALU compute, and routes the result back to register t0.

The five-step fetch-decode-execute cycle

The smallest loop the CPU runs goes by several names — fetch-execute cycle, instruction cycle, fetch-decode-execute — and the slide deck lays out the same five steps the textbook uses:

  1. PC sends an address to memory.
  2. Memory returns the instruction, feeding it into the decoder.
  3. The decoder identifies the source and destination registers and the operation.
  4. The function unit accepts the input from registers and performs the operation.
  5. Write the result back into registers or memory.

That is the entire content of a modern instruction execution. Everything else is an implementation detailComputer Organization and Design.

The Hack 16-bit CPU built in the Nand2Tetris course materials is a deliberately minimal concrete example of this loop. Its internal datapath has:

  • An A register and a D register.
  • Two Mux16 multiplexers (one selecting what enters the A register, one selecting what enters the ALU's y input).
  • An ALU with a multi-bit control bus and a multi-bit status bus emitting zr (zero) and ng (negative) flags.
  • A PC program counter.

PC drives the instruction-memory address, the instruction word flows into the A-register / ALU control paths, the ALU computes, the d-bits route the result to D, A, or memory, and the j-bits combined with zr/ng decide whether PC increments or loads from A. None of this needs more than the five-step cycle above; everything else is an explicit choice encoded into the c-bits.

An instruction is just a number

An instruction is just a fixed-width number the decoder can pattern-match against. The 32-bit RISC-V base instruction set lays its fields out so that the register specifiers always sit in the same positions, regardless of format:

  • R-type (register-register ALU): [funct7(7) | rs2(5) | rs1(5) | funct3(3) | rd(5) | opcode(7)].
  • I-type (immediate ALU like addi t0, x0, 6): [imm(12) | rs1(5) | funct3(3) | rd(5) | opcode(7)].

The opcode picks the format family, funct3 and funct7 pick the operation inside that family, and the fixed positions of rs1, rs2, and rd let the decoder read the register specifiers before it has decoded the opcode. That is the entire reason an instruction can be a flat number: every piece of metadata sits in a known fieldComputer Organization and Design.

I/O as the boundary

I/O devices are the bridges between the CPU and the outside world, including the keyboard and mouse (input), the display and printer (output), and the disk (persistent storage). The chapter-2 component diagram shows them in their place: the I/O box contains Input and Output sub-modules, both attached to the CPU and the memory hierarchy. The I/O box belongs in the picture because some hardware (such as a keyboard or a network adapter) is an input that the program reads, and some (such as a monitor or a speaker) is an output the program writes.

The takeaway: the CPU is two cooperating halves, control and datapath, and one fetch-decode-execute cycle is the smallest unit of work the CPU actually does. Everything else, pipelining, branching, caches, interrupts, is a refinement layered on top of that five-step dance.

Talking to the CPU — variables, control flow, syntax, errors, and a Python primer

Now that we know what a CPU does, this last chapter is the smallest running program that uses it. The same five-step fetch-decode-execute loop runs the same memory pyramid out of chapter 4; the difference is only that humans write programs at a friendlier altitude than 32-bit patterns.

Variables bind a name to a memory cell to a value

A variable (变量) is the binding of a name to a memory cell to a value. Once written, the program reads or rewrites the value by referencing the name; the cell stays put. The slide-deck image makes the bindings visible:

A variable, in programming and in memory.

Caption: Left: a code statement int age = 21;. Middle: a memory cell with "age" on top and "21" below, sitting on a band labelled "RAM". Right: three callouts — "Variable Name" pointing at "age", "Value of the variable" pointing at "21", and "Random Access Memory" pointing at the RAM band.

This is the first time the tutorial's vocabulary turns into something a person types. The variable's name lives in the source code and the compiler's symbol table; the value lives at some address in RAM at runtime. The compilation step resolves the name to that address.

Three control structures

Every program, no matter how large, is built from three control structures (控制结构): sequence (顺序), selection (选择), and iteration (迭代). The slide-deck diagram covers all three at once:

The three control structures, with code and flowchart for each.

Caption: A. Sequence: four blue rectangles stacked vertically, each showing the next statement. B. Iteration split into Bounded (for i in range(6): y = y+1) and Un-bounded (while i != 10: z = z-3), each with a flowchart where the judgment box feeds back into the body. C. Selection split into Two-armed (if i >= 5: x = x+1 else: x = x-1) and One-armed (if i != 10: Done = True), each with a flowchart branching to True and False.

Each control structure corresponds directly to a piece of the CPU's fetch-decode-execute cycle. Sequence corresponds to the default PC-increment: do this, do this, do this. Selection corresponds to a conditional jump: the decoder flips a flag from the comparison and the control unit either increments the PC or jumps. Iteration is the same conditional jump with an unconditional jump back, making a loop. The same chapter-5 datapath moves and counts the bits that flow through all three structures. Once a reader can see this overlap, the difference between "what the CPU does" and "what Python does" gets smaller.

Syntax: keywords, operators, identifiers, comments

A programming language's syntax (语法) is the set of structural rules a compiler or interpreter enforces. The slide deck breaks syntax into four components:

  • Keywords (关键字): reserved words with a predefined meaning (if, while, int, return).
  • Operators (运算符): symbols or characters that perform operations on data. Python's operator families are arithmetic (+ - * / %), relational (< <= > >= == !=), logical (and or not), bitwise (& | << >> ~ ^), and assignment (= += -= *= %=).
  • Identifiers (标识符): names programmers give to variables, functions, classes.
  • Comments (注释): annotations for humans; ignored by the compiler.

A program that violates syntax fails before it runs. The slide deck's three error classes capture exactly this distinction:

Error classWhen it firesExample
Syntax errorThe code cannot be parsedMissing : after if
Runtime errorExecution raises an exception10 / 0
Logical errorThe code runs but gives the wrong answerscore > 60 for a 60-point pass

A program can run successfully and still give a wrong answer; that is why testing matters.

The smallest Python program that demonstrates all three structures

A runnable example is the fastest way to consolidate everything. The program below demonstrates sequence, selection, and iteration in roughly ten lines:

price = 8
quantity = 3
print(price * quantity)  # sequence: three statements, run top to bottom

attempts = 0
while attempts < 3:                # iteration (un-bounded while)
    score = int(input("Score? "))
    if score >= 60:                # selection (one-armed condition)
        print("Pass")
        break
    else:                          # selection (two-armed condition, the else branch)
        print("Try again")
    attempts = attempts + 1

Walking it line by line: price = 8 and quantity = 3 bind two names to two values in RAM. print(price * quantity) runs the multiplication 24 and prints it; that is the sequence. The while attempts < 3: head is the un-bounded iteration from the chapter-diagram above — every loop body runs while the comparison is true. The if score >= 60: body is the one-armed selection; the matching else: is the second arm. Running the program expects: input a value, if it is 60 or above print "Pass" and exit; otherwise print "Try again" and increment attempts. After three failed attempts the loop ends without breaking.

This program is small, but it exercises every vocabulary term the chapter introduced. Variable, sequence, selection, iteration, keyword, operator, identifier, comment — all present, all readable. Once a reader can read this program and predict its output, the chapter's job is done.

The takeaway: a program is just a sequence of instructions the CPU can fetch and execute. Variables are bindings, control structures are the same branches and loops the CPU does anyway, syntax is the rule book the compiler enforces, and errors fall into three classes that tell you where to look for the fix.

参考文献

本专题引用的核心资料如下,建议深入学习时阅读原文:

  1. Turing machine — Wikipedia — https://en.wikipedia.org/wiki/Turing_machine
  2. ENIAC — Wikipedia — https://en.wikipedia.org/wiki/ENIAC
  3. Von Neumann architecture — Wikipedia — https://en.wikipedia.org/wiki/Von_Neumann_architecture
  4. Patterson & Hennessy, Computer Organization and Design: The Hardware/Software Interface, RISC-V Edition 2 — Elsevier product page
  5. Two's complement — Wikipedia — https://en.wikipedia.org/wiki/Two%27s_complement
  6. IEEE 754 — Wikipedia — https://en.wikipedia.org/wiki/IEEE_754
  7. Memory hierarchy — Wikipedia — https://en.wikipedia.org/wiki/Memory_hierarchy
  8. Nisan & Schocken, The Elements of Computing Systems (Nand2Tetris Project 5 lecture PDF) — nand2tetris.org Project 5 PDF
Turing to Python:计算机科学的六大基石