Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Optimized scheduling service to maximize optional attendees - #32

Open
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal
Open

Optimized scheduling service to maximize optional attendees#32
apluscs wants to merge 17 commits into
masterfrom
calendar-optimal

Conversation

@apluscs

Copy link
Copy Markdown
Owner

No description provided.

@jalexanderqedjalexanderqed left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review is not 100% complete, but I may not be able to get back to this for a while, so sending now.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to review again once the variables I whined about have better names.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You've resolved a bunch of comments but not actually pushed the changes.

@acmcarther

Copy link
Copy Markdown
Collaborator

Nevermind, I got myself tricked by clicking an outdated comment...

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

going to need another pass.

for (int changeLogIndex = 0; changeLogIndex < changeLog.size(); ++changeLogIndex) {
// Need to back up mandatoryAttendeesMeetingTimesIndex in case we missed a time range in
// mandatoryAttendeesMeetingTimes.
mandatoryAttendeesMeetingTimesIndex = Math.max(0, mandatoryAttendeesMeetingTimesIndex - 1);

@acmcartheracmcartherJun 19, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not the clearest way to do this.

From what I can tell, you're intending to iterate over mandatoryAttendeesMeetingTimes only once, and you iterate over it over the course of iterating through changes. This "backtracking" is necessary because of the way you're iterating on the index variable.

The pattern I'd use for this is to (1) retain an iterator for mandatoryAttendeesMeetingTimes and (2) retain the "next" meeting time to be processed. Upon successful processing, get the next meeting time from the iterator, until there are no more remaining.

A skeleton of this:

Iterator<TimeRange> mandatoryMeetingTimesIter = mandatoryAttendeesMeetingTimes.iterator();
Optional<TimeRange> nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ? Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
for (Map.Entry<String,String> changeEntry : changes.entrySet()) {
while (nextMandatoryMeetingTimeOpt.isPresent()) {
TimeRangethisMandatoryMeetingTime = nextMandatoryMeetingTImeOpt.get();
// TODO: Explain what this check is doingif (thisMandatoryMeetingTime.start() < changeEntry.getKey()) {
break;
}
updateOptimalTimes(
TimeRange.fromStartEnd(
Math.max(thisMandatoryMeetingTime.start(), prevTime),
Math.min(thisMandatoryMeetingTime.end(),
(Integer) changeEntry.getKey()),
false));
// Queue up the next meeting time.nextMandatoryMeetingTimeOpt = mandatoryMeetingTimesIter.hasNext() ?
Optional.of(mandatoryMeetingTimesIter.next()) : Optional.empty();
}
prevTime = (Integer) changeEntry.getKey();
currAttendance += (Integer) changeEntry.getValue();
}
// TODO: What does it mean if nextMandatoryMeetingTimeOpt.isPresent() (still)? Handle this

@apluscsapluscsJun 19, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

  1. l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.
  2. l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

l could accomplish this decrement by keeping a prevMandatoryMeetingTime and setting thisMandatoryMeetingTime to that at the top of every outer for loop but that seems clumsy. Or l could do something with a ListIterator, since it supports a previous() method. Any thoughts?

@acmcartheracmcartherJun 22, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

l changed thisMandatoryMeetingTime.start() < changeEntry.getKey() to thisMandatoryMeetingTime.start() >= changeEntry.getKey() for logic reasons.

Acknowledged, though I don't see this check in the new code, so I'm really not sure what's going on.

l don't see how mandatoryMeetingTimesIter is going back by 1 at the start of the outer for loop. It also fails some tests, because of this reason (easiest to see is in the onlyOptionalAndDisjoint test).

This could be interpreted as "why doesn't your code do this" or "my code doesn't actually do this". I'll try to answer both, but I just wanted to give you this caveat that i didn't really actually understand your comment.

The solution I described doesn't require mandatoryMeetingTimesIter to "go back one", because it is not being incremented unless the value is consumed. This is the purpose behind storing "the next value", and incrementing that immediately after the call to updateOptimalTimes. This more closely matches the semantics you want, rather than the for loop construction, which always increments the value when the value (that it is an index to) doesn't always get consumed.

A do while might be equivalent and still use the index based construction (though please, if you do that, don't let it grow to be like five lines in the declaration like this one).

@apluscsapluscsJun 26, 2020

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Sorry for the confusion.

  1. The change in my first point was done locally and l didn't push that because it was failing tests.
  2. The crux is that l need to advance mandatoryMeetingTimesIter enough for it to be too far in the future but then still be able to go back to last one that was valid (that time could still be valid for the next one in the changeLog). l think l get what you're saying now, with looking ahead to see the next mandatoryMeetingTime and choosing to advance or not. But in your code, when you "Queue up the next meeting time", you advance the iterator and you're unable to go back = bugs. l can use your iterator method but l'll have to make some changes from the code you proposed.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Nvm, iterators are annoyingly verbose. l'll take you up on the while loop idea.

@acmcartheracmcarther left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You might need jqed to review this to approval. I can't understand what is going on here.

Sign up for freeto 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.

3 participants

@apluscs@acmcarther@jalexanderqed