Programming for the Web

Independent Reading Journal


Learning Objectives

  • You can adapt familiar routes, selection, templates, and JSON coordination to a new domain.
  • You can connect form fields to a supplied function that creates a reading session.
  • You can save sessions and retrieve them after restarting the application.

Part 3’s Reading Tracker recorded reading time. Your new Reading Journal gives reading sessions a browser interface. Each record describes one session, with an identifier, book title, category, and minutes.

Adapt lookup and links from Chapter 5, search from Chapter 6, form submissions from Chapter 7, and saving from Chapter 9.

Reading Session Records

The starter’s sessions.json contains these records:

[
{
"id": "S17",
"title": "The Long Road",
"category": "fiction",
"minutes": 20
},
{
"id": "S44",
"title": "Field Notes",
"category": "nonfiction",
"minutes": 35
}
]

Browse Reading Sessions

Build the journal in four exercises: browse, search, save, and submit. Complete each exercise to unlock the next. Every new starter includes a sample solution to the previous step, so use the supplied files for that exercise.

Begin with a page for browsing the stored sessions and following links to their details. Adapt the task lookup and detail pages from Chapter 5. This first version only reads records.

Reading Journal: Browse

0 / 40 points

Complete find_session, the two GET routes in main.py, and the list in templates/sessions.html.

find_session(records, session_id) returns the matching record or None. GET /sessions displays sessions in stored order, with each title linking to its detail page and its category alongside it. An empty journal displays No sessions..

GET /sessions/{session_id} displays session.html with the record under session, or returns 404 if absent. Pass the list under sessions; use ordinary Jinja insertion for text. Browsing leaves the JSON file unchanged.

Search the Journal

The next starter supplies working browsing and detail pages, plus a function that selects sessions by book title. Connect that function to the list route and the search form’s q field, as in Chapter 6. Searching leaves the stored sessions unchanged.

Reading Journal: Search

0 / 20 points

Complete the marked list route in main.py. The title filter and search form are supplied.

For GET /sessions?q=..., read the current records and call select_sessions(records, q). Pass the selected records under sessions and the search text under q to sessions.html. Keep browsing and detail links working; searching leaves the JSON file unchanged.

Save a Reading Session

With browsing and searching working, add the storage operation from Chapter 9. The starter supplies the JSON writer and the session preparation helper. Complete the function that adds one session while preserving the earlier sessions. The browser submission route comes in the final exercise.

Preparing a Reading Session

Use categories such as fiction, nonfiction, and other. Repeated book titles represent separate reading sessions.

The supplied prepare_session(title, category, minutes) trims the title and category and converts minutes with int(minutes). Enter minutes as a whole number, such as 20.


Reading Journal: Save

0 / 30 points

Complete add_session(path, title, category, minutes) in main.py using the supplied helpers.

Read the current records, pass the three original strings to prepare_session, append its returned session, save the complete collection with write_records, and return the new session. Keep all earlier sessions, including repeated readings of the same book. Saved sessions remain available after restarting.

Connect the Submission Form

The final starter includes a working storage function and an addition form. Connect the form’s three values to that function and redirect to the list, as in Chapter 7. A new session should appear alongside the earlier sessions.

Reading Journal: Submit

0 / 25 points

Complete the two marked statements in add_from_form.

Call add_session once with DATA_FILE and the three original submitted strings. Then return a 303 redirect to the GET route that displays the journal. Keep the supplied form and earlier browsing, search, and saving behavior.

Use whole-number minutes, such as 20.


Explore the completed journal in a browser

If you run your completed exercise locally, open http://127.0.0.1:8000/sessions. Browse a session, search by book title, and add another session for an existing book. Restart the server and check that the saved sessions remain.

Check Your Understanding

  1. Two sessions record reading the same book. Why should each detail link use the session’s identifier rather than the book title?
  2. A title search finds the correct sessions, but its input is blank in the resulting page. Which connection between the list route’s context and the search input would you check?
  3. A form submits minutes as the string "20", but JSON stores the number 20. Where does this conversion happen in the journal, and which values should the submission route pass on?
  4. Trace one new session from the POST request to the list shown after the redirect. Which steps create or save the record, and which steps only read and display it?