Red-Green-Code

Deliberate practice techniques for software developers

  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter

Time Tortoise: Daily Summary File, Part 2

By Duncan Smith Oct 5 0

Calendar

This is one in a series of articles about Time Tortoise, a Universal Windows Platform app for planning and tracking your work schedule. For more on the development of this app and the ideas behind it, see my Time Tortoise category page.

This week’s task: an initial implementation of the Daily Summary File.

DailySummary

The DailySummary class is responsible for generating and writing the contents of the daily summary text file. It needs to know these things:

  • How often the file should be written.
  • How to retrieve the raw data that will be formatted in the file.
  • How to write a text file to disk.

This week’s code updates support those requirements.

Here’s the high-level design: MainViewModel contains an instance of DailySummary, and exposes a WriteDailySummary method. Other parts of the system call that method when they want to update the daily summary file.

The DailySummary class itself is part of the ViewModel project. It depends on Repository, which is part of Model. Think of the daily summary text file as a type of view, with the DailySummary class as the supporting view model.

Repository and IRepository

The Time Tortoise GUI shows a list of time segments for a selected activity, optionally filtered to a date range. For the daily summary, we want time segments filtered to the current day, but we want them for all activities, not just one. Rather than iterate through all activities, it’s more efficient to retrieve the required time segments in a single request. Entity Framework makes that easy. Here’s the Repository query:

return _context.TimeSegments.
Where(t => t.StartTime >= startTime.Value &&
t.EndTime <= endTime.Value).ToList();

Settings, ISettings, and SettingsUtility

The WriteDailySummary method uses a new setting, DailySummaryUpdateIntervalSeconds, to determine how often to update the summary file. If fewer seconds than specified have elapsed since the last update, then a call to WriteDailySummary has no effect.

With the Time Tortoise settings infrastructure, the following steps are used to add a new setting:

  • Add an accessor with the appropriate name to the ISettings interface and the Settings class.
  • Set a default value for the setting in the SetDefaultSettings method in SettingsUtility.
  • Add a section to settings.txt with the new setting name, its value, and a comment explaining the purpose of the setting.

I also made a change to SettingsUtility this week: the settings path is exposed as a public property, to make it easy for other classes (like DailySummary) to write files to the same location.

MainPage.xaml

As explained in Time Tortoise: Timers, the view must own the main timer event in a UWP solution. To ensure that the daily summary file is updated periodically while the timer is running, the MainPage view calls Main.WriteDailySummary on each timer tick. But the file doesn’t actually get written on each tick, since WriteDailySummary checks the update interval setting first. It only gets updated as often as that setting specifies.

In addition to writing the file periodically while the timer is running, I also want to write it when the user starts and stops the timer. And there are other times (e.g., when the user edits a time segment) where it also makes sense to write the file. It’s easy enough to add more calls to WriteDailySummary to cover those cases.

Writing Text Files

Once all of the source data is available, the DailySummary class can write the file to disk. As explained in Time Tortoise: Reading and Writing Text Files in UWP Apps, UWP has some rules about file I/O and similar operations. However, it turns out that those rules aren’t enforced when a UWP app calls a method in a .NET Standard library from a UWP view. In that scenario, the File.WriteAllText method works as you would expect. So after building the summary file in memory (in a StringBuilder), I write it to disk by calling File.WriteAllText with the full path and the string representation of the file contents.

(Image credit: Kim Alaniz)

Categories: TT

Prev
Next

Stay in the Know

I'm trying out the latest learning techniques on software development concepts, and writing about what works best. Sound interesting? Subscribe to my free newsletter to keep up to date. Learn More
Unsubscribing is easy, and I'll keep your email address private.

Getting Started

Are you new here? Check out my review posts for a tour of the archives:

  • 2023 in Review: 50 LeetCode Tips
  • 2022 in Review: Content Bots
  • 2021 in Review: Thoughts on Solving Programming Puzzles
  • Lessons from the 2020 LeetCode Monthly Challenges
  • 2019 in Review
  • Competitive Programming Frequently Asked Questions: 2018 In Review
  • What I Learned Working On Time Tortoise in 2017
  • 2016 in Review
  • 2015 in Review
  • 2015 Summer Review

Archives

Recent Posts

  • Do Coding Bots Mean the End of Coding Interviews? December 31, 2024
  • Another Project for 2024 May 8, 2024
  • Dynamic Programming Wrap-Up May 1, 2024
  • LeetCode 91: Decode Ways April 24, 2024
  • LeetCode 70: Climbing Stairs April 17, 2024
  • LeetCode 221: Maximal Square April 10, 2024
  • Using Dynamic Programming for Maximum Product Subarray April 3, 2024
  • LeetCode 62: Unique Paths March 27, 2024
  • LeetCode 416: Partition Equal Subset Sum March 20, 2024
  • LeetCode 1143: Longest Common Subsequence March 13, 2024
Red-Green-Code
  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter
Copyright © 2025 Duncan Smith