> Source URL: /resources/project-structure.guide
# Project Structure

As programs grow, putting everything in one file gets hard to manage. This guide covers patterns for organizing Python projects into clear, maintainable pieces.

## The `main()` Pattern

Define a `main()` function that ties your program together, then call it at the bottom of the file. This gives your program a clear starting point that reads like a story:

```python
def display_greeting(name):
    print("Welcome, " + name + "!")

def main():
    name = input("Enter your name: ")
    display_greeting(name)
    print("Session started.")

main()
```

Without `main()`, your top-level code runs line by line, scattered between function definitions. With `main()`, the flow is obvious: _get a name, greet, start session_.

## Why Use `main()`?

- **Readability** — one function tells you what the whole program does
- **Organization** — separates setup/orchestration from helper logic
- **Control** — code inside `main()` only runs when you call it, not on import

## Splitting into Multiple Files

When a project has several functions, move helpers into their own file:

```
my-project/
    main.py
    helpers.py
    data/
        agents.txt
```

`helpers.py` holds reusable functions:

```python
# helpers.py

def load_agents(filename):
    agents = []
    with open(filename, "r") as file:
        for line in file:
            parts = line.strip().split(",")
            agent = {"name": parts[0], "department": parts[1]}
            agents.append(agent)
    return agents

def display_agent(agent):
    print(agent["name"] + " — " + agent["department"])
```

`main.py` imports and uses them:

```python
# main.py
from helpers import load_agents, display_agent

def main():
    agents = load_agents("data/agents.txt")
    for agent in agents:
        display_agent(agent)

main()
```

## The `__name__` Guard

When Python runs a file directly, it sets a special variable `__name__` to `"__main__"`. When a file is _imported_, `__name__` is set to the file's module name instead.

This matters because any code at the top level of a file runs on import. The guard prevents that:

```python
# helpers.py

def greet(name):
    return "Hello, " + name + "!"

if __name__ == "__main__":
    print(greet("test"))
```

**Run `helpers.py` directly:**

```
$ python helpers.py
Hello, test!
```

**Import `helpers` from another file:**

```python
# main.py
from helpers import greet

print(greet("Alice"))
```

```
$ python main.py
Hello, Alice!
```

The test line inside the guard does _not_ run when `main.py` imports `helpers`. Without the guard, you would see both "Hello, test!" and "Hello, Alice!".

## When to Use the Guard

Put code inside `if __name__ == "__main__":` when:

- You have test or demo code in a helper file
- You want to run a file on its own _and_ import it from elsewhere
- You want to keep your `main()` call from running on import

A typical helper file looks like this:

```python
# helpers.py

def load_data(filename):
    # ... loading logic ...
    return data

def process_data(data):
    # ... processing logic ...
    return results

if __name__ == "__main__":
    test_data = load_data("test.txt")
    print(process_data(test_data))
```

And a typical entry point:

```python
# main.py
from helpers import load_data, process_data

def main():
    data = load_data("data/records.txt")
    results = process_data(data)
    print(results)

if __name__ == "__main__":
    main()
```

## Putting It All Together

Here is a complete two-file project:

```
archive-audit/
    main.py
    helpers.py
    data/
        agents.txt
```

```python
# helpers.py

def load_agents(filename):
    agents = []
    with open(filename, "r") as file:
        for line in file:
            parts = line.strip().split(",")
            agents.append({
                "name": parts[0],
                "department": parts[1],
                "score": int(parts[2])
            })
    return agents

def get_active(agents):
    results = []
    for agent in agents:
        if agent["score"] >= 70:
            results.append(agent)
    return results

def save_report(filename, agents):
    with open(filename, "w") as file:
        for agent in agents:
            file.write(agent["name"] + ": " + str(agent["score"]) + "\n")

if __name__ == "__main__":
    test_agents = load_agents("data/agents.txt")
    print("Loaded " + str(len(test_agents)) + " agents")
```

```python
# main.py
from helpers import load_agents, get_active, save_report

def main():
    agents = load_agents("data/agents.txt")
    active = get_active(agents)
    save_report("data/report.txt", active)
    print("Report saved: " + str(len(active)) + " active agents")

if __name__ == "__main__":
    main()
```

## Common Mistakes

**Forgetting the guard in a helper file**

```python
# helpers.py

def greet(name):
    return "Hello, " + name + "!"

print(greet("test"))  # Runs every time helpers is imported!
```

**Running the wrong file**

```bash
# Wrong — runs helpers.py directly, not your main program
python helpers.py

# Right — run the entry point
python main.py
```

**Putting `main()` at the top level without the guard**

```python
# This runs on import too
def main():
    print("Starting...")

main()  # Always runs, even when imported

# Better
if __name__ == "__main__":
    main()  # Only runs when this file is executed directly
```


---

## Backlinks

The following sources link to this document:

- [Project Structure Guide](/resources/resources.index.llm.md)
- [Project Structure Guide](/resources/modules.guide.llm.md)
