0%

Reading and Writing Files · practice

Append Without Erasing

reading_report.txt answers “what is true now?” The history file answers a different question: “what successful runs have happened?”

Different meanings deserve different modes.

Append starts at the end

Implement this small boundary:

def append_history(path, count):
    with open(path, "a", encoding="utf-8") as handle:
        handle.write(f"Recorded {count} books.\n")

Mode "a" creates the file if it is missing. If it exists, every write goes to the end instead of replacing earlier contents.

Reset a scratch file, then change one letter for the second write:

Try it

The first open makes the experiment start from a known state. The second preserves that existing line and adds another. "w" and "a" differ by a single character and by everything that character means. Delete append-demo.txt when you are done with it; it is scratch, not part of the project.

The writes one complete record, including its newline, in one call. That keeps record boundaries visible. A future version might record a date or source name, but clocks would make today’s project and grader nondeterministic. This chapter records only the stable fact it actually knows: the number of books processed by this run.

Replacement and preservation are decisions

The important lesson is not “append is safer than write.” It is not.

  • Use "w" when the whole file is one replaceable result.

  • Use "a" when existing complete records are part of the artifact’s meaning.

Appending every new report would leave several headings and several current counts in a file that promises one current report. Replacing history would silently destroy the evidence it exists to retain.

Before choosing a mode, finish this sentence: “This file represents …” The right mode often follows directly.

Finish the successful path

After main() writes the fresh report, append one history record and change the success message to:

Wrote reading_report.txt and recorded 4 books.

The actual path and count must supply those values. Keep the two error handlers before all writing; a failed read should not create a report or a history record that looks successful.

Which pairing matches the artifacts' meanings?

Check this the same way you checked the report: run the program twice and open reading_history.txt. You should see two records, not one. Then run it a third time and confirm you see three, in the order they happened. A history that only ever holds the latest run is a history that has forgotten its job.

Task

Finish the journal’s successful path.

  • Implement append_history(path, count) with a with statement, explicit mode "a", and UTF-8.

  • Append exactly Recorded N books.\n using the supplied count.

  • After writing the fresh report, main() must append one history record.

  • Print Wrote reading_report.txt and recorded N books. using the actual report path and count.

  • Keep the existing narrow error behavior; a failed read must not be recorded as success.