0%

Chapter 10

Organizing a Program Across Files

Why Split a Working Program

Something changes with this chapter, and it changes before you write a line.

Until now every lesson gave you one editor holding one program. This chapter gives you a project: a set of files that persist from one lesson to the next. What you write in Lesson 2 is still there in Lesson 8, and the file panel beside the editor is how you move between them.

The project already contains one file. Open main.py and read it.

What you are looking at

This chapter starts with a fresh, smaller quiz using familiar responsibilities: a Question that knows its own answer, a Quiz that holds questions, an Attempt that scores responses, a that turns an attempt into report lines, and a main that wires them together.

It keeps one text-question type and a running score so you can concentrate on moving responsibilities between files. It does not replace Chapter 9’s richer family or its validation rules. Preserve this supplied program’s behavior throughout the chapter.

At about sixty lines it still fits comfortably in one file. We will practice the boundaries that become useful as the program grows.

What one file costs

Programs do not become hard to work with because they are long. They become hard because everything in them can reach everything else.

Finding things. report_lines is between Attempt and build_quiz for no reason at all. In a thousand-line file, “where is the scoring rule?” becomes a search rather than a place.

Reading. To understand Attempt you scroll past Question and Quiz. Nothing tells you which of them Attempt actually depends on, because in one file the answer is always “any of it”.

Changing. Two people editing this file are editing the same file, and their changes collide even when the work does not overlap.

Reusing. Another program can import Question from this guarded file, but it also loads definitions for report formatting and quiz-building. A focused makes the smaller dependency clear.

Testing. Chapter 13 writes real tests. Testing Question alone is much easier when Question lives somewhere alone.

Which of these is the strongest reason to split this program into modules?

What we are aiming for

By the end of the chapter, main.py looks roughly like this:

from models import Question, Quiz
from report import report_lines


def main():
    ...

This is the intermediate flat layout; Lesson 7 adds the quizapp package prefix. The import lines show the dependencies. Anyone opening this file learns in three seconds that the program has a domain and a reporting layer, and that the entry point uses both. That sentence is not in a comment anywhere; it is in the structure.

The chapter gets there one step at a time:

  • Lessons 2 and 3 create your first module and import from it.

  • Lesson 4 looks at what actually happens when Python runs an import.

  • Lesson 5 makes main.py an entry point rather than a dumping ground.

  • Lesson 6 draws the line between rules and presentation, in files this time.

  • Lesson 7 groups modules into a package, and meets the one import problem that bites beginners.

  • Lesson 8 finishes the split.

A word about the workspace

Because the files persist, a mistake persists too. If a later lesson behaves strangely, the cause may be in a file you wrote earlier, which is exactly the situation this chapter is teaching you to work in.

Run always executes main.py, even while another file is open. Submit checks the files required by the current lesson.

The Reset button restores the project to how it started. It clears your chapter files but keeps completion checkmarks, so later exercises may need earlier work rebuilt. Use it only when you intend to restart the project.