Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch to show for #79: show "yellow" To-Dos in Today and remove them from Upcoming #80

Merged
merged 18 commits into from
Jun 6, 2021

Conversation

AlexanderWillner
Copy link
Contributor

No description provided.

@codecov-commenter
Copy link

codecov-commenter commented May 5, 2021

Codecov Report

Merging #80 (747cae0) into main (4141f5c) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##              main       #80   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            2         2           
  Lines          341       352   +11     
=========================================
+ Hits           341       352   +11     
Impacted Files Coverage Δ
things/api.py 100.00% <100.00%> (ø)
things/database.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4141f5c...747cae0. Read the comment docs.

@AlexanderWillner
Copy link
Contributor Author

@mikez will test tomorrow when having yellow tasks - feel free to already comment on the changes.

@AlexanderWillner AlexanderWillner changed the title initial (untested) starting point for #79 (showing yellow tasks) Patch to show for #79: show "yellow" To-Dos in Today and remove them from Upcoming May 6, 2021
@mikez
Copy link
Contributor

mikez commented May 6, 2021

I took a look!

  1. I'm not a big fan of leaking SQL into the API interface, since it adds complexity. Alternative idea: Since the number of today tasks and also those " > now" are practically a small number, you could do this in pure Python. For example, using list comprehensions or a for loop and the datetime.now().isoformat() output.

  2. To clarify what I wrote here: When you click on "Today" in the Things app, then yellow notifications will be generated for various cases. You are only handling one of these here. I suggest you think about and list out all of the unconfirmed_today_tasks cases as a comment in things.today. This will give us an overview over what we've already implemented and what we haven't. Otherwise, users won't know what to expect.

@mikez
Copy link
Contributor

mikez commented May 7, 2021

Another idea for (1.): add the string options "past" and "future" to start_date. It compares start_date to the date and time of now.

Also, a technical remark: I've noticed that start_date isn't always a date. For example, if you set an alert, then it turns into a datetime.

@mikez
Copy link
Contributor

mikez commented May 8, 2021

Some suggestions:

  1. Why title-case "Future" and "Past" as supposed to "future" and "past"?
  2. To not increase complexity, I'd keep database.make_filter as it was before and instead extend database.make_date_filter. You're essentially doing make_date_filter with an offset of "0" here. For boolean offsets, you can call database.make_filter from within make_date_filter.
  3. Add start_date to the "# Validation" section.
  4. The parameter deadline is very similar, you might consider giving it the past/future options too.

@AlexanderWillner
Copy link
Contributor Author

  1. Why title-case "Future" and "Past" as supposed to "future" and "past"?

No special reason, changed it now. Also created #81 because of this, as currently we have for example Inbox (uppercase) but incomplete (lowercase).

  1. To not increase complexity, I'd keep database.make_filter as it was before and instead extend database.make_date_filter. You're essentially doing make_date_filter with an offset of "0" here. For boolean offsets, you can call database.make_filter from within make_date_filter.

I gave it a shot.

  1. Add start_date to the "# Validation" section.

Done, however, see #81 - I'm thinking more about exploiting types (enums, classes, ...) or type hints here sooner or later.

  1. The parameter deadline is very similar, you might consider giving it the past/future options too.

Done.

@mikez
Copy link
Contributor

mikez commented May 10, 2021

  1. Why title-case "Future" and "Past" as supposed to "future" and "past"?

No special reason, changed it now. Also created #81 because of this, as currently we have for example Inbox (uppercase) but incomplete (lowercase).

The convention I used here was to always do lower case except for where the Things App has a different convention. "Inbox", "Anytime", etc. are special nouns involving GTD collection names; they're title-cased in the app. It is fine to use start="inbox" though, since we run the line start = start and start.title() in database.get_tasks.

@mikez
Copy link
Contributor

mikez commented May 10, 2021

I will take a look at your changes and comment as soon as possible.

…ion date) tasks with a due date, calculated some test expectations, reordered some expectations
Copy link
Contributor

@mikez mikez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your patience, @AlexanderWillner. Commented. I hope it's helpful.

things/api.py Outdated Show resolved Hide resolved
things/api.py Outdated Show resolved Hide resolved
things/api.py Show resolved Hide resolved
things/database.py Outdated Show resolved Hide resolved
things/database.py Outdated Show resolved Hide resolved
things/database.py Outdated Show resolved Hide resolved
return {
None: "",
False: f"AND {column} IS NULL",
True: f"AND {column} IS NOT NULL",
}.get(value, default)


def make_date_filter(date_column, offset):
def make_date_filter(date_column: str, offset) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this function is getting too complex. I find it hard to read.
Maybe split it out into two functions?

  • make_date_range_filter ("3d", "2w", "5y")
  • make_date_filter (True, False, "future", "past")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personal gut feeling: keep it. These functions would be very similar in what they want to achieve and the current version is around 20 lines of code. But also fine splitting it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vote for splitting. It seems hard to read, especially for somebody who's never seen this code before.

A date range filter (specified by an offset) and a date filter (True, False, "past", "future) seems more readable for me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One can always merge again if it seems too redundant. I much prefer many smaller functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #82 for this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why break it out into a separate PR?

The proposal was to rename make_date_filter to make_date_range_filter, but leave it as-is. Then, to add a new function called make_date_filter which operates on True, False, None, "future", "past".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mh:

  • In case of None: return ""
  • In case of True/False: return make_filter
  • In case of Future/Past: set offset to 0 and specify operator

The new method would duplicate the actual code

column_datetime = f"datetime({date_column}, 'unixepoch', 'localtime')"
offset_datetime = f"datetime('now', 'localtime', '{modifier}')"  # type: ignore

Wouldn't it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the case of "future" and "past", my thinking was to call make_date_range_filter from within make_date_filter. Or.. what do you think?

@AlexanderWillner I think we're almost there with this review. I look forward when we can merge this in. :)

things/api.py Outdated Show resolved Hide resolved
things/api.py Outdated Show resolved Hide resolved
things/api.py Outdated Show resolved Hide resolved
things/api.py Outdated
unconfirmed_overdue_tasks = tasks(
start_date=False,
deadline="past",
start="Anytime",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't Inbox and Someday be possible too? Maybe the start is irrelevant here.

Copy link
Contributor

@mikez mikez May 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @AlexanderWillner ; see earlier comment further above which wasn't resolved yet.

things/api.py Outdated Show resolved Hide resolved
things/database.py Outdated Show resolved Hide resolved
things/database.py Outdated Show resolved Hide resolved
things/database.py Outdated Show resolved Hide resolved
return {
None: "",
False: f"AND {column} IS NULL",
True: f"AND {column} IS NOT NULL",
}.get(value, default)


def make_date_filter(date_column, offset):
def make_date_filter(date_column: str, offset) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vote for splitting. It seems hard to read, especially for somebody who's never seen this code before.

A date range filter (specified by an offset) and a date filter (True, False, "past", "future) seems more readable for me.

return {
None: "",
False: f"AND {column} IS NULL",
True: f"AND {column} IS NOT NULL",
}.get(value, default)


def make_date_filter(date_column, offset):
def make_date_filter(date_column: str, offset) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One can always merge again if it seems too redundant. I much prefer many smaller functions.

things/api.py Show resolved Hide resolved
things/api.py Outdated Show resolved Hide resolved
things/api.py Outdated Show resolved Hide resolved
@AlexanderWillner
Copy link
Contributor Author

@mikez long discussions here ;) remind me: is there something open?

things/api.py Outdated
- `deadline == None` (default), then include all tasks.

deadline_suppressed : bool or None, optional
- `deadline_suppressed == True`, only include tasks with a overdue deadline
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • "with an overdue deadline"
  • might need more explanation: "deadline suppressed" is a technical term used in the database. It means overdue tasks which have been moved from Today to Inbox, Anytime, or Someday.

things/api.py Outdated
- `deadline_suppressed == True`, only include tasks with a overdue deadline
that have been moved from the today view (Inbox, Anytime, Someday).
- `deadline_suppressed == False`, only include tasks with an overdue deadline
that have not been moved from the today view to another view (Inbox, Anytime, Someday).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are only tasks with overdue deadlines included or all tasks no matter if their deadline is overdue or not?

things/api.py Outdated
unconfirmed_overdue_tasks = tasks(
start_date=False,
deadline="past",
start="Anytime",
Copy link
Contributor

@mikez mikez May 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @AlexanderWillner ; see earlier comment further above which wasn't resolved yet.

return {
None: "",
False: f"AND {column} IS NULL",
True: f"AND {column} IS NOT NULL",
}.get(value, default)


def make_date_filter(date_column, offset):
def make_date_filter(date_column: str, offset) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why break it out into a separate PR?

The proposal was to rename make_date_filter to make_date_range_filter, but leave it as-is. Then, to add a new function called make_date_filter which operates on True, False, None, "future", "past".

things/api.py Show resolved Hide resolved
@AlexanderWillner
Copy link
Contributor Author

@mikez let us finish this pull request ;)

@mikez
Copy link
Contributor

mikez commented Jun 5, 2021

@AlexanderWillner Thanks for your patience. I hope to get back to this PR ASAP.

@mikez
Copy link
Contributor

mikez commented Jun 6, 2021

@AlexanderWillner Well done. I'll satisfy my need for order and readability in an upcoming pull request.

@mikez mikez merged commit ab73287 into thingsapi:main Jun 6, 2021
@AlexanderWillner
Copy link
Contributor Author

AlexanderWillner commented Jun 6, 2021

Thanks. Does it? You changed a few things (for the better) in #83 - good work ;)
PS: misread your initial comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants