Python task manager from scratch, part 30: Adding a feature I want

I don't like how tasks accumulate in my current task managers. This is some combination of a software problem and a life problem. Often, improving one improves the other.

I'd like for Veery to accurately prompt me to delete or push back tasks--when that's appropriate. It's not obvious how to do this: mere longevity is not the only information we need. Some low-urgency tasks that can legitimately hang around for a while; some recently-added tasks are obviously better off deleted or deferred.

I need to give this issue more careful thought before I make major architectural decisions. For now, I can implement something I know I want, more or less regardless of Veery's ultimate form: the ability to "kick" the due date of a task. The necessary work is:

  1. Implement a kick() method on Task.
  2. Add an endpoint in main.py for processing kick commands.
  3. Add a button for kicking the task to every task in the Web interface.
  4. Add tests.

Some notes on the work:

  1. I was not trying to get this feature exactly right, but even so came across enough subtleties that I needed to stop and think. It was only in testing that I realized that I wanted kick() to behave differently in cases where a Task's due date had or had not passed.
  2. Using datetime.now() in tests is imperfect. Eventually it will probably be necessary to use freezegun or some other time-mocking/-stubbing tool. For now, I prefer to (i) write tests more quickly and (ii) avoid dependencies. Time is hard to get right and there are always more real-world domain considerations and edge cases than you first think. It's important to test this functionality, but fine to knowingly not address the full complexity of the feature (yet).
  3. This is a nice case study in what is sometimes called "tracer bullet" implementation.[1] The goal is to strike a balance between (i) implementing an unmaintainable mess and (ii) over-designing some small detail prematurely. The problem with (ii), besides the impossibility of getting it right the first time under any circumstances, is that you can't test something properly without at least some of the supporting context implemented. The ideal situation is to get some end-to-end thing working and under test in a way that at least approximately respects the form that a mature and maintainable system will have.

Here's the current commit in the veery/ repository.

[1] "Tracer bullet" can mean different things; what I'm using "tracer bullet" to describe here is also called by many names. Beware.


Next post: Python task manager from scratch, part 31: Adding some style


Home page