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

Fix time spent on bubble choice = sum of sub-level time spent #40117

Merged
merged 8 commits into from Apr 22, 2021

Conversation

maureensturgeon
Copy link
Contributor

@maureensturgeon maureensturgeon commented Apr 16, 2021

  • Refactor merge_user_progress_by_level (users_helper function that determines progress for each level)
  • Update time_spent for parent bubble choice level to be sum of sublevel time_spent

Links

Testing story

Added unit tests and manually tested a bubble choice by adding progress on multiple choice levels, then checking time spent in the progress table.

Deployment strategy

Follow-up work

Privacy

Security

Caching

PR Checklist:

  • Tests provide adequate coverage
  • Privacy and Security impacts have been assessed
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@@ -342,41 +342,6 @@ def section_level_progress
}
end

# Get level progress for a set of users within this script.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to users_helper

Copy link
Contributor

Choose a reason for hiding this comment

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

🎉

@maureensturgeon maureensturgeon force-pushed the maureen/LP-1851-time-spent-bubble-choice branch from 46705c3 to 5c3f09f Compare April 20, 2021 16:26
@maureensturgeon maureensturgeon marked this pull request as ready for review April 20, 2021 16:27
@maureensturgeon maureensturgeon requested a review from a team April 20, 2021 16:27
Copy link
Contributor

@jamescodeorg jamescodeorg left a comment

Choose a reason for hiding this comment

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

I'm not quite done yet but sending out some questions before a long stretch of meetings.

This is an excellent improvement! One of the things I've been wondering about is how to structure all the special-case logic for calculating progress for different level types and this change really helps reveal some of the structure here.

completion_status = activity_css_class(user_level)
locked = user_level.try(:show_as_locked?, script_level.lesson) || script_level.lesson.lockable? && !user_level

# if the level has not been tried, less progress data is necessary
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you elaborate a bit more on why we need a special case for not_tried here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup! So if a level status is not tried there are two possible things that happen:

  1. If it's not locked we don't merge any progress for that level
  2. If it is locked then we merge only status and locked state for the progress for that level

In either one of those cases we don't need a full set of progress data so we return just what we need. I'll update the comment and try to make it more clear.

readonly_answers: !!user_level.try(:readonly_answers) || nil,
paired: (paired_user_levels.include? user_level.try(:id)) || nil,
last_progress_at: include_timestamp ? user_level&.updated_at&.to_i : nil,
time_spent: user_level&.time_spent&.to_i
Copy link
Contributor

Choose a reason for hiding this comment

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

Are .try and &. equivalent? If so, maybe we can be more consistent about using one or the other, at least within a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually had to look this up. So it sounds like the main difference is that using try, if a method is called that doesn't exist for the object then it will swallow the NoMethodError and return nil. I think moving towards & seems like the right call here. I'll update.

Copy link
Contributor

Choose a reason for hiding this comment

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

TIL! thanks for that distinction.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay so turns out Free Response levels have a peer_reviewable method but other types of levels don't so that's a valid use of try that I'll need to leave there.

Copy link
Contributor

@cforkish cforkish left a comment

Choose a reason for hiding this comment

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

LGTM! Nicely done!

@@ -342,41 +342,6 @@ def section_level_progress
}
end

# Get level progress for a set of users within this script.
Copy link
Contributor

Choose a reason for hiding this comment

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

🎉

@@ -160,6 +195,8 @@ def user_summary(user)
# this in advance for many users in some use cases.
# @param [Enumerable<Integer>] paired_user_levels
# A collection of UserLevel ids where the user was pairing.
# @param [Boolean] include_timestamp
Copy link
Contributor

Choose a reason for hiding this comment

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

are there any cases where we don't pass true for this? i can't think of a use case for that. if we're not using it, let's remove it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm. i find that questionable. from a brief inspection it looks like we only include that data for the teacher dashboard, but i can't think of a reason for that. it doesn't require any extra db queries and would result in very minor data bloat, so imo it would be worth the reduction in complexity to remove it. could you try to find out if there's a specific reason we're excluding it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree we should investigate, going to punt this for now to avoid increasing the scope of this ticket

}.compact
end
end
end
progress
end

# Summarizes a user's level progress for bubble choice level (parent level and sublevels)
private def get_bubble_choice_progress(level, user, user_levels_by_level, script_level, paired_user_levels, include_timestamp)
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: in terms of figuring out how this code works, imo get_level_progress should come before this.

Copy link
Contributor

Choose a reason for hiding this comment

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

that said, i do think factoring this out into its own helper function really improves the readability of merge_user_progress_by_level 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll move it down!

@maureensturgeon maureensturgeon merged commit 8c938fb into staging Apr 22, 2021
@maureensturgeon maureensturgeon deleted the maureen/LP-1851-time-spent-bubble-choice branch April 22, 2021 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants