Skip to content
9 changes: 7 additions & 2 deletions STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,16 @@ staying inline.**
library-page content (e.g. `libraries/pillow.md`'s per-method sections) — most content pages
should never need to go past `###`.

### Homepage keyword deep-links (`index.md`)
### Homepage keyword deep-links (`index.md`, `libraries/index.md`)

Each card in `index.md`'s "What's inside" grid ends with a row of `` [`keyword`](page.md#anchor) ``
links — one per concept the page teaches, so a reader can jump straight to the specific thing
they're after instead of landing on the page and hunting.
they're after instead of landing on the page and hunting. Library pages (`libraries/*.md`) are
the exception: their keyword links live only on their card in `libraries/index.md`'s own grid,
not on the main `index.md` — the top-level cards link to `libraries/<page>.md` as a whole,
without a per-heading keyword row. `tests/test_homepage_keyword_links_cover_all_headings` checks
each library subpage's headings against `libraries/index.md` instead of `index.md` for exactly
this reason.

- **Coverage — every `##` and `###` heading needs an entry.** Not just "the topic is
represented somewhere nearby" — each heading gets its own link, using its own anchor. A page
Expand Down
2 changes: 1 addition & 1 deletion docs/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Why Python Field Guide exists, who built it, and how to send feedba

## What is Python?

Python is a general-purpose language built for code that's easy to read back later, even by someone who didn't write it. There's no compiling: write a `.py` file, run it directly.
Python is a general-purpose language built for code that's easy to read back later, even by someone who didn't write it. No separate compilation step: write a .py file and run it with Python. Python handles the work of preparing and executing your code for you.

It shows up everywhere — web backends, data analysis and machine learning, automating repetitive tasks, scientific computing, quick glue scripts. Several of these are covered on this site's [Libraries](index.md#utilities) pages.

Expand Down
14 changes: 7 additions & 7 deletions docs/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ A **collection** is a single object that groups multiple values (like [basic typ

<div class="pt-jump-table" markdown="block">

| Collection Type | Example | Access values by | Use it for |
|------|---------|:-----------------:|------------|
| <a href="#lists">**`list`**</a> | <pre><code class="language-python-ref">["ball", "burmese"]</code></pre> | position # | <ul><li>An ordered group of items you can freely add to, remove from, or reorder</li><li>Not sure? Start here — the default, general-purpose choice</li></ul> |
| <a href="#dictionaries">**`dictionary "dict"`**</a> | <pre><code class="language-python-ref">{&#10; "species": "ball",&#10; "length_ft": 5&#10;}</code></pre> | Name of a key | <ul><li>Values stored under names ("keys") instead of position, like `species`, `length_ft`</li><li>Use it to look values up by name</li><li>Can't have duplicate keys</li></ul> |
| <a href="#tuples">**`tuple`**</a> | <pre><code class="language-python-ref">("ball", "burmese")</code></pre> | position # | <ul><li>Like a list, but fixed — can't be changed once created</li><li>Values that should stay exactly as they are, like a coordinate pair</li></ul> |
| <a href="#sets">**`set`**</a> | <pre><code class="language-python-ref">{"ball", "burmese"}</code></pre> | Membership (`in`) | <ul><li>An unordered group where duplicates are automatically dropped</li><li>Use it for fast "is this in here?" checks</li></ul> |
| Collection Type | Example | Access values by | Mutable | Use it for |
|------|---------|:-----------------:|:-------:|------------|
| <a href="#lists">**`list`**</a> | <pre><code class="language-python-ref">["ball", "burmese"]</code></pre> | position # | :material-check:{ .pt-icon-success } | <ul><li>An ordered group of items you can freely add to, remove from, or reorder</li><li>Not sure? Start here — the default, general-purpose choice</li></ul> |
| <a href="#dictionaries">**`dictionary "dict"`**</a> | <pre><code class="language-python-ref">{&#10; "species": "ball",&#10; "length_ft": 5&#10;}</code></pre> | Name of a key | :material-check:{ .pt-icon-success } | <ul><li>Values stored under names ("keys") instead of position, like `species`, `length_ft`</li><li>Use it to look values up by name</li><li>Can't have duplicate keys</li></ul> |
| <a href="#tuples">**`tuple`**</a> | <pre><code class="language-python-ref">("ball", "burmese")</code></pre> | position # | :material-close:{ .pt-icon-fail } | <ul><li>Like a list, but fixed — can't be changed once created</li><li>Values that should stay exactly as they are, like a coordinate pair</li></ul> |
| <a href="#sets">**`set`**</a> | <pre><code class="language-python-ref">{"ball", "burmese"}</code></pre> | Membership (`in`) | :material-check:{ .pt-icon-success } | <ul><li>An unordered group where duplicates are automatically dropped</li><li>Use it for fast "is this in here?" checks</li></ul> |

</div>

Expand Down Expand Up @@ -77,7 +77,7 @@ class diagram panel

- **Index with `list[index]`** to return the item at that index (position number) of the list.

To **update** the item at that index, set it equal to something else **`list[index] = new_item`**.
To **update** the item at that index, set it equal to something else **`list[index] = new_item`**. This works because a list is **mutable** — updating an item changes it in place instead of building a new one, the same way [an object's attributes](oop.md#classes-and-objects) can be changed after it's created.

*Run the below example, and change the indexes to see how they work:*

Expand Down
2 changes: 1 addition & 1 deletion docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ NameError: name 'name' is not defined

The **last line** and the **file and line** above it still matter most, same as before.

**Longer tracebacks** show one `File` line per function call involved — your code calling a function, which calls another function, and so on. Keep reading bottom to top: the first `File` line naming *your own file* (not a library you imported) is almost always the one worth looking at the frames above it are usually just the library code that was doing what your code asked, not the actual source of the bug.
**Longer tracebacks** show one `File` line per function call involved — your code calling a function, which calls another function, and so on. Start at the bottom of the traceback to identify the exception. Then read upward through the stack to understand how your program got there, looking first at the lines in your own code.

```python-ref
Traceback (most recent call last):
Expand Down
40 changes: 40 additions & 0 deletions docs/foundations.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,46 @@ Other languages fix a variable to one type permanently at creation; Python doesn

<div class="pfg-section" markdown="block">

## Expressions and statements

Every line of Python code is either an **expression** or a **statement**. An expression is anything that evaluates to a value — `2 + 3`, `species`, `species == "burmese"`. A statement is a complete instruction — an assignment, a `print()` call, an `if` statement's condition (covered on the [Conditionals](conditionals.md#if-elif-else) page) — and it's usually built out of one or more expressions.

```python-ref
2 + 3 # an expression — evaluates to 5
species # an expression — evaluates to whatever species currently holds
species == "burmese" # an expression — evaluates to True or False
length_ft = 2 + 3 # a statement — the expression "2 + 3" evaluates first, then gets stored
print(length_ft) # a statement — print() evaluates the expression "length_ft" to display it
```

The distinction is about what's allowed where: an expression can go anywhere Python expects a value — inside a function call's parentheses, on the right side of `=`, as part of a longer expression — but a statement can't, since it doesn't evaluate to anything.

??? warning "A statement can't be nested inside other code"
`y = (x = 2 + 3)` raises a `SyntaxError` — `=` only works as its own standalone statement, so tucking one inside another line, even in parentheses, fails immediately. This is different from some other languages, where assignment can be chained or nested like a value.

```python-ref
x = 2 + 3 # fine — a standalone statement
y = (x = 2 + 3) # SyntaxError — a statement can't sit inside an expression
```

??? run "Run an expressions vs. statements example"
All the examples above, combined into one script:

```python
species = "burmese"

print(2 + 3)
print(species)
print(species == "burmese")

length_ft = 2 + 3
print(length_ft)
```

</div>

<div class="pfg-section" markdown="block">

## Input function

`input()` allows the program to get typed input from the user
Expand Down
Loading
Loading